前言
本文是教你如何将FreeRTOS移植到自己搭建的标准库工程当中。你需要准备一块STM32F10x系列的板子一块和已经搭建好的标准库工程一个,然后就只需要跟着本文做就可以了。
一、FreeRTOS
在移植FreeRTOS前,先来认识认识FreeRTOS。
FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要。
由于RTOS需占用一定的系统资源(尤其是RAM资源),只有μC/OS-II、embOS、salvo、FreeRTOS等少数实时操作系统能在小RAM单片机上运行。相对μC/OS-II、embOS等商业操作系统,FreeRTOS操作系统是完全免费的操作系统,具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行,其最新版本为11.0.0版。
在此就不再过多的介绍FreeRTOS,感兴趣的朋友可以自行百科。
二、下载FreeRTOS
1)点击下面的链接进入FreeRTOS官网
2)在官网首页点击 “下载FreeRTOS” 进入下载页面
3)点击下载最新版本的FreeRTOS
三、移植FreeRTOS
1)解压下载好的FreeRTOS压缩包,里面的文件如下图所示
我们只关注FreeRTOS文件,因为这个FreeRTOS文件里面包含了移植FreeRTOS实时操作系统所需要的所有文件。下面开始移植FreeRTOS。
2)在搭建好的工程中新建FreeRTOS文件
3)然后在FreeRTOS文件中新建inc、src、port三个文件
inc 头文件
src源文件
port移植层
4)移植FreeRTOS头文件
将解压后的FreeRTOS的
...\FreeRTOSv202212.01\FreeRTOS\Source\include
路径下的所有文件复制到工程的FreeRTOS的inc
5)移植对应芯片的配置文件
将解压后的FreeRTOS的
...\FreeRTOSv202212.01\FreeRTOS\Demo\CORTEX_STM32F103_Keil
路径下的FreeRTOSConfig.h复制到工程的FreeRTOS的inc
于是工程的FreeRTOS的inc文件内容如下(未截取完整)
6)移植FreeRTOS源文件
将解压后的FreeRTOS的
...\FreeRTOSv202212.01\FreeRTOS\Source
路径下的所有.c文件复制到工程的FreeRTOS的src
于是工程的FreeRTOS的src内容如下
7)移植内存管理单元(Memory Management Unit)
将解压后的FreeRTOS的
...\FreeRTOSv202212.01\FreeRTOS\Source\portable
路径下的MemMang复制到工程的FreeRTOS的portable
8)将对应芯片的port.c和portmacro.h移植到工程的port中
将解压后的FreeRTOS的
...\FreeRTOSv202212.01\FreeRTOS\Source\portable\RVDS\ARM_CM3
路径下的所有文件复制到工程的FreeRTOS的portable
于是工程的FreeRTOS的port内容如下
四、keil工程添加FreeRTOS
1)在工程树中新建分组“FreeRTOS”
首先将工程中的FreeRTOS下的src中的所有文件加入FreeRTOS分组中
再将工程中的FreeRTOS下的port中的port.c文件加入FreeRTOS分组中
最后将工程中的FreeRTOS下的port中的MenMang文件下的heap_4.c加入FreeRTOS分组中
2)添加头文件路径
五、运行FreeRTOS
为了让FreeRTOS正常工作还需在FreeRTOSConfig.h和stm32f10x_it.c两个文件中添加如下3行宏定义
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define xPortSysTickHandler SysTick_Handler
并且还需要注释掉stm32f10x_it.c下的SVC_Handler、PendSV_Handler、SysTick_Handler这3个函数。
最后我们在main.c中添加如下代码
#include "stm32f10x.h" // Device header
#include "FreeRTOS.h"
#include "task.h"
TaskHandle_t app_task1_handle = NULL;
TaskHandle_t app_task2_handle = NULL;
void App_Task1(void* pvParamenters);
void App_Task2(void* pvParamenters);
int main(void)
{
//将全部优先级设为抢占优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
//创建任务
xTaskCreate((TaskFunction_t)App_Task1, //任务入口函数
(const char *)"App_Task1", //任务名字
(uint16_t)configMINIMAL_STACK_SIZE, //任务栈大小
(void*)NULL, //任务入口函数参数
(UBaseType_t)1, //任务优先级
(TaskHandle_t*)&app_task1_handle); //任务句柄
//创建任务
xTaskCreate((TaskFunction_t)App_Task2, //任务入口函数
(const char *)"App_Task2", //任务名字
(uint16_t)configMINIMAL_STACK_SIZE, //任务栈大小
(void*)NULL, //任务入口函数参数
(UBaseType_t)1, //任务优先级
(TaskHandle_t*)&app_task2_handle); //任务句柄
//开启任务调度器
vTaskStartScheduler();
}
void LED_Init()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能C端口时钟
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50Mhz
GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化GPIOC
}
void App_Task1(void *pvParameters)
{
LED_Init();
for(;;)
{
GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_RESET);
vTaskDelay(500);
GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);
vTaskDelay(500);
}
}
void App_Task2(void *pvParameters)
{
for(;;)
{
}
}
下载后现象是LED灯闪亮。为了验证任务2也可以执行,还需要将任务1中的内容和任务2中的内容交换。交换后LED灯依旧闪亮,则移植成功。
补充
有个小问题,我的一位朋友在复制main.c代码的时候,使用手机阅读的,于是用手机复制的,再传到电脑上使用,会报错。可能是文本的转换出了问题,因此推荐大家使用电脑复制
总结
关于将FreeRTOS的移植到自己的标准库工程中
首先,需要在工程中创建FreeRTOS文件,并在FreeRTOS文件中新建inc、src、port三个子文件
其次,就是将官方给出的FreeRTOS移植到自己的工程中
最后,就是将FreeRTOS添加进自己的keil工程中,并在FreeRTOSConfig.h和stm32f10x_it.c这2个文件中添加宏定义和注释掉stm32f10x_it.c文件中的SVC_Handler、PendSV_Handler、SysTick_Handler这3个函数