在使用相关的程序做各种处理的时候,需要先将程序注册下,否则无法使用。这样做的好处是可以 将同类型程序集中放置一个表中,方便管理和修改。

常用的程序注册函数有

  • regmsg( )
  • regurc ( )
  • regapp( )
  • regnotify( )
  • regrsp( )
  • reguart( )

regmsg()用来注册相应的消息处理程序

regmsg()这个程序放在 sys.lua 这个库文件中。提供的lua 主架构sys.run() 目前能够处理的消息中,除定时器消息(定时器函数直接用 sys.timer_start 来启动)和物理串口消息(用 reguart 来注册) 外,其余外部消息,例如AT 命令的虚拟串口数据接收消息、音频消息、充电管理消息、按键消息等,均需要用 regmsg 注册相应的消息处理函数。

  • 串口消息 分为虚拟 AT 口(msg.uart_id = uart.ATC)和物理串口(msg.uart_id = 串口号)消息。 其中虚拟 AT 口的消息已经缺省注册了,不需要用户再注册; 物理串口消息处理函数使用前需要用 reguart 来注册。
  • 键盘消息(msg.id=rtos.MSG_KEYPAD=3) 需要用 regmsg()来注册处理函数
  • 中断消息(msg.id=rtos.MSG_INT=4) 需要用 regmsg()来注册处理函数
  • 电源管理消息(msg.id=rtos.MSG_PMD=5) 需要用 regmsg()来注册处理函数
  • 音频消息(msg.id=rtos.MSG_AUDIO) 需要用 regmsg()来注册处理函数
function 
    regmsg(id,handler) handlers[id] = handler
end

regmsg处理流程见下面的图:

regmsg

使用方法举例

例1:在应用模块中加入键盘处理程keymsg(msg)

第一步:编制键盘消息处理程序

local function keymsg(msg) 

  if msg.pressed then

--键盘按下时的处理程序 

    else 
  end

--键盘弹起时的处理程序

end

第二步:注册该处理程序

sys.regmsg(rtos.MSG_KEYPAD,keymsg) 

这样,当 rtos.receive()收到键盘消息msg(msg.id=rtos.MSG_KEYPAD=3)时,通过 sys.run()

的分发,自动进入 keymsg(msg)这个 function 中进行处理。


例2:在应用模块中加入GPIO 中断处理程序

第一步:编制 GPIO中断处理程序

假设:

gsensor连接的是GPIO5 机械式

震动传感器连接的是GPIO3 GPS

连接的是 GPO1

IO.gsensor= pio.P0_5 IO.shake = pio.P0_3 IO.gps = pio.P1_1

local function gpio_int(msg)

--产生下降沿脉冲中断

    if msg.int_id == cpu.INT_GPIO_NEGEDGE then

--如果产生中断的 GPIO 是gsensor 引脚

        ifmsg.int_resnum == IO.gsensor then

--如果产生中断的 GPIO 是机械式振动传感器引脚

        elseif  msg.int_resnum == IO.shake then

-如果产生中断的 GPO 是 GPS 引脚

        elseif  msg.int_resnum == IO.gps then

        end

--产生上升沿脉冲中断

    elseif id ==cpu.INT_GPIO_POSEDGE then

    end

end

第二步:注册该处理程序

sys.regmsg(rtos.MSG_INT,gpio_int)

例3:在应用模块中加入 PMD(电源管理)消息处理程序

第一步:编制电源管理消息处理程序

local functionBatManage(msg)
    print("msg.voltage,msg.charger,msg.state =",msg.voltage,msg.charger,msg.state)                  DealCharger(msg)
    DealVolt(msg)
end

第二步:注册该处理程序

sys.regmsg(rtos.MSG_PMD,BatManage)

regapp( )用来注册应用程序

对 AT 命令的查询结果或某些事件的处理结果,会以 dispatch(消息 id, 参数 1,参数 2,….)的形式 来通知,如果想在 app 中对该消息 id 及对应的参数(参数1,参数 2,….)进行进一步处理,需要事先以 regapp 方式注册该 app 程序,注册后,每次 dispatch 相应的消息 id,就自动会进入相应的 app 程序 对 dispatch 出来的消息 id 和参数进行处理。

regapp 的详细流程详见下图:

regapp

regapp有 2 种注册方式:

1)以表的形式来注册

localtable = { 消息 id1 = app1, 消息 id2 = app2, …… , 消息 idn = appn }sys.regapp(table)

这种以表的方式注册 app 程序,一次可以注册多个 app。

使用方法举例:

例:注册多个dispatch 消息处理程序

第一步:填写注册表

在本例中: 长按键消息(MMI_KEYPAD_LPRESS)和短按键消息(MMI_KEYPAD_SPRESS)由客户编写用程序 dispatch 出来; 通话相关的消息(CALL_CONNECTED,CALL_DISCONNECTED,CALL_INCOMING)由库文件 cc.lua dispatch 出来

local idleapp = {
  MMI_KEYPAD_LPRESS = LongPresskey,     --长按键处理
  MMI_KEYPAD_SPRESS = ShortPresskey,    --短按键处理
  CALL_CONNECTED = connect,             --通话接通 
  CALL_DISCONNECTED = disconnect,       --通话挂断
  CALL_INCOMING = incall                --来电话
}

