码云地址
/**
* @brief 是否使用默认shell任务while循环,使能宏`SHELL_USING_TASK`后此宏有意义
* 使能此宏,则`shellTask()`函数会一直循环读取输入,一般使用操作系统建立shell
* 任务时使能此宏,关闭此宏的情况下,一般适用于无操作系统,在主循环中调用`shellTask()`
*/
#define SHELL_TASK_WHILE 1
SHELL_TASK_WHILE: 设置为1,在初始化调用一次 shellTask
函数即可。在函数内自动循环。
其他配置宏,具体查看shell_cfg.h
文件即可。
创建 shell_port.c
和 shell_port.h
文件,编写初始化函数和读写函数。
(1) 创建全局 shell 变量,注册当前shell用户信息。创建全局buffer区,用于存放接受到的字符信息。
Shell shell;
char shellBuffer[512];
(2) 编写写字符函数
/**
* @brief 用户shell写
*
* @param data 数据
*/
void userShellWrite(char data)
{
USARTX_SendChar(SHELL_UART, data);
}
使用STM32的库函数,直接将字符输出。
(3) 编写读字符函数
/**
* @brief 用户shell读
*
* @param data 数据
* @return char 状态
*/
signed char userShellRead(char *data)
{
*data = 0;
if (USART_GetITStatus(SHELL_UART, USART_IT_RXNE) != RESET) {
*data = USART_ReceiveData(SHELL_UART);
}
USART_ClearFlag(SHELL_UART, USART_FLAG_RXNE);
if (*data == 0) {
return -1;
}
return 0;
}
需要清除标志位。
正常接受字符,则返回0, 异常接受字符,则返回-1.
注: 在shellTask中,会循环调用 shell.read函数,即我们自己编写的读字符函数。会根据函数返回值判断是否执行句柄函数。
if (shell->read && shell->read(&data) == 0)
{
shellHandler(shell, data);
}
--------分割线--------
第二种方法,则是创建串口中断的回调函数,回调函数绑定为shellHandler
,在串口中断中,只要获取一个字符,则会执行shellHandler
函数,此方法不用一直调用 shellTask
函数。
USARTX_CreateDefaultUsart(&UART);
USART1_DefaultInit(&UART, 115200);
UART.CallbackFunc = readReceive;
USARTX_Init(&UART);
最后,整个shell的初始化函数如下:
void userShellInit(void)
{
// 初始化串口,并设置回调函数
USARTX_CreateDefaultUsart(&UART);
USART1_DefaultInit(&UART, 115200);
UART.CallbackFunc = readReceive;
USARTX_Init(&UART);
// 绑定读写字符函数
shell.write = userShellWrite;
shell.read = userShellRead;
shellInit(&shell, shellBuffer, 512);
}