This commit is contained in:
Robofish 2026-02-04 12:43:11 +08:00
parent 5f624a51b9
commit 8712efa6f2
2 changed files with 80 additions and 10 deletions

View File

@ -11,12 +11,28 @@
#include <task.h> #include <task.h>
#include <cmsis_os2.h> #include <cmsis_os2.h>
/* Private constants -------------------------------------------------------- */
static const char *const CLI_WELCOME_MESSAGE =
"\r\n"
" ______ __ _______ __ \r\n"
" | __ \\.-----.| |--.-----.| | |.---.-.-----.| |-.-----.-----.\r\n"
" | <| _ || _ | _ || || _ |__ --|| _| -__| _|\r\n"
" |___|__||_____||_____|_____||__|_|__||___._|_____||____|_____|__| \r\n"
" -------------------------------------------------------------------\r\n"
" FreeRTOS CLI. Type 'help' to view a list of registered commands. \r\n"
"\r\n";
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
static MRobot_Device_t devices[MROBOT_MAX_DEVICES]; static MRobot_Device_t devices[MROBOT_MAX_DEVICES];
static uint8_t device_count = 0; static uint8_t device_count = 0;
static char current_path[64] = "/"; static char current_path[64] = "/";
static char output_buffer[MROBOT_MAX_OUTPUT_LEN]; static char output_buffer[MROBOT_MAX_OUTPUT_LEN];
/* 自定义命令存储最多16个 */
#define MROBOT_MAX_CUSTOM_COMMANDS 16
static CLI_Command_Definition_t *custom_commands[MROBOT_MAX_CUSTOM_COMMANDS];
static uint8_t custom_command_count = 0;
/* UART 相关变量 */ /* UART 相关变量 */
static uint8_t uart_rx_char; static uint8_t uart_rx_char;
static uint8_t cmd_buffer[128]; static uint8_t cmd_buffer[128];
@ -295,7 +311,7 @@ static BaseType_t cmd_show(char *pcWriteBuffer, size_t xWriteBufferLen, const ch
/* 显示所有设备 */ /* 显示所有设备 */
if (print_count > 1) { if (print_count > 1) {
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset, offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
"[第 %u/%u 次]\r\n", current_iteration + 1, print_count); "[第 %lu/%lu 次]\r\n", (unsigned long)(current_iteration + 1), (unsigned long)print_count);
} }
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset, "所有设备信息:\r\n"); offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset, "所有设备信息:\r\n");
for (uint8_t i = 0; i < device_count && offset < (int)xWriteBufferLen; i++) { for (uint8_t i = 0; i < device_count && offset < (int)xWriteBufferLen; i++) {
@ -317,8 +333,8 @@ static BaseType_t cmd_show(char *pcWriteBuffer, size_t xWriteBufferLen, const ch
int offset = 0; int offset = 0;
if (print_count > 1) { if (print_count > 1) {
offset = snprintf(pcWriteBuffer, xWriteBufferLen, offset = snprintf(pcWriteBuffer, xWriteBufferLen,
"[第 %u/%u 次] === %s ===\r\n", "[第 %lu/%lu 次] === %s ===\r\n",
current_iteration + 1, print_count, devices[i].name); (unsigned long)(current_iteration + 1), (unsigned long)print_count, devices[i].name);
} else { } else {
offset = snprintf(pcWriteBuffer, xWriteBufferLen, offset = snprintf(pcWriteBuffer, xWriteBufferLen,
"=== %s ===\r\n", devices[i].name); "=== %s ===\r\n", devices[i].name);
@ -419,15 +435,24 @@ void MRobot_Init(void) {
/* 启动 UART 接收 */ /* 启动 UART 接收 */
BSP_UART_Receive(BSP_UART_VOFA, &uart_rx_char, 1, false); BSP_UART_Receive(BSP_UART_VOFA, &uart_rx_char, 1, false);
/* 等待用户按下回车键再显示欢迎消息 */
volatile bool enter_pressed = false;
while (!enter_pressed) {
if (uart_rx_char == '\r' || uart_rx_char == '\n') {
enter_pressed = true;
}
osDelay(10);
}
/* 发送欢迎消息 */ /* 发送欢迎消息 */
const char *welcome = "\r\n\r\n"
"================================\r\n"
" MRobot CLI v1.0\r\n"
" 输入 'help' 获取帮助\r\n"
"================================\r\n"
"root@mrobot:~$ ";
tx_complete = false; tx_complete = false;
BSP_UART_Transmit(BSP_UART_VOFA, (uint8_t *)welcome, strlen(welcome), true); BSP_UART_Transmit(BSP_UART_VOFA, (uint8_t *)CLI_WELCOME_MESSAGE, strlen(CLI_WELCOME_MESSAGE), true);
while (!tx_complete) { osDelay(1); } /* 等待发送完成 */
/* 发送提示符 */
const char *prompt = "root@mrobot:~$ ";
tx_complete = false;
BSP_UART_Transmit(BSP_UART_VOFA, (uint8_t *)prompt, strlen(prompt), true);
while (!tx_complete) { osDelay(1); } /* 等待发送完成 */ while (!tx_complete) { osDelay(1); } /* 等待发送完成 */
} }
@ -458,6 +483,37 @@ int8_t MRobot_RegisterMotor(const char *name, void *motor) {
return MRobot_RegisterDevice(name, MROBOT_DEVICE_TYPE_MOTOR, motor, mrobot_print_motor); return MRobot_RegisterDevice(name, MROBOT_DEVICE_TYPE_MOTOR, motor, mrobot_print_motor);
} }
int8_t MRobot_RegisterCommand(const char *command, const char *help_text,
MRobot_CommandCallback_t callback, int8_t param_count) {
if (custom_command_count >= MROBOT_MAX_CUSTOM_COMMANDS) {
return -1; /* 命令数量已达上限 */
}
if (command == NULL || help_text == NULL || callback == NULL) {
return -1; /* 参数无效 */
}
/* 动态分配命令定义结构体 */
CLI_Command_Definition_t *cmd_def = (CLI_Command_Definition_t *)pvPortMalloc(sizeof(CLI_Command_Definition_t));
if (cmd_def == NULL) {
return -1; /* 内存分配失败 */
}
/* 强制转换以移除 const 限制(仅用于初始化) */
*(const char **)&cmd_def->pcCommand = command;
*(const char **)&cmd_def->pcHelpString = help_text;
*(pdCOMMAND_LINE_CALLBACK *)&cmd_def->pxCommandInterpreter = (pdCOMMAND_LINE_CALLBACK)callback;
cmd_def->cExpectedNumberOfParameters = param_count;
/* 注册到 FreeRTOS CLI */
FreeRTOS_CLIRegisterCommand(cmd_def);
/* 保存指针以便后续可能的清理(虽然一般不需要) */
custom_commands[custom_command_count] = cmd_def;
custom_command_count++;
return 0;
}
void MRobot_Run(void) { void MRobot_Run(void) {
/* 动态 htop 模式 */ /* 动态 htop 模式 */
if (htop_mode) { if (htop_mode) {

View File

@ -51,6 +51,9 @@ typedef enum {
/* 设备打印回调函数类型 */ /* 设备打印回调函数类型 */
typedef void (*MRobot_PrintCallback_t)(void *device_data, char *buffer, uint16_t buffer_size); typedef void (*MRobot_PrintCallback_t)(void *device_data, char *buffer, uint16_t buffer_size);
/* 命令处理回调函数类型(与 pdCOMMAND_LINE_CALLBACK 相同) */
typedef long (*MRobot_CommandCallback_t)(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
/* 注册的设备结构 */ /* 注册的设备结构 */
typedef struct { typedef struct {
char name[32]; char name[32];
@ -116,6 +119,17 @@ int8_t MRobot_RegisterIMU(const char *name, void *imu_device);
*/ */
int8_t MRobot_RegisterMotor(const char *name, void *motor); int8_t MRobot_RegisterMotor(const char *name, void *motor);
/**
* @brief MRobot CLI
* @param command "test"
* @param help_text "test: 测试命令\r\n"
* @param callback
* @param param_count 0=-1=
* @retval 0 , -1
*/
int8_t MRobot_RegisterCommand(const char *command, const char *help_text,
MRobot_CommandCallback_t callback, int8_t param_count);
/** /**
* @brief MRobot CLI * @brief MRobot CLI
*/ */