| 
 
| 1.AT Commond的介绍 AT command(V2) 一款管理AT命令通信交互组件, 适用于Modem、WIFI模块、蓝牙等使用AT命令或者ASCII命令行通信的场景,它涵盖了大部分AT通信形式,如参数设置,查询,二进制数据发送等,同时也支持自定义命令交互管理,由于它的每个命令请求都是异步的,所以对于无操作系统的环境也支持。相对于V1版本,新版本在命令接收匹配,URC不定长度数据捕获以及内存安全上做了大量优化,让它可以应对更多复杂产品应用。
 
 基本特性
 所有命令请求都是异步的,无操作系统也可以运行。
 支持单行命令,批量命令,可变参数命令以及自定义AT命令。
 支持命令响应超时,错误重传,优先级管理。
 支持不定长度URC(未经请求主动主报)消息捕获。
 支持多个AT设备通信管理。
 支持内存使用监视与限制。
 支持命令请求的生命周期管理,实时监视命令执行状态。
 支持命令透传
 系统要求
 为了能够使AT命令正常通信,目标系统必须满足以下要求:
 
 动态内存支持。
 RAM 资源:至少 1KB (取决于接收缓冲区与URC缓冲区的设置),建议在可分配3KB内存以上的系统中使用。
 编译器:系统中使用了一些C99的特性(柔性数组、内联),所以编译器需要开启对C99的支持。对于IAR,GCC它们默认是打开的,而Keil MDK需要手动增加编译选项(--c99 --gnu)。
 2.源码获取
 源码链接如下:
 
 AT Command: 一款管理AT命令通信交互组件, 适用于Modem、WIFI模块、蓝牙等使用AT命令或者ASCII命令行通信的场景。
 https://gitee.com/moluo-tech/AT-Command
 
 3.移植过程
 将如下所示的文件添加到过程中:
 
 
   
 
 添加完成后的情况如下:
 
 
   
 
 编译后若工程出现很多报错,则是该头文件未添加。添加后的文件如下:
 
 
   
 
 至此,AT-Commond V2移植完成。
 
 4.适配AT Commond的接口
 定义适配器,完成驱动接口及缓冲区设置,并在循环中轮询AT Commond。
 
 具体如下:
 
 #include "at_user.h"
 
 extern Drv_Uart_t Usart1;
 
 static at_device_t at_device;
 /*
 创建互斥锁
 用于实现AT接口
 */
 static int AT_mutex_init(void)
 {
 at_device.AT_Mutex = rt_mutex_create("AT_Mutex", RT_IPC_FLAG_PRIO);
 if (!at_device.AT_Mutex)
 {
 rt_kprintf("AT_Mutex create failed");
 }
 RTT_LOG_D("AT_Mutex create SUCCESS");
 
 
 return RT_EOK;
 }
 
 INIT_APP_EXPORT(AT_mutex_init);
 
 /*
 互斥锁锁定
 */
 static void AT_mutex_lock(void)
 {
 rt_mutex_take(at_device.AT_Mutex, RT_WAITING_FOREVER);
 }
 /*
 互斥锁解锁
 */
 static void AT_mutex_unlock(void)
 {
 rt_mutex_release(at_device.AT_Mutex);
 }
 /*
 串口数据的无阻塞性读取
 */
 static uint32_t usart_lwrb_read_data(uint8_t *data, uint32_t len)
 {
 uint32_t read_len = (uint32_t)lwrb_read(&Usart1.uart1_rx_rb, data, len);
 return read_len;
 }
 /*
 AT对象的接口实现
 */
 const at_adapter_t at_adapter = {
 .lock = AT_mutex_lock,        // 多任务上锁(非OS下填NULL)
 .unlock = AT_mutex_unlock, // 多任务解锁(非OS下填NULL)
 .write = UART1_Write,
 .read = usart_lwrb_read_data,  // 串口数据读接口(非阻塞式)
 .recv_bufsize = 256,// 接收缓冲区大小(按实际情况填写)
 .urc_bufsize = 256,
 };
 
 static int _URC_T1_Cb(at_urc_info_t *info)
 {
 RTT_LOG_E("_URC_T1_Cb");
 return 0;
 }
 
 static int __test_urc_tab(at_urc_info_t *info)
 {
 RTT_LOG_E("__test_urc_tab");
 return 0;
 }
 
 /*
 AT Commond 的urc表
 MCU收到URC表对应的前缀后,会调用对应的回调函数
 */
 static const urc_item_t urc_table[] =
 {
 // 其它URC...
 {.prefix = "+CSQ:",.endmark = '\n',.handler =_URC_T1_Cb},
 {.prefix = "AT+JJJ",.endmark = '\n',.handler =__test_urc_tab}
 };
 
 /*
 AT-Commond 线程,负责轮询AT-Commond
 注意:
 当该线程的URC表功能出现异常时,可能是由于线程的栈空间太小,导致AT对象的URC表内存未正常开辟
 最终导致在查表时找不到对应的URC数据
 */
 void AT_Thread_Enter(void *parameter)
 {
 at_device.at_obj = at_obj_create(&at_adapter);
 
 if (at_device.at_obj == NULL)
 {
 RTT_LOG_E("AT obj create failed");
 }
 
 //设置AT对象的URC表
 at_obj_set_urc(at_device.at_obj, urc_table, 2);
 
 while (1)
 {
 at_obj_process(at_device.at_obj);//这里会接收来自其他MCU发送的数据,并查询对应的URC表,若接收到的数据有含有URC表的前缀,并且后缀也存在,则会调用URC表的回调函数执行对应的操作
 rt_thread_mdelay(5);
 }
 }
 
 
 //这里是RT-Thread 创建AT Commond轮询的线程
 int AT_Commond_Init(void)
 {
 if (!RT_Thread_Create_AndStar(&(at_device.AT_Commond_Handle), "AT_Commond", AT_Thread_Enter, NULL, AT_Thread_Stack_Size, AT_Thread_Proirity, 30))
 {
 RTT_LOG_E("AT_Commond failed");
 }
 return RT_EOK;
 }
 
 INIT_APP_EXPORT(AT_Commond_Init);
 
 
 
 
 其中上述的适配AT Commond接口的读写操作,在博主的CIU32L051 实现DMA+LWRB环形队列实现的串口无阻塞性收发中已经已经实现。这里就不再多讲。
 
 5.移植验证
 这里只验证AT Commond的URC表功能,其自定义AT命令的功能,与URC表的功能相似,这里就不多做解释。
 
 
   
 
 
   
 
 具体效果如下:
 
 
   
 
 右图中的URC_buf为串口收到的对应数据,以及收到对应的URC内容后执行回调的情况,可见AT Commond V2移植成功。
 ————————————————
 版权声明:本文为CSDN博主「wxy888888」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
 原文链接:https://blog.csdn.net/wxy888888/article/details/149638587
 
 
 | 
 |