RT-Thread 命令行组件 Finsh 教程
在本教程中,我们将介绍如何在 RT-Thread 中使用命令行组件 Finsh。通过 Finsh,可以方便地在设备上进行调试和操作。
1. 实现控制台/串口输出函数
首先,在基于 CubeMX 生成的工程中,实现控制台/串口输出函数 rt_hw_console_output(const char *str)
。这个函数通常放在 usart.c
文件中,使用 HAL 库实现:
void rt_hw_console_output(const char *str)
{
/* 使用 HAL 库将字符串输出到串口 */
rt_size_t i = 0, size = 0;
char a = '\r';
__HAL_UNLOCK(&huart1);
size = rt_strlen(str);
for (i = 0; i < size; i++)
{
if (*(str + i) == '\n')
{
HAL_UART_Transmit(&huart1, (uint8_t *)&a, 1, 1);
}
HAL_UART_Transmit(&huart1, (uint8_t *)(str + i), 1, 1);
}
}
2. 验证 rt_kprintf
接口输出调试信息
在工程中使用 RT-Thread 提供的 rt_kprintf
接口输出调试信息,验证 rt_hw_console_output
函数是否正常工作:
rt_kprintf("testCount: %d", testCount++);
3. 开启 Finsh 组件
在工程配置中添加宏定义 RTE_USING_FINSH
,以启用 Finsh 组件:
4. 实现 Finsh 组件接受指令的函数
实现 rt_hw_console_getchar(void)
函数,用于从控制台获取输入字符:
char rt_hw_console_getchar(void)
{
int ch = -1;
/* 通过 HAL 库从串口接收一个字符 */
if (HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET)
{
ch = huart1.Instance->DR & 0xff;
}
else
{
if (HAL_UART_GET_FLAG(&huart1, UART_FLAG_ORE) != RESET)
{
__HAL_UART_CLEAR_OREFLAG(&huart1);
}
rt_thread_mdelay(10);
}
return ch;
}
5. 解决编译错误
在编译时,如果遇到找不到 finsh_api.h
头文件的错误,添加 components/finsh
目录到头文件路径:
6. 编译并烧写
编译工程并烧写到设备,确保没有编译错误。烧写成功后,控制台应显示 msh>
提示符,表示 Finsh 正在等待输入。
7. 测试 Finsh 命令
在控制台输入 help
,验证 Finsh 是否正常工作。应看到 Finsh 输出可用命令的帮助信息:
msh> help
8. 添加自定义线程命令
为 Finsh 添加一个自定义的线程创建命令 TaskInit
。在项目中定义一个新的线程创建函数,并将其注册到 Finsh 中:
9. 通过 Finsh 启动线程
在控制台输入自定义命令 TaskInit
,启动新创建的线程:
10. 使用自动初始化宏
RT-Thread 提供了多种自动初始化宏,用于不同阶段的初始化。这些宏包括:
INIT_BOARD_EXPORT
:板级自动初始化INIT_PREV_EXPORT
:组件自动预初始化INIT_DEVICE_EXPORT
:设备相关自动初始化INIT_COMPONENT_EXPORT
:组件自动初始化INIT_APP_EXPORT
:应用层自动初始化
例如,将自定义的 TaskCreate 函数设置为自动初始化:
对应的 demo 源码, 请点击 RtosExPro at rtt_finsh
也可扫码关注博主同名公众号"不解之榬",回复 “RT-Thread” 获取
注:
如果遇到函数声明类型不匹配的警告
解决方案是将函数返回值由 void
修改为 int
,并确保函数内按实际情况返回一个值。
参考链接:
移植控制台/FinSH