1、开发环境
(1)Keil MDK: V5.38.0.0
(2)STM32CubeMX: V6.8.1
(3)MCU: STM32F103C8(F1系列软仿真最方便)
(4)ARM编译器:V5(使用V6编译会报错)
2、移植准备工作
(1)用于移植FreeRTOS的基础工程。
- 时钟已配置好
- 串口已配置好
- printf已经重定向到串口1
(2)FreeRTOS官网下载的带示例的源码。
(3)printf重定向程序
int fputc( int ch, FILE *f )
{
USART_TypeDef *USARTx = USART1;
while( (USARTx->SR & (1<<7)) == 0); // 等待上次的数据发送完成
USARTx->DR = ch;
return ch;
}
3、添加FreeRTOS源码
(1)在基础工程中新建Middlewares文件夹。如下图所示:
(2)将FreeRTOS源码的FreeRTOS整个文件复制到工程的Middlewares文件夹中。
(3)FreeRTOS文件下只保留Source,其余均删除。
(4)Source目录下保留以下文件。
(5)portable目录下保留以下文件。
(6)RVDS目录下保留用到的架构文件,STM32F1系列使用ARM_CM3。
4、添加FreeRTOSConfig.h文件
(1)FreeRTOSConfig.h 是 FreeRTOS 操作系统的配置文件, FreeRTOS 操作系统是可裁剪的,用
户可以根据需求对 FreeRTOS 进行裁剪,裁剪掉不需要用到的 FreeRTOS 功能,以此来节约 MCU中寸土寸金的内存资源。
(2)FreeRTOSConfig.h获取途径
- 自己编写
- FreeRTOS官方源码中Demo(示例工程)下的FreeRTOSConfig.h。(后续根据需要在进行相应修改)
(3)将官方示例中的FreeRTOSConfig.h文件复制到“FreeRTOS_01_Create_Task\Middlewares\FreeRTOS\Source\portable”目录下。也可选择其他自己认为更合适的目录。
5、将FreeRTOS源码添加到Keil工程
(1)KeilMDK打开工程,新建两个文件分组,分别为 Middlewares/FreeRTOS_CORE 和
Middlewares/FreeRTOS_PORT,如下图所示:
(2)Middlewares/FreeRTOS_CORE 分组用于存放 FreeRTOS 的内核 C 源码文件,将 “FreeRTOS_01_Create_Task\Middlewares\FreeRTOS\Source”目录下的.c文件添加到该分组。
(3)Middlewares/FreeRTOS_PORT 分组用于存放 FreeRTOS 内核的移植文件。
- 添加“Middlewares\FreeRTOS\Source\portable\RVDS\ARM_CM3”目录下的port.c文件。
- 添加“Middlewares\FreeRTOS\Source\portable\MemMang”目录下的heap_4.c文件。
(4)添加头文件路径。
6、修改stm32f1xx_it.c文件
(1)添加下面三个函数。
extern void xPortPendSVHandler(void);
extern void xPortSysTickHandler(void);
extern void vPortSVCHandler(void);
(2)修改SVC_Handler函数。
(3)修改PendSV_Handler函数。
(4)修改SysTick_Handler函数。
7、修改时基
(1)在STM32 HAL的项目中,一般需要考虑两个时基:
- HAL时基、SYS时基源
- 操作系统时基
(2)在裸机程序中,SYS时基源默认使用SysTick;在RTOS中,SYS时基源修改为其他定时器,RTOS上基使用SysTick。
(3)修改SYS时基为其他定时器,这里修改为TIM4。
(4)SYS时基源和RTOS时基源也可以共用SysTick,但CubeMX不建议这么用,既然不建议,那我们就不用呗。
8、创建任务示例
8.1、程序结构
(1)芯片厂商提供的芯片操作库,如STM32的标准库和HAL库。
(2)FreeRTOS的源码。
(3)用户编写的源码。
8.2、程序编写
(1)使用两个函数分别创建两个任务;需要包含头文件"FreeRTOS.h"和"task.h"。
(2)任务1的代码
/*任务1的函数*/
void vTask1( void * param)
{
while(1)
{
printf("1");
}
}
(2)任务2代码
/*任务2的函数*/
void vTask2( void * param)
{
while(1)
{
printf("2");
}
}
(3)main函数
int main( void )
{
...
xTaskCreate(vTask1, "task1", 100, NULL, 1, NULL); /*创建任务1*/
xTaskCreate(vTask2, "task2", 100, NULL, 1, NULL); /*创建任务2*/
/* 启动调度器 */
vTaskStartScheduler();
}
(4)运行效果(也可以软件仿真)
8.3、完整工程下载地址
(1)完整工程存储再码云。
(2)FreeRTOS_CSDN: 用来保存FreeRTOS学习使用中用到的程序