/* Includes ----------------------------------------------------------------- */ #include "device/mrobot.h" #include "component/freertos_cli.h" #include "bsp/uart.h" #include #include #include #include /* Private variables -------------------------------------------------------- */ static MRobot_Device_t devices[MROBOT_MAX_DEVICES]; static uint8_t device_count = 0; static char current_path[64] = "/"; static char output_buffer[MROBOT_MAX_OUTPUT_LEN]; /* Private function prototypes ---------------------------------------------- */ static BaseType_t cmd_help(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString); static BaseType_t cmd_htop(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString); static BaseType_t cmd_cd(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString); static BaseType_t cmd_ls(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString); static BaseType_t cmd_show(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString); static BaseType_t cmd_pwd(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString); /* CLI 命令定义 */ static const CLI_Command_Definition_t cmd_def_help = { "help", "help: 显示所有可用命令\r\n", cmd_help, 0 }; static const CLI_Command_Definition_t cmd_def_htop = { "htop", "htop: 显示 FreeRTOS 任务状态信息\r\n", cmd_htop, 0 }; static const CLI_Command_Definition_t cmd_def_cd = { "cd", "cd : 切换目录\r\n", cmd_cd, 1 }; static const CLI_Command_Definition_t cmd_def_ls = { "ls", "ls: 列出当前目录内容\r\n", cmd_ls, 0 }; static const CLI_Command_Definition_t cmd_def_show = { "show", "show [device]: 显示设备信息\r\n", cmd_show, -1 /* 可变参数 */ }; static const CLI_Command_Definition_t cmd_def_pwd = { "pwd", "pwd: 显示当前目录\r\n", cmd_pwd, 0 }; /* Private functions -------------------------------------------------------- */ /* help 命令实现 */ static BaseType_t cmd_help(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) { (void)pcCommandString; snprintf(pcWriteBuffer, xWriteBufferLen, "MRobot CLI v1.0\r\n" "可用命令:\r\n" " help - 显示帮助信息\r\n" " htop - 显示任务状态\r\n" " cd - 切换目录\r\n" " ls - 列出目录内容\r\n" " pwd - 显示当前路径\r\n" " show - 显示设备信息\r\n" "\r\n"); return pdFALSE; } /* htop 命令实现 */ static BaseType_t cmd_htop(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) { (void)pcCommandString; static char task_buffer[512]; vTaskList(task_buffer); snprintf(pcWriteBuffer, xWriteBufferLen, "Task Name\tState\tPri\tStack\tNum\r\n" "-----------------------------------------------\r\n" "%s\r\n", task_buffer); return pdFALSE; } /* pwd 命令实现 */ static BaseType_t cmd_pwd(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) { (void)pcCommandString; snprintf(pcWriteBuffer, xWriteBufferLen, "%s\r\n", current_path); return pdFALSE; } /* cd 命令实现 */ static BaseType_t cmd_cd(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) { const char *param; BaseType_t param_len; param = FreeRTOS_CLIGetParameter(pcCommandString, 1, ¶m_len); if (param != NULL) { char path[64]; strncpy(path, param, param_len); path[param_len] = '\0'; if (strcmp(path, "/") == 0 || strcmp(path, "..") == 0) { strcpy(current_path, "/"); } else if (strcmp(path, "dev") == 0 || strcmp(path, "/dev") == 0) { strcpy(current_path, "/dev"); } else if (strcmp(path, "modules") == 0 || strcmp(path, "/modules") == 0) { strcpy(current_path, "/modules"); } else { snprintf(pcWriteBuffer, xWriteBufferLen, "错误: 目录不存在\r\n"); return pdFALSE; } snprintf(pcWriteBuffer, xWriteBufferLen, "切换到: %s\r\n", current_path); } else { snprintf(pcWriteBuffer, xWriteBufferLen, "错误: 缺少路径参数\r\n"); } return pdFALSE; } /* ls 命令实现 */ static BaseType_t cmd_ls(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) { (void)pcCommandString; int offset = 0; if (strcmp(current_path, "/") == 0) { offset = snprintf(pcWriteBuffer, xWriteBufferLen, "dev/\r\nmodules/\r\n"); } else if (strcmp(current_path, "/dev") == 0) { offset = snprintf(pcWriteBuffer, xWriteBufferLen, "设备列表:\r\n"); for (uint8_t i = 0; i < device_count && offset < (int)xWriteBufferLen; i++) { offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset, " %s\r\n", devices[i].name); } if (device_count == 0) { offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset, " (无设备)\r\n"); } } else if (strcmp(current_path, "/modules") == 0) { offset = snprintf(pcWriteBuffer, xWriteBufferLen, "(模块功能暂未实现)\r\n"); } return pdFALSE; } /* show 命令实现 */ static BaseType_t cmd_show(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) { const char *param; BaseType_t param_len; param = FreeRTOS_CLIGetParameter(pcCommandString, 1, ¶m_len); if (strcmp(current_path, "/dev") != 0) { snprintf(pcWriteBuffer, xWriteBufferLen, "错误: show 命令仅在 /dev 目录下可用\r\n"); return pdFALSE; } if (param == NULL) { /* 显示所有设备 */ int offset = snprintf(pcWriteBuffer, xWriteBufferLen, "所有设备信息:\r\n"); for (uint8_t i = 0; i < device_count && offset < (int)xWriteBufferLen; i++) { offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset, "\r\n=== %s ===\r\n", devices[i].name); if (devices[i].print_callback != NULL) { devices[i].print_callback(devices[i].data, pcWriteBuffer + offset, xWriteBufferLen - offset); offset = strlen(pcWriteBuffer); } } } else { /* 显示特定设备 */ char device_name[32]; strncpy(device_name, param, param_len); device_name[param_len] = '\0'; bool found = false; for (uint8_t i = 0; i < device_count; i++) { if (strcmp(devices[i].name, device_name) == 0) { found = true; int offset = snprintf(pcWriteBuffer, xWriteBufferLen, "=== %s ===\r\n", devices[i].name); if (devices[i].print_callback != NULL) { devices[i].print_callback(devices[i].data, pcWriteBuffer + offset, xWriteBufferLen - offset); } else { snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset, "无打印函数\r\n"); } break; } } if (!found) { snprintf(pcWriteBuffer, xWriteBufferLen, "错误: 设备 '%s' 未找到\r\n", device_name); } } return pdFALSE; } /* Exported functions ------------------------------------------------------- */ void MRobot_Init(void) { /* 初始化设备数组 */ memset(devices, 0, sizeof(devices)); device_count = 0; /* 注册 CLI 命令 */ FreeRTOS_CLIRegisterCommand(&cmd_def_help); FreeRTOS_CLIRegisterCommand(&cmd_def_htop); FreeRTOS_CLIRegisterCommand(&cmd_def_cd); FreeRTOS_CLIRegisterCommand(&cmd_def_ls); FreeRTOS_CLIRegisterCommand(&cmd_def_show); FreeRTOS_CLIRegisterCommand(&cmd_def_pwd); } int8_t MRobot_RegisterDevice(const char *name, MRobot_DeviceType_t type, void *data, MRobot_PrintCallback_t print_callback) { if (device_count >= MROBOT_MAX_DEVICES) { return -1; } if (name == NULL || data == NULL) { return -1; } strncpy(devices[device_count].name, name, sizeof(devices[device_count].name) - 1); devices[device_count].type = type; devices[device_count].data = data; devices[device_count].print_callback = print_callback; device_count++; return 0; } int8_t MRobot_ProcessCommand(const char *cmd_string, char *output_buffer, uint16_t buffer_size) { if (cmd_string == NULL || output_buffer == NULL || buffer_size == 0) { return -1; } BaseType_t result; int offset = 0; do { result = FreeRTOS_CLIProcessCommand(cmd_string, output_buffer + offset, buffer_size - offset); offset = strlen(output_buffer); } while (result != pdFALSE && offset < (int)buffer_size); return 0; } const char *MRobot_GetCurrentPath(void) { return current_path; }