第二步:注册该表

sys.regapp(idleapp)

2) 以 app 的形式注册

sys.regapp(app,消息 id)

以 app 形式注册的程序,一次只可以注册一个 app,但是消息 id 可以不止一个。 使用方法举例:

例:当网络注册状态改变时,闪灯随之改变

第一步:编制闪灯变化程序

local functionlight(id,data)

-- 当 GSM 网络注册状态发生变化时闪灯发生变化

    if id == "NET_STATE_CHANGED" then if data =="REGISTERED" then
        if data == "REGISTERED" then
            GPIO_ontime(SLOW,ioChgNet)            --蓝灯慢闪
        else
            GPIO_ontime(SLOW,ioChgingNoNet)       --红灯慢闪
    end

GPIO_ontime(SLOW,ioChgingNoNet)   --红灯慢闪

-- 当充电状态发生变化时的闪灯也相应变化

    elseif id == “CHARGE_STATE_CHANGED” then 
        if data ==“CHARGING” then
            GPIO_ontime(FAST,ioChgingNoNet)     --红灯快闪
        else
            GPIO_on(ioChgNet) --蓝灯常亮
        end
    end 
end

第二步:注册 light 程序

sys.regapp(light,"NET_STATE_CHANGED",”  CHARGE_STATE_CHANGED”)

regurc()用来注册某些 URC相应的处理程序

URC=unsolicitedresult code ,即非请求式上报命令,也就是主动上报的命令。

如果用户需要在应用模块中自己处理感兴趣的 URC,需要用 regurc() 程序来注册 URC 处理程序来达到 目的。regurc() 程序放在 ril.lua 中。

fuction regurc(prefix,handler) 
    urctable[prefix] =handler
end

regurc 处理流程见下面的图:

regurc

使用方法举例:

例:处理 URC

第一步:根据需求,自己编制 URC 的处理程序

local function IdleUrc(data,prefix) 
  if prefix =="+CPIN" then
    local p =smatch(data,"NOT%s*INSERTED",string.len(prefix)+1) 
        if p then
        pbapp.SetSim(false)
        end
        local p = smatch(data,"READY",string.len(prefix)+1) 
        if p then
            pbapp.SetSim(true)          
        end
    end
end

第二步:注册该程序

ril.regurc("+CPIN",IdleUrc)

regrsp()用来注册 AT 命令处理程序

当用户发送 AT 命令时,一般是需要这些命令的返回结果的,AT 命令返回结果的处理程序 app 是通 过 regrsp()函数注册在 rsptable 表中的。这样当发送AT 命令时,会自动执行该处理程序处理 AT 命令 返回结果。

functionregrsp(head,fnc,typ) 放在 ril.lua这个库文件中。

head是 AT 命令的头,fnc 是处理函数,typ 是该命令的类型(cmd type: 0:no reuslt 1:number 2:sline3:mline 4:string10:spec)。

例如:AT+CHFA?这个获取音频通道命令的 head 是+CHFA? ,fnc 是 AT 命令返回结果处理程序, 由客户自己来编写,typ 是 2。

对 AT 命令的返回结果的处理,一般有两种情况:

1)一些常用的 AT 命令的处理程序,库文件已经缺省用 regrsp 注册了。此时处理程序会把 AT 命令结果 dispatch 出来,后续再用 regapp 注册的 app 再做进一步处理(适用于异步处理或前后有因果关系的情 况)

2)如果 AT 命令在 lib库文件中没有被 regrsp 注册过,则需要用 regrsp()注册相应的处理程序。此时 用户可以在这些处理程序中直接处理 AT 命令返回结果(适用于同步处理),也可以用 1)的异步处理方 式。

regrsp 处理流程见下面的图:

regrsp

使用方法举例:

例 1:使用 AT+CPAS?命令获取手机状态

第一步:编制 rsp 程序来处理 AT+CPAS?命令的返回结果

local sta
local function rsp(cmd,success,response,intermediate) 
  if cmd == "AT+CPAS?" then
    sta =string.match(intermediate,”+CPAS:%s*(%d)”)
    end
end

第二步:注册该处理程序

ril.regrsp("+CPAS?",rsp,2)

reguart()用来注册 uart 口的数据处理程序

串口(包括物理串口和 debug uart 口)使用之前需要先用reguart()程序来注册处理程序。

reguart()放在sys.lua 这个库文件中。

function reguart(id,fnc) 
    uartprocs[id] = fnc
end

现在的端口 id 分配如下:

物理端口 1:id = 1

物理端口 2: id = 2

debug 口: id = 3

reguart 处理流程见下面的图:

reguart

举例说明:如何使用 debuguart 口与上位机通讯

第一步:设置 debug uart 口的通讯特性

uart.setup(3,921600,8,uart.PAR_NONE,uart.STOP_1,2)--(debug uart 口波特率必须是921600 ,mode=2,使用 ID=0xA2数据透传)

第二步:编写 debug uart 的输入输出处理程序

local function huartreader() 
    local s
    while true do
        s =uart.read(3,"*l",0)
        if string.len(s) ~= 0 then 
            cmddealer(s)
        else
            break;
        end
     end
end

第三步:注册该处理程序

sys.reguart(3,huartreader)