目录
概述
1 RT-Thread Nano
1.1 Nano版本介绍
1.2 RT-Thread Nano的特点
2 STM32Cube 创建工程
2.1 STM32Cub配置板卡参数
2.2 项目程序架构
3 移植RT-Thread
3.1 Keil IDE加载RT-Thread
3.2 解决上面两个ERROR
3.2.1 ERROR-1:
3.2.2 ERROR-2
3.3 移植FINSH
3.4 添加OSTick
4 测试
4.1 线程测试
4.2 控制台验证
源代码下载地址:
RT-ThreadNano版本在STM32F103RB上的快速移植资源-CSDN文库
概述
本文主要介绍RT-Thread Nano版本在NUCLEO-F13RB上的移植方法,包括RT-Thread的版本信息,各个版本的差异,Keil下RT-Thread的安装,以及结合STM32Cube创建工程的方法。文中还详细记录了修改代码的内容和修改方法。还编写具体的案例验证代码,验证RT-Thread的功能。
1 RT-Thread Nano
1.1 Nano版本介绍
RT-Thread Nano 是一个极简版的硬实时内核,它是由 C 语言开发,采用面向对象的编程思维,具有良好的代码风格,是一款可裁剪的、抢占式实时多任务的 RTOS。其内存资源占用极小,功能包括任务处理、软件定时器、信号量、邮箱和实时调度等相对完整的实时操作系统特性。适用32 位 ARM 入门级 MCU 。
下图是 RT-Thread Nano 的软件框图,包含支持的 CPU 架构与内核源码,还有可拆卸的 FinSH 组件:
1.2 RT-Thread Nano的特点
RT-Thread Nano 在使用上也非常简单,带给开发者友好的开发体验。
- 易裁剪:Nano 的配置文件为 rtconfig.h,该文件中列出了内核中的所有宏定义,有些默认没有打开,如需使用,打开即可。具体的配置可见 Nano 版块的 RT-Thread Nano 配置 教程。
- 易添加 FinSH 组件:FinSH 组件 可以很方便的在 Nano 上进行移植,而不再依赖 device 框架,只需要对接两个必要的函数即可完成 FinSH 移植。
- 自选驱动库:可以使用厂商提供的固件驱动库,如 ST 的 STD 库、HAL 库、LL 库等,可以自行选择。
- 完善的文档:包含 内核基础、线程管理 (例程)、时钟管理 (例程)、线程间同步 (例程)、线程间通信 (例程)、内存管理 (例程)、中断管理,以及 Nano 版块的移植教程。
2 STM32Cube 创建工程
2.1 STM32Cub配置板卡参数
step -1: 选择板卡
打开STM32Cube,在board选项面板搜索NUCLEO-F103RB,点击板卡Item配置项目参数
step -2: 配置参数
点击板卡后,STM32Cube会自动配置板卡上外围资源。
step -3: 禁止如下两项配置
step -4: 配置项目相关参数
2.2 项目程序架构
完成项目参数配置后,就可以生成代码,生成代码框架结构如下:
3 移植RT-Thread
3.1 Keil IDE加载RT-Thread
在Keil IDE上,依照如下步骤添加RT-Thread的源代码包。
配置完成后,IDE会自动加载RT-Thread的源代码包
初次编译代码,会出现如下错误信息:
详细log如下:
RTE/RTOS/board.c(47): error: #35: #error directive: "TODO 1: OS Tick Configuration."
#error "TODO 1: OS Tick Configuration."
RTE/RTOS/board.c: 0 warnings, 1 error
compiling thread.c...
compiling timer.c...
compiling finsh_port.c...
RTE/RTOS/finsh_port.c(14): error: #35: #error directive: Please uncomment the line <#include "finsh_config.h"> in the rtconfig.h
#error Please uncomment the line <#include "finsh_config.h"> in the rtconfig.h
RTE/RTOS/finsh_port.c: 0 warnings, 1 error
compiling gpio.c...
3.2 解决上面两个ERROR
3.2.1 ERROR-1:
RTE/RTOS/board.c(47): error: #35: #error directive: "TODO 1: OS Tick Configuration."
#error "TODO 1: OS Tick Configuration."
RTE/RTOS/board.c: 0 warnings, 1 error
这里提示,需要配置OS TICK
配置代码如下:
源代码
/**
* This function will initial your board.
*/
void rt_hw_board_init(void)
{
//#error "TODO 1: OS Tick Configuration."
/* 1、系统、时钟初始化 */
HAL_Init(); // 初始化 HAL 库
SystemClock_Config(); // 配置系统时钟
/* 2、OS Tick 频率配置,RT_TICK_PER_SECOND = 1000 表示 1ms 触发一次中断 */
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
/*
* TODO 1: OS Tick Configuration
* Enable the hardware timer and call the rt_os_tick_callback function
* periodically with the frequency RT_TICK_PER_SECOND.
*/
/* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}
3.2.2 ERROR-2
RTE/RTOS/finsh_port.c(14): error: #35: #error directive: Please uncomment the line <#include "finsh_config.h"> in the rtconfig.h
#error Please uncomment the line <#include "finsh_config.h"> in the rtconfig.h
错误位置如下:
修改方法:
step-1: 使能 "finsh_config.h"
step-2: 添加源代码
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rthw.h>
#include <rtconfig.h>
#include "usart.h"
#ifndef RT_USING_FINSH
#error Please uncomment the line <#include "finsh_config.h"> in the rtconfig.h
#endif
#ifdef RT_USING_FINSH
RT_WEAK char rt_hw_console_getchar(void)
{
/* Note: the initial value of ch must < 0 */
int ch = -1;
//#error "TODO 4: Read a char from the uart and assign it to 'ch'."
if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE) != RESET)
{
ch = huart2.Instance->DR & 0xff;
}
else
{
if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_ORE) != RESET)
{
__HAL_UART_CLEAR_OREFLAG(&huart2);
}
rt_thread_mdelay(10);
}
return ch;
}
#endif /* RT_USING_FINSH */
3.3 移植FINSH
step -1: 控制台接口
step -2: 添加接口函数
源代码
#ifdef RT_USING_CONSOLE
static int uart_init(void)
{
//#error "TODO 2: Enable the hardware uart and config baudrate."
MX_USART2_UART_Init();
return 0;
}
INIT_BOARD_EXPORT(uart_init);
void rt_hw_console_output(const char *str)
{
//#error "TODO 3: Output the string 'str' through the uart."
rt_size_t i = 0, size = 0;
char a = '\r';
__HAL_UNLOCK(&huart2);
size = rt_strlen(str);
for (i = 0; i < size; i++)
{
if (*(str + i) == '\n')
{
HAL_UART_Transmit(&huart2, (uint8_t *)&a, 1, 1000);
}
HAL_UART_Transmit(&huart2, (uint8_t *)(str + i), 1, 1000);
}
}
#endif
3.4 添加OSTick
在stm32f1xx_it.c文件中调用rt_os_tick_callback
源代码
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
rt_os_tick_callback();
/* USER CODE END SysTick_IRQn 1 */
}
4 测试
4.1 线程测试
RT-Thread默认会调用main()线程,在main()函数中添加一个断点验证其是否能进入
4.2 控制台验证
复位MCU,系统能正常打印log, 输入help命令后,MCU也能正常的响应该命令。说明系统已经移植成功。