admin管理员组文章数量:1550692
文章目录
目录
文章目录
前言
一、如何开启AT组件
二、使用步骤
1.修改控制IO引脚
2.修改状态引脚的检测
3.AT 脚手架测试CLI
前言
操作系统:win10
开发板:正点原子stm32f103旗舰版 + SIM7600CE模块
目的:在RTT中使用AT组件与SIM7600CE等AT命令设备进行快速测试验证
一、如何开启AT组件
在env工具中输入menuconfig,然后在online packages中选择IOT------AT Device
保存,退出;
然后输入pkgs --update更新包
最后,输入scons --target=mdk5 来编译整个工程。
二、使用步骤
打开工程,需要根据实际情况修改以下代码。
1.修改控制IO引脚
打开rtconfig.h文件
需要对照自己板子的硬件进行修改
由于笔者的AT_DEVICE_STATUS_PIN状态引脚没有引出,所以还需要修改源码中的一处地方。
2.修改状态引脚的检测
打开at_socket_sim76xx.c文件,注销掉模块的开关机函数对该IO的检测
然后编译,直接烧录代码到单片机中。串口打印信息如下所示:
AT组件显示初始化成功(文件系统因为没有挂载,所以显示失败),输入help查看相关命令
然后测试下网络的连通性,使用at_ping www.baidu,注意这里不能使用ping命令。
如果有自己的服务器,可以使用at_connect命令来连接服务器。
以上就是AT组件的简单使用,这里要提一下AT组件的脚手架CLI功能,因为这个功能对于测试来说比较实用。
3.AT 脚手架测试CLI
开启该功能后,我们可以直接通过调试串口发送命令给无线模块进行测试,简单的工作原理示意图如下:
开启AT脚手架功能,直接发命令at client 即可。
这样就可以根据无线模块的AT手册进行测试验证了。
上述测试了ATI和AT+CSQ指令,直接在调试串口输入指令,单片机会将调试串口的指令转发到串口3(即无线模块连接的串口)
更多的指令,可以直接参考无线模块sim7600ceAT指令手册进行测试。
AT组件脚手架实现的源码如下:
调试串口相关:
信号量、环形队列、串口接收回调函数定义
static struct rt_semaphore console_rx_notice;
static struct rt_ringbuffer *console_rx_fifo = RT_NULL;
static rt_err_t (*odev_rx_ind)(rt_device_t dev, rt_size_t size) = RT_NULL;
实现如下:主要就是备份原来的环境,设置新的环境(开启)-----恢复原来的环境(关闭),这里的环境指的是串口接收的回调函数
/*调试串口读取数据*/
static char console_getchar(void)
{
char ch;
rt_sem_take(&console_rx_notice, RT_WAITING_FOREVER);
rt_ringbuffer_getchar(console_rx_fifo, (rt_uint8_t *)&ch);
return ch;
}
/*调试串口的接收中断回调函数*/
static rt_err_t console_getchar_rx_ind(rt_device_t dev, rt_size_t size)
{
uint8_t ch;
rt_size_t i;
for (i = 0; i < size; i++)
{
/* read a char */
if (rt_device_read(dev, 0, &ch, 1))
{
rt_ringbuffer_put_force(console_rx_fifo, &ch, 1);
rt_sem_release(&console_rx_notice);
}
}
return RT_EOK;
}
/*cli init*/
void at_cli_init(void)
{
rt_base_t int_lvl;
rt_device_t console;
rt_sem_init(&console_rx_notice, "cli_c", 0, RT_IPC_FLAG_FIFO);
/* create RX FIFO */
console_rx_fifo = rt_ringbuffer_create(AT_CLI_FIFO_SIZE);
/* created must success */
RT_ASSERT(console_rx_fifo);
int_lvl = rt_hw_interrupt_disable();
console = rt_console_get_device();
if (console)
{
/* backup RX indicate */
odev_rx_ind = console->rx_indicate;/*备份原来的接收回调函数*/
rt_device_set_rx_indicate(console, console_getchar_rx_ind);/*设置新的接收回调函数*/
}
rt_hw_interrupt_enable(int_lvl);
}
/* cli deinit */
void at_cli_deinit(void)
{
rt_base_t int_lvl;
rt_device_t console;
int_lvl = rt_hw_interrupt_disable();
console = rt_console_get_device();
if (console && odev_rx_ind)
{
/* restore RX indicate */
rt_device_set_rx_indicate(console, odev_rx_ind);/*恢复原始的接收回调函数*/
}
rt_hw_interrupt_enable(int_lvl);
rt_sem_detach(&console_rx_notice);
rt_ringbuffer_destroy(console_rx_fifo);
}
sim7600ce通信的串口类似,源码如下:
static char client_getchar(void)
{
char ch;
rt_sem_take(&client_rx_notice, RT_WAITING_FOREVER);
rt_ringbuffer_getchar(client_rx_fifo, (rt_uint8_t *)&ch);
return ch;
}
static void at_client_entry(void *param)
{
char ch;
while(1)
{
ch = client_getchar();
rt_kprintf("%c", ch);
}
}
static rt_err_t client_getchar_rx_ind(rt_device_t dev, rt_size_t size)
{
uint8_t ch;
rt_size_t i;
for (i = 0; i < size; i++)
{
/* read a char */
if (rt_device_read(dev, 0, &ch, 1))
{
rt_ringbuffer_put_force(client_rx_fifo, &ch, 1);
rt_sem_release(&client_rx_notice);
}
}
return RT_EOK;
}
static void client_cli_parser(at_client_t client)
{
#define ESC_KEY 0x1B
#define BACKSPACE_KEY 0x08
#define DELECT_KEY 0x7F
char ch;
char cur_line[FINSH_CMD_SIZE] = { 0 };
rt_size_t cur_line_len = 0;
static rt_err_t (*client_odev_rx_ind)(rt_device_t dev, rt_size_t size) = RT_NULL;
rt_base_t int_lvl;
rt_thread_t at_client;
at_status_t client_odev_status;
if (client)
{
/* backup client status */
{
client_odev_status = client->status;
client->status = AT_STATUS_CLI;
}
/* backup client device RX indicate */
{
int_lvl = rt_hw_interrupt_disable();
client_odev_rx_ind = client->device->rx_indicate;
rt_device_set_rx_indicate(client->device, client_getchar_rx_ind);
rt_hw_interrupt_enable(int_lvl);
}
rt_sem_init(&client_rx_notice, "cli_r", 0, RT_IPC_FLAG_FIFO);
client_rx_fifo = rt_ringbuffer_create(AT_CLI_FIFO_SIZE);
at_client = rt_thread_create("at_cli", at_client_entry, RT_NULL, 512, 8, 8);
if (client_rx_fifo && at_client)
{
rt_kprintf("======== Welcome to using RT-Thread AT command client cli ========\n");
rt_kprintf("Cli will forward your command to server port(%s). Press 'ESC' to exit.\n", client->device->parent.name);
rt_thread_startup(at_client);
/* process user input */
while (ESC_KEY != (ch = console_getchar()))
{
if (ch == BACKSPACE_KEY || ch == DELECT_KEY)
{
if (cur_line_len)
{
cur_line[--cur_line_len] = 0;
rt_kprintf("\b \b");
}
continue;
}
else if (ch == '\r' || ch == '\n')
{
/* execute a AT request */
if (cur_line_len)
{
rt_kprintf("\n");
/*转发执行的指令*/
at_obj_exec_cmd(client, RT_NULL, "%.*s", cur_line_len, cur_line);
}
cur_line_len = 0;
}
else
{
rt_kprintf("%c", ch);
/*获取输入的AT命令*/
cur_line[cur_line_len++] = ch;
}
}
/* restore client status */
client->status = client_odev_status;
/* restore client device RX indicate */
{
int_lvl = rt_hw_interrupt_disable();
rt_device_set_rx_indicate(client->device, client_odev_rx_ind);
rt_hw_interrupt_enable(int_lvl);
}
rt_thread_delete(at_client);
rt_sem_detach(&client_rx_notice);
rt_ringbuffer_destroy(client_rx_fifo);
}
else
{
rt_kprintf("No mem for AT cli client\n");
}
}
else
{
rt_kprintf("AT client not initialized\n");
}
}
#endif /* AT_USING_CLIENT */
static void at(int argc, char **argv)
{
if (argc != 2 && argc != 3)
{
rt_kprintf("Please input '<server|client [dev_name]>' \n");
return;
}
at_cli_init();
if (!strcmp(argv[1], "server"))
{
#ifdef AT_USING_SERVER
server_cli_parser();
#else
rt_kprintf("Not support AT server, please check your configure!\n");
#endif /* AT_USING_SERVER */
}
else if (!strcmp(argv[1], "client"))
{
#ifdef AT_USING_CLIENT
at_client_t client = RT_NULL;
if (argc == 2)
{
client_cli_parser(at_client_get_first());
}
else if (argc == 3)
{
client = at_client_get(argv[2]);
if (client == RT_NULL)
{
rt_kprintf("input AT client device name(%s) error.\n", argv[2]);
}
else
{
client_cli_parser(client);
}
}
#else
rt_kprintf("Not support AT client, please check your configure!\n");
#endif /* AT_USING_CLIENT */
}
else
{
rt_kprintf("Please input '<server|client [dev_name]>' \n");
}
at_cli_deinit();
}
MSH_CMD_EXPORT(at, RT-Thread AT component cli: at <server|client [dev_name]>);
RTT AT组件方便测试验证无线模块,节省了很多时间。
脚手架源文件请参考at_cli.c文件。更多模块支持请参考下载的包中exmaple文件夹。
版权声明:本文标题:RT-Thread AT组件学习 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1727246681a1104709.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论