一种AT命令通信解析模块

仓库地址:https://gitee.com/moluo-tech/AT-Command.git

基本接口说明:

  • at_send_singlline, 发送单行命令,正确响应OK,错误响应ERROR,超时3S

  • at_send_multiline, 多行命令,正确响应OK,错误响应ERROR,超时3S

  • at_do_cmd,支持自定义发送格式与接收匹配串

  • at_do_work,支持自定义发送与接收解析

/*AT管理器 ------------------------------------------------------------------*/
typedef struct at_obj{
    at_adapter_t            adap;
    at_env_t                env;                             /* 作业运行环境*/
    at_item_t               items[10];                       /* 最大容纳10个作业*/
    at_item_t               *cursor;                         /* 当前作业项*/
    struct list_head        ls_ready, ls_idle;               /* 就绪,空闲作业链*/
    unsigned int            timer;
    unsigned int            urc_timer;                       /* urc接收计时器*/
    at_return               ret; 
    //urc接收计数, 命令响应接收计数器
    unsigned short          urc_cnt, recv_cnt;
    unsigned char           suspend: 1;
}at_obj_t; 

at_obj_t为一个AT解析器,

adap:为一个AT适配器,主要用于发送数据给AT模块和接收来自AT模块的数据
env: 记录AT解析器运行相关状态和数据
cursor:当前作业项指针
ls_ready:待处理作业表项链表节点
ls_idle:空闲作业表链表节点
items为AT解析器作业表

其将一个AT解析器看作是一个at_obj_t。
 

/*AT接口适配器 ---------------------------------------------------------------*/
typedef struct {
    unsigned int (*write)(const void *buf, unsigned int len); /* 发送接口*/
    unsigned int (*read)(void *buf, unsigned int len);        /* 接收接口*/
    void         (*error)(void);                              /* AT执行异常事件*/
    utc_item_t    *utc_tbl;                                   /* urc 表*/
    unsigned char *urc_buf;                                   /* urc接收缓冲区*/
    unsigned char *recv_buf;                                  /* 数据缓冲区*/
    unsigned short urc_tbl_count;                             /* urc表项个数*/
    unsigned short urc_bufsize;                               /* urc缓冲区大小*/
    unsigned short recv_bufsize;                              /* 接收缓冲区大小*/
}at_adapter_t;


at_adapter_t为一个AT适配器,

write和read:用来发送和接收数据接口

error:用来处理错误回调函数

utc_tbl:utc表,其意义是收到AT模块发来的匹配项(prefix)后,执行相应的动作(handler)

urc_buf:urc接收的缓存区

recv_buf:适配器接收到数据缓存区,recv_buf和urc_buf数据都是适配器收到的数据

urc_tbl_count:用来记录utc表大小
/*urc处理项 -----------------------------------------------------------------*/
typedef struct {
    const char *prefix;  //需要匹配的头部
    void (*handler)(char *recvbuf, int size); 
}utc_item_t;

/*AT作业运行环境*/
typedef struct {
    int         i,j,state;                                    
    void        *params;
    void        (*reset_timer)(struct at_obj *at); 
    bool        (*is_timeout)(struct at_obj *at, unsigned int ms); /*时间跨度判断*/
    void        (*printf)(struct at_obj *at, const char *fmt, ...);
    char *      (*find)(struct at_obj *at, const char *expect);
    char *      (*recvbuf)(struct at_obj *at);                 /* 指向接收缓冲区*/
    unsigned int(*recvlen)(struct at_obj *at);                 /* 缓冲区总长度*/
    void        (*recvclr)(struct at_obj *at);                 /* 清空接收缓冲区*/
    bool        (*abort)(struct at_obj *at);                   /* 终止执行*/
}at_env_t;

state:用来记录适配器工作状态:处于发送数据态、等待接收AT模块响应状态、等待接收AT模块超时状态见:do_cmd_handler、send_signlline_handler、send_multiline_handler

params:不同的作业类型其含义不同

#define AT_TYPE_WORK       0                             /* 普通作业 ----------*/
#define AT_TYPE_CMD        1                             /* 标准命令 ----------*/  
#define AT_TYPE_MULTILINE  2                             /* 多行命令 ----------*/
#define AT_TYPE_SINGLLINE  3                             /* 单行命令 ----------*/

为AT_TYPE_WORK时,其指向at_obj_t

为AT_TYPE_CMD时,其为NULL

为AT_TYPE_MULTILINE时,其为多行命令字符串指针

为AT_TYPE_SINGLLINE时,其为单行命令字符串指针

