273 lines
9.3 KiB
C
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, ¶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;
|
|
}
|