AT指令的一种解析想法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wuhenyouyuyouyu/article/details/83010935

       最近一直在忙着做NBlot模块,话说博客也好久没有更新了,最近整理下思路,

做下总结,权当是一片博客吧。

AT指令大家很熟悉了,这里不再做介绍(不熟悉的,请参考《GSM Rec.07.07标准AT命令》)。

一个命令类型最多分为四类:
1、设置类型,CMD=设置参数,回复OK或者ERROR;        可用通用模式解析
2、读取类型,CMD?读取参数当前值,回复+CMD:参数列表;解析返回字符串,可能做命令转变
3、测试类型,CMD=?读取默认参数值和可设置范围;       解析返回字符串,可能做命令转变,也有可能返回OK
4、执行类型,CMD  读取不可设置参数值;              解析返回字符串,可能做命令转变

这里解析主要运用到消息地图的方法,同时为了减小地图的大小,每个命令字节不具体细分是那个

命令类别,交给具体的命令解析函数去处理。如下:

//! 消息地图
const static msg_t c_tMSGMap[]  =  {
    {"AT",              JZQ_AT_CMD_AT},
    {"ATE0",            JZQ_AT_CMD_ATE0},
    {"AT$MYGMR",        JZQ_AT_CMD_MYGMR},
    {"AT$MYTYPE",       JZQ_AT_CMD_MYTYPE},
    {"ATI",             JZQ_AT_CMD_ATI},
    {"AT$MYCCID",       JZQ_AT_CMD_MYCCID},
    {"AT+CSQ",          JZQ_AT_CMD_CSQ},
    {"AT+CREG",         JZQ_AT_CMD_CREG},
    {"AT+CIMI",         JZQ_AT_CMD_CIMI},
};

在具体的命令解析函数里面,都次都可以指定NBlot模组的数据返回解析函数,做到每个命令和命令

的回复处理函数一 一对应。如下:

发送给NBlot模块命令:

    user_nblot_send(get_byte_pipe_buffer(&tBytePipe),get_byte_pipe_num(&tBytePipe));
    s_tNblotAppBuffer.pRxCallBack = JZQ_AT_CMD_MYNETWRITE_ACK; 

NBlot模块的命令接收解析:

    switch(s_tState){
        case FSM_NBLOT_PROTOCOL_START:
            s_tState = FSM_NBLOT_PROTOCOL_WAIT_DATA;
            s_tNBlotAppBuffer.hwBufferSize = 0;
            //break;
        case FSM_NBLOT_PROTOCOL_WAIT_DATA:
            if(nblot_rx_buffer_is_empty()){
                break;
            }
            s_tState = FSM_NBLOT_PROTOCOL_REV_FRAME;
            //break;
        case FSM_NBLOT_PROTOCOL_REV_FRAME:
            tFsmRt = nblot_protocol_revice_frame();
            if(fsm_rt_cpl ==  tFsmRt|| fsm_rt_buffer_full == tFsmRt){
                s_tState = FSM_NBLOT_PROTOCOL_HANDLE;
            }else if(fsm_rt_err == tFsmRt){
                RESET_FSM_NBLOT_PROTOCOL();
                return fsm_rt_err;
            }
            break;
        case FSM_NBLOT_PROTOCOL_HANDLE:
            if(NULL != s_ptRxCallBack){
                s_ptRxCallBack(s_tNBlotAppBuffer.chBuffer,s_tNBlotAppBuffer.hwBufferSize);
            }
            RESET_FSM_NBLOT_PROTOCOL();
            return fsm_rt_cpl;
        default:
            FSM_DEFAULT_ACTION();
    }

至此一个大体的AT命令解析架构介绍完毕了,但是这个架构会有一个问题,

就是如果仅仅考虑问答式命令形式,这个架构再加一个超时无效处理的维护

线程就可以(维护线程就干一件事情,发送命令后,启动维护线程,设置超

时命令,如果在设置的超时时间内回复,则通过发送命令时候指定的处理函

数解析,如果超时了,就把指针清NULL,同时发送超时消息)。如果还要考

虑主动上报,那么上面的架构就需要在(每个)处理函数里面加入主动上报

的处理逻辑,否则逻辑上就不对。这样就会产生很多“脏代码”,处理方法是利

用行为继承,在FSM_NBLOT_PROTOCOL_HANDLE前面增加一个DEFULT_HANDLE

处理,把一些通用或者主动上报的(每个命令帧都需要考虑的情况)打包成一个处理函数。

到目前为止,AT指令解析,基本讲完了,说些题外话:

1、下行数据可能要考虑拼包问题,因为在测试过程中发现主站下发一个APDU,在模块

      端会被分为两个socket包,并且时间间隔还很长(目前监控到最长30S);这里有一

      个问题,如果考虑拼包,那么就和协议关联了。

2、socket会自己断开,一定要有重建机制;

2018.10.23

       前几天和一位老工程师交流这个AT指令解析方法,有一些心得,记录下,也算是一种

思想上的提高。

        这个解析方法有个确实,就是当指令阅读,消息地图越大,检索时间越长。如果系统

要求这个检索时间和地图大小无关,时间是“确定”的,怎么解决?

        首先我们就想到是什么?什么情况下检索时间和数据表大小无关?我们是不是想到了

数组下标,查表的方法。没错,查表的时间确定,并且和表的大小无关。那么我们怎么进行

查表呢?首先我们需要有一个格式化算法,把AT指令流格式化为数组下标,然后用数组下标

直接查表来得到解析函数。

        这个格式化的算法怎么设计,我目前还没有很好的思路,如果你有什么好的想法,请留言

给我。

猜你喜欢

转载自blog.csdn.net/wuhenyouyuyouyu/article/details/83010935