at_env_t中的params数据追踪:

函数add_work(at_obj_t *at, void *params, void *info, int type)的第二个参数params其赋给at_item_t中的param。

函数at_work_manager中的e->params = at->cursor->param;语句就是将at_item_t中的param赋给

at_env_t中的params

reset_timer:当适配器发送完一个作业后会调用reset_timer来更新当前时刻,以便等待AT模块响应超时,见函数do_cmd_handler、send_signlline_handler、send_multiline_handler

is_timeout:用于判断等待AT模块响应超时时间是否到达

printf:用于调试过程中打印一些信息

find:用于匹配收到来自AT模块响应字符串,此处没有间接调用find而是直接调用search_string

recvbuf:用来获取适配器接收缓存见get_recv_buf函数

recvlen:用来获取适配器接收缓存大小,见get_recv_count函数

recvclr:清除适配器中的接收区缓存数据其实质就是将at_obj_t中的recv_cnt接收数据个数清0,见recv_buf_clear函数

作业项数据结构分析:

/*AT作业项*/
typedef struct {
    unsigned int  state : 3;
    unsigned int  type  : 3;                                 /* 作业类型*/
    unsigned int  abort : 1; 
    void          *param;                                    /* 通用参数*/
	void          *info;                                     /* 通用信息指针*/
    struct list_head node;                                   /* 链表结点*/
}at_item_t;


at_item_t用于记录一个作业一些信息和状态
state:
       /*AT状态 (当前版本未用) ------------------------------------------------------*/
    typedef enum {
        AT_STATE_IDLE,                                             /* 空闲状态*/
        AT_STATE_WAIT,                                             /* 等待执行*/
        AT_STATE_EXEC,                                             /* 正在执行*/
    }at_work_state;

type:作业类型
     /**AT作业类型(实际是4种类型的状态机轮询程序) -----------------------------------*/
      #define AT_TYPE_WORK       0                             /* 普通作业 ----------*/
      #define AT_TYPE_CMD        1                             /* 标准命令 ----------*/  
      #define AT_TYPE_MULTILINE  2                             /* 多行命令 ----------*/
      #define AT_TYPE_SINGLLINE  3                             /* 单行命令 ----------*/

param:
      AT_TYPE_WORK:at_obj_t
      AT_TYPE_CMD: NULL
      AT_TYPE_MULTILINE:指向多行命令字符串指针
      AT_TYPE_SINGLLINE:指向单行命令字符串指针
info:
      AT_TYPE_WORK:普通作业执行的实际工作函数
      AT_TYPE_CMD: 指向at_cmd_t,标准命令执行的工作
      AT_TYPE_MULTILINE:指向at_callbatk_t,多行命令执行完调用的回调函数
      AT_TYPE_SINGLLINE:指向at_callbatk_t,单行命令执行完调用的回调函数
node:当前作业对应的链表节点

 可以参考其仓库中有一个wifi_task.c例子

at_poll_task:AT解析器工作函数,调用at_work_manager用来处理链表中存在的作业表,当前有作业要处理时,会将当前数据发送给AT模块,再从AT适配器中读取数据,接收到数据分成两部分处理,一个是调用urc_recv_process来搜索urc表匹配的字符串,匹配上进行相应的处理,一般用来打印调试信息,用以记录AT模块工作过程和状态,另一个是在函数at_work_manager中根据作业类型调用do_work_handler、do_cmd_handler、send_signlline_handler、send_multiline_handler来根据实际收到AT模块收到的数据做不同处理。其处理是根据作业类型来决定。如下

AT_TYPE_WORK:直接调用int (*work)(at_env_t *e),其完成的工作主要是一些不与AT模块交互的工作,因此AT_TYPE_WORK作业不用发送数据给AT模块也不必理会来自AT模块的数据

AT_TYPE_CMD:自定义发送器sender,发送完后根据每一个at_cmd_t收到匹配项matcher项作相应的处理(调用cb),AT_TYPE_CMD作业是最灵活的每一个at_cmd_t对应不同的处理

typedef struct {
    void (*sender)(at_env_t *e);                            /*自定义发送器 */
    const char *matcher;                                    /*接收匹配串 */
    at_callbatk_t  cb;                                      /*响应处理 */
    unsigned char  retry;                                   /*错误重试次数 */
    unsigned short timeout;                                 /*最大超时时间 */
}at_cmd_t;

AT_TYPE_SINGLLINE,AT_TYPE_MULTILINE:只针对AT模块回应是"OK"和"ERROR"的命令

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值