【GD32E503评测】+Letter-shell移植到gd32e503v
[复制链接]
移植Letter-shell
Letter-shell 是一个开源项目,功能强大的嵌入式shell,遵循MIT开源许可协议。
Letter-shell 3.0是一个C语言编写的可以嵌入在程序中的嵌入式shell,可以通过串口命令行完成用户函数的调用、运行。
目前支持的功能有:
- 命令自动补全
- 快捷键功能定义
- 命令权限管理
- 用户管理
- 变量支持
- 代理函数和参数代理解析
源代码获取地址:
基于tos的shell移植
前面我们成功的移植了tos到GD32E503V上,下面基于任务级别的shell移植。
- 串口驱动
官方例程中已经做了串口的初始化部分,这里不详细描述。为了更好的移植shell,我们需要增加串口输出的处理。
void uart_output(char dat)
{
usart_data_transmit(EVAL_COM0, (uint8_t)dat);
while(RESET == usart_flag_get(EVAL_COM0, USART_FLAG_TBE));
}
- Shell_port.c文件中关键函数的移植
为了让shell成功的运行起来,不许完成shell_port.c中如下几个关键函数的移植工作,包括, userShellWrite,userShellRead。
/**
* @brief 用户shell写
*
* @param data 数据
*/
void userShellWrite(char data)
{
// serialTransmit(&debugSerial, (uint8_t *)&data, 1, 0xFF);
uart_output(data);
}
/**
* @brief 用户shell读
*
* @param data 数据
* @return char 状态
*/
signed char userShellRead(char *data)
{
return 0;
}
/**
* @brief 用户shell初始化
*
*/
void userShellInit(void)
{
shell.write = userShellWrite;
// shell.read = userShellRead;
shellInit(&shell, shellBuffer, 512);
}
可见,userShellRead函数我们没有处理,那么shell是如何获取到串口输入数据的呢?
因为shell提供了一个可以在中断级调用的处理接口,可以直接获取串口数据进入shell的处理流程中。
我们只需要在串口的接收中断函数中调用如下函数:
shellHandler(&shell, rx);
- 创建shell的任务
官方网站中如下介绍,对于运行在操作系统的情况,建立shellTask任务(确保sell_cfg.h中的配置无误),任务参数为shell对象
OsTaskCreate(shellTask, &shell, ...);
对于裸机环境,在主循环中调用shellTask,或者在接收到数据时,调用shellHandler
我们利用tos的任务方式建立了shellTask任务。
#define SHELL_TASK_STK_SIZE 2048
extern void shell_task_entry(void *arg);
osThreadDef(shell_task_entry, osPriorityBelowNormal, 1, SHELL_TASK_STK_SIZE);
//shell处理任务
void shell_task_entry(void *arg)
{
userShellInit();
while(1)
{
tos_task_delay(10);
shellTask(&shell);
}
}
- 其它配置
定义宏SHELL_GET_TICK()为获取系统tick函数,使能tab双击操作,用户长帮助补全
/**
* @brief 获取系统时间(ms)
* 定义此宏为获取系统Tick,如`HAL_GetTick()`
* @NOTE 此宏不定义时无法使用双击tab补全命令help,无法使用shell超时锁定
*/
#define SHELL_GET_TICK() SysTick_GetCount()
Shell的任务创建方式
函数创建和调用方式
创建可管理用户函数方法:
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"
变量创建和调用方式
导出变量:
变量导出使用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
移植效果展示
|