AT组件提供了MCU与外接通信模组间基于AT命令的基础通信能力,是物联网应用场景中不可或缺的模块之一。基于该组件,用户可以只关注AT指令的语义,无需关心AT指令的收发过程,简化外接模组的AT通信驱动的开发。下图是AliOS Things中AT组件的结构示意图。其包括:

- AT Core:AT组件核心模块,主要包括AT配置处理、AT接收分发,AT设备管理。该模块实现AT接收、发处理、添加AT设备主流程。
- AT API:AT组件API,主要包括发送、注册回调、数据读取、初始化、去初始化、添加设备、删除设备。该模块封装了AT核心模块的功能,简化了用户的调用方式。
API列表
名称 | 说明 |
at_init | 初始化AT组件 |
at_deinit | 去初始化AT组件 |
at_add_dev | 根据配置添加AT设备 |
at_delete_dev | 根据设备描述符删除AT设备 |
at_send_wait_reply | 在用户task中,使用该接口发送数据,并等待回复 |
at_send_no_reply | 使用该接口发送数据,但不等待回复 |
at_read | 在回调函数里,从底层读取AT字符流 |
at_register_callback | 注册AT接收处理回调函数 |
at_yield | 单task情况下,从底层接收数据 |
使用
添加该组件
在使用at的组件或应用对应的aos.mk中添加
$(NAME)_COMPONENTS += at
在使用at的组件或应用对应的Config.in中添加
select AOS_COMP_AT if !AOS_CREATE_PROJECT
头文件
对外头文件代码位于include/utility/at
,包括
at.h
使用时只需包含
#include "at/at.h"
使用示例
/* 初始化 */
at_init();
/**
* 配置AT设备参数
*/
uart_dev.port = 1;
uart_dev.config.baud_rate = 9600;
uart_dev.config.data_width = DATA_WIDTH_8BIT;
uart_dev.config.parity = NO_PARITY;
uart_dev.config.stop_bits = STOP_BITS_1;
uart_dev.config.flow_control = FLOW_CONTROL_DISABLED;
uart_dev.config.mode = MODE_TX_RX;
at_config.type = AT_DEV_UART;
at_config.port = uart_dev.port;
at_config.dev_cfg = &uart_dev;
at_config.send_wait_prompt = 0;
/* 添加AT设备,成功后返回设备fd */
if ((at_dev_fd = at_add_dev(&at_config)) < 0) {
LOGE(TAG, "AT parser device add failed!\n");
return -1;
}
/* 注册感兴趣前缀对应的回调处理 */
at_register_callback(at_dev_fd, "+NSONMI:", NULL, NULL, 0,
m5310a_socket_data_indicator_handler, NULL);
/* 发送AT test命令 */
memset(cmd, 0, sizeof(cmd));
snprintf(cmd, sizeof(cmd) - 1, "%s", "AT");
/* 发送并等待回复 */
at_send_wait_reply(at_dev_fd, cmd, strlen(cmd), true, NULL, 0,
rsp, M5310A_DEFAULT_RSP_LEN, NULL);
if (strstr(rsp, "OK") == NULL) {
LOGE(TAG, "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
return -1;
}
更详细的例子请参考application/example/example_legacy/at_app
API 详情
at_init
原型
int at_init(void);
接口说明
初始化AT组件。
参数说明
无
返回值说明
值 | 说明 |
---|---|
0 | 成功 |
负值 | 失败 |
接口示例
/* 初始化,先于其他API前调用 */
at_init();
at_deinit
原型
int at_deinit(void);
接口说明
去初始化AT组件。
参数说明
无
返回值说明
值 | 说明 |
---|---|
0 | 成功 |
负值 | 失败 |
接口示例
/* 去初始化 */
at_deinit();
at_add_dev
原型
int at_add_dev(at_config_t *config);
接口说明
根据配置添加AT设备。
参数说明
参数 | 数据类型 | 方向 | 说明 |
---|---|---|---|
config | at_config_t * | 输入 | AT设备配置,at_config_t定义见标准宏和结构体定义 |
返回值说明
值 | 说明 |
---|---|
非负值 | 成功,AT设备文件描述符 |
负值 | 失败 |
接口示例
/**
* 配置AT设备参数
*/
uart_dev.port = 1;
uart_dev.config.baud_rate = 9600;
uart_dev.config.data_width = DATA_WIDTH_8BIT;
uart_dev.config.parity = NO_PARITY;
uart_dev.config.stop_bits = STOP_BITS_1;
uart_dev.config.flow_control = FLOW_CONTROL_DISABLED;
uart_dev.config.mode = MODE_TX_RX;
at_config.type = AT_DEV_UART;
at_config.port = uart_dev.port;
at_config.dev_cfg = &uart_dev;
at_config.send_wait_prompt = 0;
/* 添加AT设备,成功后返回设备fd */
if ((at_dev_fd = at_add_dev(&at_config)) < 0) {
LOGE(TAG, "AT parser device add failed!\n");
return -1;
}
at_delete_dev
原型
int at_delete_dev(int fd);
接口说明
根据设备描述符删除AT设备。
参数说明
参数 | 数据类型 | 方向 | 说明 |
---|---|---|---|
fd | int | 输入 | AT设备文件描述符 |
返回值说明
值 | 说明 |
---|---|
0 | 成功 |
负值 | 失败 |
接口示例
/* 添加AT设备,成功后返回设备fd */
if ((at_dev_fd = at_add_dev(&at_config)) < 0) {
LOGE(TAG, "AT parser device add failed!\n");
return -1;
}
/* 删除fd对应的AT设备 */
if ((at_delete_dev(at_dev_fd)) < 0) {
LOGE(TAG, "AT parser device delete failed!\n");
return -1;
}
at_send_wait_reply
原型
int at_send_wait_reply(int fd, const char *cmd, int cmdlen, bool delimiter,
const char *data, int datalen,
char *replybuf, int bufsize,
const at_reply_config_t *atcmdconfig);
接口说明
在用户task中,使用该接口发送数据,并等待回复。
参数说明
参数 | 数据类型 | 方向 | 说明 |
---|---|---|---|
fd | int | 输入 | AT设备文件描述符 |
cmd | const char * | 输入 | 准备发送的命令字符串 |
cmdlen | int | 输入 | 命令字符串长度 |
delimiter | bool | 输入 | 是否添加分割符号 |
const char * | const char * | 输入 | 准备发送的数据字符串 |
datalen | int | 输入 | 数据长度 |
replybuf | char * | 输出 | 回复缓存指针,由调用者提供 |
bufsize | int | 输入 | 回复缓存大小 |
atcmdconfig | const at_reply_config_t * | 输入 | 回复前缀、成功后缀、失败后缀等配置 |
返回值说明
值 | 说明 |
---|---|
0 | 成功 |
负值 | 失败 |
接口示例
/* 发送AT test命令 */
memset(cmd, 0, sizeof(cmd));
snprintf(cmd, sizeof(cmd) - 1, "%s", "AT");
/* 发送并等待回复 */
at_send_wait_reply(at_dev_fd, cmd, strlen(cmd), true, NULL, 0,
rsp, M5310A_DEFAULT_RSP_LEN, NULL);
/* 检查是否包含期望字符 */
if (strstr(rsp, "OK") == NULL) {
LOGE(TAG, "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
return -1;
}
at_send_no_reply
原型
int at_send_no_reply(int fd, const char *data, int datalen, bool delimiter);
接口说明
使用该接口发送数据,但不等待回复。
参数说明
参数 | 数据类型 | 方向 | 说明 |
---|---|---|---|
fd | int | 输入 | AT设备文件描述符 |
const char * | const char * | 输入 | 准备发送的数据字符串 |
datalen | int | 输入 | 数据长度 |
返回值说明
值 | 说明 |
---|---|
0 | 成功 |
负值 | 失败 |
接口示例
/* 准备AT test命令 */
memset(cmd, 0, sizeof(cmd));
snprintf(cmd, sizeof(cmd) - 1, "%s", "AT");
/* 发送cmd,无等待 */
at_send_no_reply(at_dev_fd, cmd, strlen(cmd), true);
at_read
原型
int at_read(int fd, char *outbuf, int readsize);
接口说明
在回调函数里,从底层读取AT字符流。
参数说明
参数 | 数据类型 | 方向 | 说明 |
---|---|---|---|
fd | int | 输入 | AT设备文件描述符 |
char * | char * | 输出 | 缓存指针 |
readsize | int | 输入 | 读取长度 |
返回值说明
值 | 说明 |
---|---|
非负 | 成功,读取长度 |
负值 | 失败 |
接口示例
while (data != ',') {
/* 从对应fd读取数据,一般只在回调函数里调用*/
ret = at_read(at_dev_fd, &data, 1);
if (ret != 1) {
break;
}
/* 解析读出的数据*/
if(data >= '0' && data <= '9') {
fd = fd * 10 + (data - '0');
}
}
at_register_callback
原型
int at_register_callback(int fd, const char *prefix, const char *postfix, char *recvbuf,
int bufsize, at_recv_cb cb, void *arg);
接口说明
注册AT接收处理回调函数
参数说明
参数 | 数据类型 | 方向 | 说明 |
---|---|---|---|
fd | int | 输入 | AT设备文件描述符 |
const char * | const char * | 输入 | 感兴趣的前缀,必须 |
postfix | const char * | 输入 | 感兴趣的后缀,可选 |
recvbuf | char * | 输入 | 用于缓存前缀后缀之间的数据 |
bufsize | int | 输入 | 缓存大小 |
cb | at_recv_cb | 输入 | 回调处理函数 |
arg | void * | 输入 | 回调处理函数参数 |
返回值说明
值 | 说明 |
---|---|
0 | 成功 |
负值 | 失败 |
接口示例
/* 注册多个前缀对应的回调函数 */
at_register_callback(at_dev_fd, "+NSONMI:", NULL, NULL, 0,
m5310a_socket_data_indicator_handler, NULL);
at_register_callback(at_dev_fd, "\r\nCONNECT OK", NULL, NULL, 0,
m5310a_socket_connect_indicator_handler, NULL);
at_register_callback(at_dev_fd, "+NSOCLI:", NULL, NULL, 0,
m5310a_socket_close_indicator_handler, NULL);
at_yield
原型
int at_yield(int fd, char *replybuf, int bufsize, const at_reply_config_t *atcmdconfig,
int timeout_ms);
接口说明
单task情况下,从底层接收数据。
参数说明
参数 | 数据类型 | 方向 | 说明 |
---|---|---|---|
fd | int | 输入 | AT设备文件描述符 |
char * | char * | 输出 | 接收缓存 |
bufsize | int | 输入 | 缓存大小 |
atcmdconfig | const at_reply_config_t * | 输入 | 接收前缀、成功后缀、失败后缀配置 |
timeout_ms | int | 输入 | 超时时间 |
返回值说明
值 | 说明 |
---|---|
0 | 成功 |
负值 | 失败 |
接口示例
/* 单task时, 调用该函数从底层缓存中收取数据并处理回调 */
at_yield(at_dev_fd, NULL, 0, NULL, 200);
配置说明
AT可配置项包括:
- 是否定义AOS_ATCMD,默认为定义AOS_ATCMD
- 最大AT设备数,默认是1
- AT发送后等待超时时间,默认为是5000ms
- AT读取超时时间,默认为1000ms
- AT分段发送时等待提示符超时时间,默认为200ms
移植说明
AT模块需要实现AT设备操作wrapper、系统wrapper。
AT设备操作wrapper
接口 | 描述 |
int (*init)(void *dev) |
初始化设备 dev:设备参数 返回值:0成功,-1失败 |
int (*recv)(void *dev, void *data, uint32_t expect_size, uint32_t *recv_size, uint32_t timeout) |
数据接收 dev:设备参数 data:数据地址 expect_size:期望长度 recv_size:接收长度 timeout:接收超时时长 返回值:0成功,-1失败 |
int (*send)(void *dev, void *data, uint32_t size, uint32_t timeout) |
数据发送 dev:设备参数 data:数据地址 size:长度 timeout:超时时长 返回值:>0发送长度,-1失败 |
int (*deinit)(void *dev) |
去初始化 dev:设备参数 返回值:0成功,-1失败 |
系统wrapper
锁函数
函数名 | 说明 |
---|---|
void *atpsr_mutex_new(void) | 创建锁 |
void atpsr_mutex_lock(void *mutex) | 上锁 |
void atpsr_mutex_unlock(void *mutex) | 开锁 |
void atpsr_mutex_free(void *mutex) | 删除锁 |
信号量函数
函数名 | 说明 |
---|---|
void *atpsr_sem_new(void) | 创建信号量 |
void atpsr_sem_signal(void *sem) | 释放信号量 |
int atpsr_sem_wait(void *sem, uint32_t timeout_ms) | 等待信号量 |
void atpsr_sem_free(void *sem) | 删除信号量 |
任务函数
函数名 | 说明 |
---|---|
int atpsr_task_new_ext(void *task, char *name, void (*fn)(void *), void *arg, int stack_size, int prio) | 创建任务 |
void atpsr_sleep_ms(const unsigned int millisec) | 休眠任务 |
内存函数
函数名 | 说明 |
---|---|
void *atpsr_malloc(uint32_t size) | 分配内存 |
void atpsr_free(void *ptr) | 释放内存 |
标准宏和结构体说明
结构体at_config_t定义
typedef struct {
uint8_t port; // 端口号
at_dev_type_t type; // AT设备类型,例如UART
void *dev_cfg; // AT设备底层参数,例如hal/uart.h中的uart_config_t
at_reply_config_t reply_cfg; // AT接收前缀、后缀
char *send_delimiter; // AT发送分割符
uint32_t timeout_ms; // AT发送或接收超时
uint8_t send_wait_prompt; // AT发送数据时是否等待提示符
uint32_t prompt_timeout_ms; // AT发送数据时等待提示符超时时间
uint8_t send_data_no_wait; // AT发送数据后是否等待回复
int recv_task_priority; // AT接收task优先级
int recv_task_stacksize; // AT接收task栈大小
} at_config_t;
结构体at_reply_config_t定义
typedef struct {
char *reply_prefix; // 回复前缀
char *reply_success_postfix; // 成功后缀
char *reply_fail_postfix; // 失败后缀
} at_reply_config_t;
结构体at_dev_ops_t定义
typedef struct {
at_dev_type_t type;
int (*init)(void *dev);
int (*recv)(void *dev, void *data, uint32_t expect_size,
uint32_t *recv_size, uint32_t timeout);
int (*send)(void *dev, void *data, uint32_t size,
uint32_t timeout);
int (*deinit)(void *dev);
} at_dev_ops_t;
在文档使用中是否遇到以下问题
更多建议
匿名提交