实验环境
工具:STM32CubeMX,IAR
芯片:STM32F407ZGT6
一、RT-Thread概述
RT-Thread 是一款完全由国内团队开发维护的嵌入式实时操作系统(RTOS)。
RT-Thread,全称是Real Time-Thread,顾名思义,它是一个嵌入式实时多线程操作系统, 基本属性之一是支持多任务,允许多个任务同时运行并不意味着处理器在同一时刻真地执行了多个任务。 事实上,一个处理器核心在某一时刻只能运行一个任务,由于每次对一个任务的执行时间很短、 任务与任务之间通过任务调度器进行非常快速地切换(调度器根据优先级决定此刻该执行的任务), 给人造成多个任务在一个时刻同时运行的错觉。在 RT-Thread 系统中,任务通过线程实现的, RT-Thread 中的线程调度器也就是以上提到的任务调度器。
二、CubeMX 安装 Nano Pack
这里我们可以参考官方的教程:基于 CubeMX 移植 RT-Thread Nano
要获取 RT-Thread Nano 软件包,需要在 CubeMX 中添加
https://www.rt-thread.org/download/cube/RealThread.RT-Thread.pdsc
这里我们需要使用在 CubeMX 中添加硬件包同样的方式来添加我们要使用的 RT-Thread Nano 软件包,过程如下:
- 打开 CubeMX,从菜单栏
help
进入Manage embedded software packages
界面,点击From Url
按钮,进入User Defined Packs Manager
界面,其次点击new
,填入上述网址,然后点击check
,如下图所示:
2.check
通过后,点击OK
回到User Defined Packs Manager
界面,再次点击OK
,CubeMX 自动连接服务器,获取包描述文件。回到Manage embedded software packages
界面,就会发现RT-Thread Nano 3.1.5
软件包,选择该软件包,点击Install
,如下图所示:
3. 点击安装之后,弹出Licensing Agreement
,同意协议,点击Finish
,如下图所示:
4. 待安装完成,成功安装后,版本前面的小蓝色框变成填充的绿色,现象如下图所示:
至此,RT-Thread Nano 软件包安装完毕,退出Manage embedded software packages
界面,进入 CubeMX 主界面。
三、基础工程配置
通过STM32CubeMX建立基础工程,过程如下:
-
芯片选择STM32F407ZGT6
-
选择 Nano 组件
(1)点击Softwares Packages
->Select Components
,进入组件配置界面:
(2)选择 RealThread, 然后点击
OK
按钮:
(3)这时会新增Software Packs展开就可以看见添加的
RealThread
,勾选相应内容:
-
RCC配置,将外部高速时钟(HSE)配置为Crystal/Ceramic Resonator(晶体/陶瓷谐振器),也就是使用外部晶振作为时钟源
-
SYS配置,选择SW调试接口,使用SWD协议下载和调试,将HAL用到的系统滴答定时器切换成定时器7,因为SysTick定时器我们要给rtthread使用
-
USART1配置,模式选择Asynchronous异步通信,用于调试打印
-
GPIO选择PG13,模式选择推挽输出,用于点亮LED
-
NVIC选择,取消掉这三个函数的生成,因为rtthread已经把这三个函数生成好了
-
时钟树配置,将时钟配置为168M主频
-
生成项目
四、代码修改
- 创建任务
- 主要是一个LED灯任务,一个串口发送任务,一个每0.5秒变化一次,一个每1秒发送一次。
- 在生成的RT-Thread工程中新建一个User文件夹,在User文件夹下新建app_rt_thread.c文件,并加载到工程下
- 并在app_rt_thread.c文件中添加以下代码
#include "rtthread.h"
#include "main.h"
#include "stdio.h"
struct rt_thread led1_thread;
rt_uint8_t rt_led1_thread_stack[128];
void led1_task_entry(void *parameter);
//初始化线程函数
void MX_RT_Thread_Init(void)
{
//初始化LED1线程
rt_thread_init(&led1_thread,"led1",led1_task_entry,RT_NULL,&rt_led1_thread_stack[0],sizeof(rt_led1_thread_stack),3,20);
//开启线程调度
rt_thread_startup(&led1_thread);
}
//主任务
void MX_RT_Thread_Process(void)
{
printf("Hello RT_Thread!!!\r\n");
rt_thread_delay(1000);
}
//LED1任务
void led1_task_entry(void *parameter)
{
while(1)
{
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_13, GPIO_PIN_RESET);
rt_thread_delay(500);
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_13, GPIO_PIN_SET);
rt_thread_delay(500);
}
}
-
找到Middlewares/RT-Thread/RTOS/kernel文件夹下的board.c文件,修改串口USART2为USART1
-
找到Application/User/Core里app_rt_thread.c下的rtconfig.h
-
在main.c文件中添加代码:
extern void MX_RT_Thread_Init(void);
extern void MX_RT_Thread_Process(void);
- main函数代码如下:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
MX_RT_Thread_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
MX_RT_Thread_Process();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
- 另外还有重写printf函数,在usart.c中添加以下代码,记住要加入#include<stdio.h>头文件
int putchar(int ch)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}