rm_balance/User/device/mrobot.c
2026-02-04 03:38:04 +08:00

273 lines
9.3 KiB
C

/* Includes ----------------------------------------------------------------- */
#include "device/mrobot.h"
#include "component/freertos_cli.h"
#include "bsp/uart.h"
#include <string.h>
#include <stdio.h>
#include <FreeRTOS.h>
#include <task.h>
/* 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 <path>: 切换目录\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, &param_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, &param_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;
}