当前位置: 首页 > news >正文

【Zephyr 系列 4】串口通信进阶:打造自己的 AT 命令框架

🧠关键词:Zephyr、UART、串口通信、AT命令、Shell、RTOS
📌适合人群:希望开发设备控制协议、调试接口、CLI 命令的嵌入式开发者


🎯 本篇目标

  • 使用 Zephyr 提供的 UART API 与 Shell 模块

  • 实现一套可扩展的 AT+CMD 风格串口命令框架

  • 支持查询、设置两类命令:如 AT+LED=ONAT+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 电源管理系统,实现自动唤醒、周期性采样与低功耗运行。

http://www.lqws.cn/news/82315.html

相关文章:

  • 现代语言模型中的分词算法全解:从基础到高级
  • 前端框架Vue
  • 详细解析2MHz和3MHz压电陶瓷片的区别
  • 空间智能重塑未来治理
  • MySQL中的事务
  • Java垃圾回收算法及GC触发条件
  • 齐次变换矩阵与运动旋量的指数映射
  • 操作系统学习(十一)——磁盘
  • 第12次13: 修改登录密码
  • PID项目-记事本不显示下划线
  • Spring AI 之检索增强生成(Retrieval Augmented Generation)
  • 每日算法刷题计划Day20 6.2:leetcode二分答案3道题,用时1h20min
  • cursor如何开启自动运行模式
  • leetcode0513. 找树左下角的值-meidum
  • 案例:TASK OA
  • unidbg patch 初探 微博deviceId 案例
  • vue中父子参数传递双向的方式不同
  • 如何提升大模型召回率和实战案例
  • 【数据分析】第二章 Python基础
  • 渗透测试之信息搜集
  • window/linux ollama部署模型
  • vscode中的markdown表格列宽
  • 【LeetCode 热题100】BFS/DFS 实战:岛屿数量 腐烂的橘子(力扣200 / 994 )(Go语言版)
  • Unity中的MonoSingleton<T>与Singleton<T>
  • Day10
  • leetcode刷题日记——二叉树的层次遍历
  • 全文索引详解及适用场景分析
  • 【Unity】云渲染
  • Ubuntu22.04 安装 CUDA12.8
  • 为什么ping显示connect:network is unreachable,如何排查网络不通问题?