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
|
|