【Zephyr 系列 4】串口通信进阶:打造自己的 AT 命令框架
🧠关键词:Zephyr、UART、串口通信、AT命令、Shell、RTOS
📌适合人群:希望开发设备控制协议、调试接口、CLI 命令的嵌入式开发者
🎯 本篇目标
-
使用 Zephyr 提供的 UART API 与 Shell 模块
-
实现一套可扩展的
AT+CMD
风格串口命令框架 -
支持查询、设置两类命令:如
AT+LED=ON
、AT+STATUS?
📦 环境与硬件
项目 | 描述 |
---|---|
硬件 | STM32F103C8T6 / Arduino MEGA 等 Zephyr 支持平台 |
工具链 | Zephyr SDK + west |
串口终端 | minicom / screen / serial monitor |
🏗 项目结构
zephyr-atcmd/
├── app/
│ ├── src/
│ │ ├── main.c
│ │ ├── at_cmd.c
│ │ └── at_cmd.h
│ ├── prj.conf
│ └── CMakeLists.txt
🧠 思路简述
-
使用
uart_poll_in()
从串口读取字符 -
每次读取直到遇到
\n
为止,组成完整 AT 命令 -
解析出命令类型(SET/READ)和参数
-
通过
strcmp()
分发到相应 handler 函数处理
📄 main.c
#include "at_cmd.h"void main(void) {printk("AT Command Framework Start\n");at_cmd_init();while (1) {at_cmd_poll(); // 持续处理串口输入k_msleep(10);}
}
📄 at_cmd.h
#ifndef AT_CMD_H
#define AT_CMD_Hvoid at_cmd_init(void);
void at_cmd_poll(void);#endif // AT_CMD_H
📄 at_cmd.c
#include <zephyr.h>
#include <device.h>
#include <drivers/uart.h>
#include <string.h>
#include <stdio.h>
#include "at_cmd.h"#define BUF_SIZE 64
static char input_buf[BUF_SIZE];
static int input_pos = 0;
static const struct device *uart;void at_cmd_init(void) {uart = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));if (!device_is_ready(uart)) {printk("UART not ready\n");}
}static void handle_cmd(const char *cmd) {if (strcmp(cmd, "AT+LED=ON") == 0) {printk("LED turned ON\n");// todo: 实际控制 LED} else if (strcmp(cmd, "AT+LED=OFF") == 0) {printk("LED turned OFF\n");} else if (strcmp(cmd, "AT+STATUS?") == 0) {printk("STATUS: OK\n");} else {printk("ERR: Unknown command [%s]\n", cmd);}
}void at_cmd_poll(void) {uint8_t c;while (uart_poll_in(uart, &c) == 0) {if (c == '\r') continue;if (c == '\n') {input_buf[input_pos] = '\0';handle_cmd(input_buf);input_pos = 0;} else if (input_pos < BUF_SIZE - 1) {input_buf[input_pos++] = c;}}
}
📄 prj.conf
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_PRINTK=y
🔌 测试串口命令
使用串口终端连接开发板,例如:
screen /dev/ttyUSB0 115200
尝试输入以下命令:
AT+LED=ON
AT+LED=OFF
AT+STATUS?
AT+FOO
输出结果类似:
LED turned ON
LED turned OFF
STATUS: OK
ERR: Unknown command [AT+FOO]
📚 拓展建议(进阶方向)
目标 | 技术 |
---|---|
添加 AT+PWM=xxx 控制 | 参数提取与类型转换 |
支持 AT+RESET 重启 MCU | 调用 sys_reboot(SYS_REBOOT_COLD) |
支持 JSON/Hex 等格式 | 字符串预处理与编码解析 |
使用 ringbuffer 替代临时缓冲区 | 增强稳定性和线程安全 |
将 Shell + AT 模块合并 | 支持双模式:手动命令 / 系统调试 |
📦 下一篇预告:《使用定时器与低功耗控制优化你的 MCU 项目》
我们将使用 k_timer
+ Zephyr 电源管理系统,实现自动唤醒、周期性采样与低功耗运行。