Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
学习笔记
【rtthread高级】第二篇:AT组件
发布于 2021-05-20 21:33:21 浏览:2369
订阅该版
[tocm] # 一、AT组件概念 ## 1.1 AT命令概念 AT命令是由发明拨号调制解调器modem的hayes公司为了控制modem发明的控制协议,后来移动电话厂家为GSM提供了标准的AT命令用于控制手机的GSM模块。  ## 1.2 rtthread AT组件资源占用 * AT Client 功能: 4.6K ROM 和 2.0K RAM; * AT Server 功能: 4.0K ROM 和 2.5K RAM; * AT CLI 功能: 1.5K ROM ,几乎没有使用 RAM。 ## 1.3 AT组件功能 ### AT Server: • 基础命令:实现多种通用基础命令(ATE、 ATZ 等); • 命令兼容:命令支持忽略大小写,提高命令兼容性; • 命令检测:命令支持自定义参数表达式,并实现对接收的命令参数自检测功能; • 命令注册:提供简单的用户自定义命令添加方式,类似于 finsh/msh 命令添加方式; • 调试模式:提供 AT Server CLI 命令行交互模式,主要用于设备调试。 ### AT Client: • URC 数据处理:完备的 URC 数据的处理方式; • 数据解析:支持自定义响应数据的解析方式,方便获取响应数据中相关信息; • 调试模式:提供 AT Client CLI 命令行交互模式,主要用于设备调试。 • AT Socket:作为 AT Client 功能的延伸,使用 AT 命令收发作为基础,实现标准的 BSD Socket API,完成数据的收发功能,使用户通过 AT 命令完成设备连网和数据通讯。 • 多客户端支持: AT 组件目前支持多客户端同时运行。 # 二、AT组件api ## 2.1 server api ### 2.1.1 api ``` //AT server初始化,如果使能了自动初始化则不需要 int at_server_init(void); //注册自定义AT命令 /* _name_:自定义AT命令名称,如: "AT+TEST" _args_expr_:AT 命令参数表达式;(无参数为 NULL, <> 中为必选参数, [] 中为可选参数),如 =
[,
] _test_:AT测试函数 _query_:AT查询函数 _setup_:AT设置函数 _exec_:AT执行函数 */ AT_CMD_EXPORT(_name_, _args_expr_, _test_, _query_, _setup_, _exec_); //发送数据到客户端 /* format:自定义发送数据的表达式 ...:发送数据列表 */ void at_server_printf(const char *format, ...); //带换行的发送数据到客户端 void at_server_printfln(const char *format, ...); //向客户端发送执行结果 /* result:执行结果,可取 AT_RESULT_OK 命令执行成功 AT_RESULT_FAILE 命令执行失败 AT_RESULT_NULL 命令无返回结果 AT_RESULT_CMD_ERR 输入命令错误 AT_RESULT_CHECK_FAILE 参数表达式匹配错误 AT_RESULT_PARSE_FAILE 参数解析错误 */ void at_server_print_result(at_result_t result); //解析设置命令参数 /* req_args:设置命令输入参数字符串 req_expr:解析表达式 ...:用于存放解析出的参数 */ int at_req_parse_args(const char *req_args, const char *req_expr, ...); ``` ### 2.1.2 server api示例 ``` static at_result_t at_test_setup(const char *args) { int value1,value2; /* args 的 输 入 标 准 格 式 应 为 "=1,2", "=%d,%d" 为 自 定 义 参 数 解 析 表 达 式, 解 析 得 到 结 果 存 入 value1 和 value2 变 量 */ if (at_req_parse_args(args, "=%d,%d", &value1, &value2) > 0) { /* 数 据 解 析 成 功, 回 显 数 据 到 AT Server 串 口 设 备 */ at_server_printfln("value1 : %d, value2 : %d", value1, value2); /* 数 据 解 析 成 功, 解 析 参 数 的 个 数 大 于 零, 返 回 执 行 成 功 */ at_server_print_result(AT_RESULT_OK); } else { /* 数 据 解 析 失 败, 解 析 参 数 的 个 数 不 大 于 零, 返 回 解 析 失 败 结 果 类 型 */ at_server_print_result(AT_RESULT_PARSE_FAILE); } return 0; } /* 添 加 "AT+TEST" 命 令 到 AT 命 令 列 表, 命 令 参 数 格 式 为 两 个 必 选 参 数
和
*/ AT_CMD_EXPORT("AT+TEST", =
,
, NULL, NULL, at_test_setup, NULL); ``` ## 2.2 client api rtthread将AT的响应抽象成rt_response ``` struct at_response { /* response buffer */ char *buf; /* the maximum response buffer size */ rt_size_t buf_size; /* the number of setting response lines * == 0: the response data will auto return when received 'OK' or 'ERROR' * != 0: the response data will return when received setting lines number data */ rt_size_t line_num; /* the count of received response lines */ rt_size_t line_counts; /* the maximum response time */ rt_int32_t timeout; }; typedef struct at_response *at_response_t; ``` ### 2.2.1 client 处理响应数据api ``` //创建响应结构体句柄,用于接收来自AT server的响应 /* buf_size:最大接收数据长度 line_num:接收响应的行数 timeout:接收响应的最大时间 */ at_response_t at_create_resp(rt_size_t buf_size, rt_size_t line_num, rt_int32_t timeout); //删除响应结构体句柄 /* resp:响应结构体句柄 */ void at_delete_resp(at_response_t resp); //修改响应结构体的参数 /* resp:响应结构体句柄 buf_size、line_num、timeout同at_create_resp */ at_response_t at_resp_set_info(at_response_t resp, rt_size_t buf_size, rt_size_t line_num, rt_int32_t timeout); //发送命令并接收响应 /* resp:响应结构体句柄 cmd_expr:AT命令表达式 ...:输入参数 */ rt_err_t at_exec_cmd(at_response_t resp, const char *cmd_expr, ...); //获取响应数据中指定行的数据 /* resp:响应结构体句柄 resp_line:行号 */ const char *at_resp_get_line(at_response_t resp, rt_size_t resp_line); //获取指定关键字的响应 /* resp:响应结构体句柄 keyword:关键字字符串 返回:带有指定关键字的响应数据指针 */ const char *at_resp_get_line_by_kw(at_response_t resp, const char *keyword); //解析指定行的数据 /* resp:响应结构体句柄 resp_line:行号 resp_expr:解析表达式 ...:用于存放解析到的数据 */ int at_resp_parse_line_args(at_response_t resp, rt_size_t resp_line, const char *resp_expr, ...); //解析带指定关键字的响应数据 /* resp:响应句柄 key_word:关键字字符串 resp_expr:解析表达式 ...:用于存放解析到的数据 */ int at_resp_parse_line_args_by_kw(at_response_t resp, const char *keyword, const char *resp_expr, ...); ``` ### 2.2.2 client 处理响应数据api示例 ``` /* 创 建 服 务 器 响 应 结 构 体, 64 为 用 户 自 定 义 接 收 数 据 最 大 长 度 */ resp = at_create_resp(64, 0, rt_tick_from_millisecond(5000)); /* 发 送 数 据 到 服 务 器, 并 接 收 响 应 数 据 存 放 在 resp 结 构 体 中 */ at_exec_cmd(resp, "AT+UART?"); /* 解 析 获 取 串 口 配 置 信 息, 1 表 示 解 析 响 应 数 据 第 一 行, '%*[^=]'表 示 忽 略 等 号 之 前 的 数 据 */ at_resp_parse_line_args(resp, 1,"%*[^=]=%d,%d,%d,%d,%d", &baudrate, &databits, & stopbits, &parity, &control); printf("baudrate=%d, databits=%d, stopbits=%d, parity=%d, control=%d\n", baudrate, databits, stopbits, parity, control); /* 删 除 服 务 器 响 应 结 构 体 */ at_delete_resp(resp); ``` ### 2.2.3 client URC数据处理api rtthread将AT的URC数据抽象成rt_urc ``` struct at_urc { const char *cmd_prefix; // URC 数 据 前 缀 const char *cmd_suffix; // URC 数 据 后 缀 void (*func)(const char *data, rt_size_t size); // URC 数 据 执 行 函 数 }; typedef struct at_urc *at_urc_t; ``` ``` //设置urc数据列表 /* table:URC句柄数组指针 size:有多少个at_urc */ void at_set_urc_table(const struct at_urc *table, rt_size_t size); ``` ### 2.2.4 client URC数据处理api示例 ``` static void urc_conn_func(const char *data, rt_size_t size) { /* WIFI 连 接 成 功 信 息 */ LOG_D("AT Server device WIFI connect success!"); } static void urc_recv_func(const char *data, rt_size_t size) { /* 接 收 到 服 务 器 发 送 数 据 */ LOG_D("AT Client receive AT Server data!"); } static void urc_func(const char *data, rt_size_t size) { /* 设 备 启 动 信 息 */ LOG_D("AT Server device startup!"); } static struct at_urc urc_table[] = { {"WIFI CONNECTED", "\r\n", urc_conn_func}, {"+RECV", ":", urc_recv_func}, {"RDY", "\r\n", urc_func}, }; int at_client_port_init(void) { /* 添 加 多 种 URC 数 据 至 URC 列 表 中, 当 接 收 到 同 时 匹 配 URC 前 缀 和 后 缀 的 数 据, 执 行 URC 函 数 */ at_set_urc_table(urc_table, sizeof(urc_table) / sizeof(urc_table[0])); return RT_EOK; } ``` ### 2.2.5 client 其它api ``` //发送指定大小的数据 /* buf:发送缓冲区 size:发送数据大小 */ rt_size_t at_client_send(const char *buf, rt_size_t size); //接收指定大小数据 /* buf:接收缓冲区 size:接收数据大小 timeout:接收超时时间 */ rt_size_t at_client_recv(char *buf, rt_size_t size,rt_int32_t timeout) //设置接收数据的行结束符 /* ch:希望的结束字符 */ void at_set_end_sign(char ch); //等待模块初始化完成,该函数一直发送AT命令直到模块响应 /* timeout:等待超时时间 */ int at_client_wait_connect(rt_uint32_t timeout); ```
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
happycode999
这家伙很懒,什么也没写!
文章
28
回答
6
被采纳
0
关注TA
发私信
相关文章
1
信号量的学习笔记 - 观察内存消耗
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
rt-smart
FAL
I2C_IIC
cubemx
ESP8266
WIZnet_W5500
UART
BSP
ota在线升级
PWM
flash
packages_软件包
freemodbus
潘多拉开发板_Pandora
ADC
GD32
定时器
flashDB
编译报错
keil_MDK
socket
中断
rt_mq_消息队列_msg_queue
Debug
ulog
SFUD
msh
C++_cpp
at_device
本月问答贡献
聚散无由
9
个答案
6
次被采纳
RTT_逍遥
10
个答案
2
次被采纳
a1012112796
5
个答案
2
次被采纳
三世执戟
4
个答案
2
次被采纳
加缪
2
个答案
2
次被采纳
本月文章贡献
wake_mirco
2
篇文章
7
次点赞
mushroom
1
篇文章
9
次点赞
张世争
1
篇文章
7
次点赞
RTT_逍遥
1
篇文章
6
次点赞
Jack_____
1
篇文章
5
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部