
一、Letter shell介绍Letter shell是一个用 C 语言编写的、专为嵌入式系统设计的开源命令行交互工具嵌入式Shell可以让你通过串口等通道像操作Linux终端一样调用和运行程序中的函数。官方源码https://github.com/NevermindZZT/letter-shell二、Letter shell移植新建shell_port.c和shell_port.h文件名可以随意起。定义Shell对象、初始化和配置读写回调函数Shell shell;//定义一个shell对象 static char shellBuffer[1024]; //shell写函数接口 static signed short shellPortWrite(char *data, unsigned short len) { BSP_UART_Send((uint8_t *)data, (uint16_t)len); return (signed short)len; } //shell读函数接口 static signed short shellPortRead(char *data, unsigned short len) { uint32_t rxLen; do { rxLen BSP_UART_Read((uint8_t *)data, len); if (rxLen 0) { osDelay(1); } } while (rxLen 0); return (signed short)rxLen; } void LetterShellInit(void) { shell.write shellPortWrite; shell.read shellPortRead; shellInit(shell, shellBuffer, sizeof(shellBuffer)); //创建Letter shell任务 osThreadDef(shellTaskDef, StartShellTask, osPriorityNormal, 0, 512); osThreadCreate(osThread(shellTaskDef), NULL); } void StartShellTask(void const *argument) { shellTask(shell); }使用RTOS可将SHELL_TASK_WHILE配置为1裸机配置为0主循环定时调用。Letter shell将配置的指令放到了shellCommand段里Keil MDK需要在链接器的“Misc controls”中添加--keep shellCommand*。GCC需要在链接脚本添加_shell_command_start .; KEEP (*(shellCommand)) _shell_command_end .;宏配置宏意义SHELL_TASK_WHILE是否使用默认shell任务while循环SHELL_USING_CMD_EXPORT是否使用命令导出方式SHELL_USING_COMPANION是否使用shell伴生对象功能SHELL_SUPPORT_END_LINE是否支持shell尾行模式SHELL_HELP_LIST_USER是否在输入命令列表中列出用户SHELL_HELP_LIST_VAR是否在输入命令列表中列出变量SHELL_HELP_LIST_KEY是否在输入命令列表中列出按键SHELL_ENTER_LF使用LF作为命令行回车触发SHELL_ENTER_CR使用CR作为命令行回车触发SHELL_ENTER_CRLF使用CRLF作为命令行回车触发SHELL_EXEC_UNDEF_FUNC使用执行未导出函数的功能SHELL_COMMAND_MAX_LENGTHshell命令最大长度SHELL_PARAMETER_MAX_NUMBERshell命令参数最大数量SHELL_HISTORY_MAX_NUMBER历史命令记录数量SHELL_DOUBLE_CLICK_TIME双击间隔(ms)SHELL_QUICK_HELP快速帮助SHELL_MAX_NUMBER管理的最大shell数量SHELL_GET_TICK()获取系统时间(ms)SHELL_USING_LOCK是否使用锁SHELL_MALLOC(size)内存分配函数(shell本身不需要)SHELL_FREE(obj)内存释放函数(shell本身不需要)SHELL_SHOW_INFO是否显示shell信息SHELL_CLS_WHEN_LOGIN是否在登录后清除命令行SHELL_DEFAULT_USERshell默认用户SHELL_DEFAULT_USER_PASSWORD默认用户密码SHELL_LOCK_TIMEOUTshell自动锁定超时SHELL_USING_FUNC_SIGNATURE使用函数签名SHELL_SUPPORT_ARRAY_PARAM支持数组参数三、Letter shell使用方式一、多参数形式/** *多参数测试 */ static int shellArgTest(int argc, char *argv[]) { Shell *current shellGetCurrent(); shellPrint(shellGetCurrent(), argc:%d\r\n, argc); for (int i 0;i argc;i) { shellPrint(shellGetCurrent(), argv[%d]:%s\r\n, i, argv[i]); } } SHELL_EXPORT_CMD( SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_DISABLE_RETURN, arg, shellArgTest, shell Arg Test );/** * brief LED 控制命令 — 模拟硬件控制场景 * note 示例: led on / led off / led toggle * 命令通常用于调试和手动控制外设 */ static int shellLed(int argc, char *argv[]) { if (argc 2) { shellPrint(shellGetCurrent(), Usage: led on|off|toggle\r\n); return -1; } if (strcmp(argv[1], on) 0) { shellPrint(shellGetCurrent(), LED turned ON\r\n); /* 实际项目中调用 HAL_GPIO_WritePin(...) 控制 GPIO */ } else if (strcmp(argv[1], off) 0) { shellPrint(shellGetCurrent(), LED turned OFF\r\n); } else if (strcmp(argv[1], toggle) 0) { shellPrint(shellGetCurrent(), LED toggled\r\n); } else { shellPrint(shellGetCurrent(), Unknown option: %s\r\n, argv[1]); return -1; } return 0; } SHELL_EXPORT_CMD( SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_DISABLE_RETURN, led, shellLed, control LED\r\nled on|off|toggle );