以下是关于 FreeRTOS-Plus-CLI 的详细介绍和使用指南,涵盖其核心功能、集成方法、典型应用场景及示例代码:
- FreeRTOS-Plus-CLI 是什么?
定位:FreeRTOS 的官方扩展组件,提供 命令行接口(Command Line Interface),允许开发者通过串口、网络等输入命令与 FreeRTOS 系统交互。
核心功能:
动态注册和管理自定义命令。
支持命令参数解析(如字符串、数字)。
提供标准命令(查看任务列表、内存状态等)。
适用于调试、监控和设备控制。 - 典型应用场景
调试与监控:查看任务状态、堆栈使用情况、系统运行时间。
设备控制:通过命令控制硬件(如 GPIO、传感器)。
动态配置:运行时修改系统参数(如任务优先级、定时器周期)。 - 集成 FreeRTOS-Plus-CLI
步骤 1:添加源码到工程
从 FreeRTOS 官网 下载 FreeRTOS-Plus 包。
将以下文件添加到工程:
FreeRTOS-Plus-CLI/FreeRTOS_CLI.c
FreeRTOS-Plus-CLI/FreeRTOS_CLI.h
步骤 2:初始化 CLI
在 FreeRTOS 任务中初始化 CLI 并处理输入输出:
#include “FreeRTOS_CLI.h”
void vCLITask(void *pvParameters) {
// 初始化 CLI
FreeRTOS_CLIRegisterCommand(xExampleCommand); // 注册自定义命令
char cInputBuffer[256];
char cOutputBuffer[256];
while (1) {
// 从串口读取输入(需实现底层读取函数)
if (read_uart(cInputBuffer, sizeof(cInputBuffer))) {
// 执行命令并获取输出
BaseType_t xMore = pdTRUE;
do {
xMore = FreeRTOS_CLIProcessCommand(cInputBuffer, cOutputBuffer, sizeof(cOutputBuffer));
send_uart(cOutputBuffer); // 发送输出到终端
} while (xMore == pdTRUE);
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
步骤 3:注册自定义命令
定义命令处理函数并注册:
static BaseType_t prvExampleCommand(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) {
// 解析参数(例如:example_cmd --param 123
)
const char *pcParam = FreeRTOS_CLIGetParameter(pcCommandString, 1); // 获取第一个参数
// 生成响应
snprintf(pcWriteBuffer, xWriteBufferLen, "Param: %s\r\n", pcParam);
return pdFALSE; // 无更多输出
}
// 命令结构体
static const CLI_Command_Definition_t xExampleCommand = {
“example_cmd”, // 命令名
“example_cmd [–param VALUE]: Example command\r\n”, // 帮助信息
prvExampleCommand, // 处理函数
1 // 参数数量(根据实际调整)
};
4. 常用内置命令
FreeRTOS-Plus-CLI 默认提供以下命令:
命令 功能
help 显示所有已注册命令
tasks 查看任务状态(名称、优先级等)
mem 显示堆内存使用情况
version 显示 FreeRTOS 版本
5. 示例:通过 CLI 控制 LED
static BaseType_t prvLEDCommand(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) {
const char *pcState = FreeRTOS_CLIGetParameter(pcCommandString, 1); // 获取参数(on/off)
if (strcmp(pcState, "on") == 0) {
GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
snprintf(pcWriteBuffer, xWriteBufferLen, "LED ON\r\n");
} else if (strcmp(pcState, "off") == 0) {
GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
snprintf(pcWriteBuffer, xWriteBufferLen, "LED OFF\r\n");
} else {
snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid command\r\n");
}
return pdFALSE;
}
// 注册命令
const CLI_Command_Definition_t xLEDCommand = {
“led”,
“led [on/off]: Control LED\r\n”,
prvLEDCommand,
1
};
6. 常见问题
问题 1:命令未生效
检查命令是否已注册(FreeRTOS_CLIRegisterCommand)。
确保输入命令格式正确(如参数数量匹配)。
问题 2:输出缓冲区溢出
增大 cOutputBuffer 的尺寸。
分多次返回输出(通过返回 pdTRUE 表示还有后续输出)。
问题 3:串口通信不稳定
增加输入缓冲区大小。
调整任务优先级,确保 CLI 任务及时响应。
通过 FreeRTOS-Plus-CLI,开发者可以快速构建交互式调试接口,显著提升嵌入式系统的可维护性。
命令行工具
命令行工具为移植的 FreeRTOS-Plus-CLI ,方便前期设备调试,问题排查等。
推荐使用 MobaXterm 串口工具。
串口输入 help 命令可以查看当前系统已经注册的命令:(输入后按回车执行命令,直接回车执行前一有效命令)
[图片]
例如:
heap 输出当前堆空间使用情况
osdr 0x410 2 读取校畸变芯片 0x410地址 长度2 即读0x410 0x411寄存器值
可以实现动态的控制系统变量和外设寄存器,不用频繁下载flash,在遇到BUG时可以读取外设状态等,根据自身负责模块可以自行定义实现命令行。
log打印采用 消息队列形式,打印接口仅格式化字符串,并发送消息给 log task,耗时短,对系统运行影响低,消息队列深度为5,消息buffer为512,可按格式自行添加打印,打印不过来时,消息队列满或streambuffer满,不影响其他任务运行。
LOG_INFO(MODULE_NAME,“task running:752 lock:%d error:%d ready:%d\r\n”,lock_state,error_state,ready_state);
禁止中断函数中打印 (有需求可自行修改,使用FromISR后缀的操作系统接口函数,但不推荐中断中打印)