本帖最后由 coslight 于 2020-11-26 13:06 编辑
移植letter-shell 3.0到CH32V103 1. 介绍Letter-shell 是一个开源项目,功能强大的嵌入式shell,遵循MIT开源许可协议。 Letter-shell 3.0是一个C语言编写的可以嵌入在程序中的嵌入式shell,可以通过串口命令行完成用户函数的调用、运行。 目前支持的功能有: l 命令自动补全 l 快捷键功能定义 l 命令权限管理 l 用户管理 l 变量支持 l 代理函数和参数代理解析 源代码获取地址:https://github.com/NevermindZZT/letter-shell 2. 移植过程针对不同的处理器需要做如下移植过程。 Shell shell; 2. 移植shell读,写函数,函数原型如下 /** * * @param char shell读取的字符 * */ typedef signed char (*shellRead)(char *);
/** * * @param const char 需写的字符 */ typedef void (*shellWrite)(const char); 移植支持函数: /** * * @param data 数据 */ void userShellWrite(chardata) { // serialTransmit(&debugSerial, (uint8_t*)&data, 1, 0xFF); while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); USART_SendData(USART1, (uint16_t)data);
}
/** * @brief 用户shell读 * * @param data 数据 */ signed char userShellRead(char*data) { if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == RESET) return -1; *data = (char)USART_ReceiveData(USART1); return 0; } 3. 申请一片缓冲区 char shellBuffer[512]; 4. 调用shellInit进行初始化 /** *@brief 用户shell初始化 * */ void userShellInit(void) { shell.write = userShellWrite; shell.read = userShellRead; shellInit(&shell,shellBuffer, 512); } 5. 调用(建立)shell任务 对于运行在操作系统的情况,建立shellTask任务(确保sell_cfg.h中的配置无误),任务参数为shell对象 OsTaskCreate(shellTask, &shell, ...); 对于裸机环境,在主循环中调用shellTask(),或者在接收到数据时,调用shellHandler() 6. 说明 对于中断方式使用shell,不用定义shell->read,但需要在中断中调用shellHandler 对于使用操作系统的情况,使能SHEHLL_TASK_WHILE宏,然后创建shellTask任务 7. 其他配置 定义宏SHELL_GET_TICK()为获取系统tick函数,使能tab双击操作,用户长帮助补全 /** * @brief 获取系统时间(ms) * 定义此宏为获取系统Tick,如`HAL_GetTick()` * @NOTE 此宏不定义时无法使用双击tab补全命令help,无法使用shell超时锁定 */ #define SHELL_GET_TICK() SysTick_GetCount() 8. 配置宏 shell_cfg.h文件中包含了所有用于配置shell的宏,在使用前,需要根据需要进行配置 宏 | | | | | | | | | | | | | | | | | | | | | | | | | | SHELL_PARAMETER_MAX_NUMBER | | | | | | | | | | | | | | | | | | | | SHELL_DEFAULT_USER_PASSWORD | | | |
8. RISC-V命令导出方式
在.ld 文件中增加
.shell : { _shell_command_start =.; KEEP (*(shellCommand)) _shell_command_end = .; } >FLASH AT>FLASH 3. 使用方法
3.1. 函数创建和调用方式创建可管理用户函数方法: int func(intargc, char *argv[]) { printf("%dparameter(s)\r\n", argc); for (char i =1; i < argc; i++) { printf("%s\r\n",argv); } } 导出定义方式: SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),func, func, test); 调用方式: letter:/$ func "hello world"
3.2. 变量创建和调用方式导出变量: 变量导出使用SHELL_EXPORT_VAR宏,支持整形(char,short, int),字符串,指针以及节点变量,变量导出需要使用引用的方式,如果不允许对变量进行修改,在属性中添加SHELL_CMD_READ_ONLY int varInt = 0;
SHELL_EXPORT_VAR(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_VAR_INT), varInt, &varInt, test);
char str[] = "test string";
SHELL_EXPORT_VAR(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_VAR_STRING), varStr, str, test);
Log log;
SHELL_EXPORT_VAR(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_VAR_POINT), log, &log, test);
查看变量: 在命令行直接输入导出的变量名即可查看变量当前的值 letter:/$ varIntvarInt = 0, 0x00000000
letter:/$ varStrvarStr = "test string"修改变量: 使用setVar命令修改变量的值,对于字符串型变量,请确认字符串有分配足够的空间,指针类型的变量不可修改 letter:/$ setVar varInt 45678
varInt = 45678, 0x0000b26e
letter:/$ setVar varStr "hello"
varStr = "hello"使用变量: letter shell 3.0的变量可以在命令中作为参数传递,对于需要传递结构体引用到命令中的场景特别适用,使用$+变量名的方式传递 letter:/$ shellPrint $shell "hello world\r\n"hello world
4. 效果验证系统启动效果 按tab按键 输入help命令 输入自定义函数func的执行效果:
|