1. FreeRTOS源码的下载
移植之前需要去官网获取FreeRTOS源码,官网地址:
https://sourceforge.net/projects/freertos/
建议下载v9.0.0,因为这个版本内核稳定,网上资料多,建议下载这个版本,本此实验也是使用v9.0.0版本移植的。
如果下载慢或者其他原因可以下载我的百度网盘的,包含FreeRTOS 9.0.0版本,和stm32未移植源码和移植后的源码。地址如下:
链接: https://pan.baidu.com/s/11RFfH6j1macnsB3znFj6DQ 提取码: y5v2
2. FreeRTOS源码介绍
FreeRTOS包含Demo例程和Source内核源码.
Source文件夹里面包含的是FreeRTOS内核的源代码,我们移植FreeRTOS的时候就需要这部分源代码。
Demo 文件夹里面包含了FreeRTOS官方为各个单片机移植好的工程代码。
Source文件夹
include 里面的头文件 和 红框里面的.c文件是移植FreeRTOS 所需通用的.h和.c文件
portblle文件夹,是与编译器相关的文件夹,在不同的编译器中使用不同的支持文件、不同的硬件使用不一样的内核版本,下面就说一下我们移植所需要的文件,keil 文件夹就是我们使用的编译器软件,RVDS文件夹里面的内容和keil一样,所以我们只需要RVDS文件夹内容即可,里面包含了STM32 M0,M3,M3各个系列,我们选用的是M3,MemMang文件夹下存放的是跟内存管理相关的文件。最后我们移植需要的文件夹就Memmang 和 RVDS。
3. FreeRTOS系统移植
1.准备一个stm32标准库工程,如果没有的话去下载我的源码,里面有未移植的stm32工程。
我的工程是江科大。
2.在stm32工程中新建一个文件夹FreeRTOS。
3.在刚才创建的FreeRTOS文件夹中,分别新建src、inc、port文件夹:
- src文件夹用来存放源码
- inc文件夹用来存放头文件
- port文件夹用来存放移植平台的相关文件
4.接下来将FreeRTOS源码文件移放到刚刚新建的文件夹中
回到Source文件夹中,将文件夹所以的.c文件复制到src文件夹下
5.在source文件夹中的include文件夹里全部都是FreeRTOS的头文件,将其添加到工程新建的inc文件夹中
再把FreeRTOS v9.0.0->demo->CORTEX_STM32F103_keil里面的FreeRTOSConfig.h复制到inc文件夹中
6.将Source->portable->MemMang 里面的heap_4.c 复制到port文件夹下。
将Source->portable->RVDS->ARM_CM3里面的port.c 和portmacro.h文件复制到port文件夹下
7.接着我们添加文件路径,点击魔术棒->c/c++->include paths.点击添加路径。
8.把所以的路径添加进来:
9.建组将文件全部添加到工程中,点击魔术棒旁边的三个格子的图标,选择新建组,我们分别新建FreeRTOS/src、FreeRTOS/inc、FreeRTOS/port三个组,将工程文件夹src中的所有.c文件添加到FreeRTOS_src中,将工程文件夹inc中的所有.h文件添加到FreeRTOS_inc中(不包括.readme),将工程文件夹port中的文件(heap_4.c、port.c添加到FreeRTOS_port中,还有配置文件FreeRTOSConfig.h添加到FreeRTOS_inc组中
点击黄框,如图新建三个组,点击Add files ,把所有的文件对应添加进来。
在FreeRTOSConfig.h中添加:
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define xPortSysTickHandler SysTick_Handler
同时在stm32f10x.it.c中注释这下面三个文件
void SVC_Handler(void)
{
}
void PendSV_Handler(void)
{
}
void SysTick_Handler(void)
{
}
到这里移植已经全部完成。
4.创建任务测试:
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "FreeRTOS.h"
#include "task.h"
#include "LED.H"
static void AppTask(void* parameter)
{
while (1)
{
LED1_ON();
vTaskDelay(500);
LED1_OFF();
vTaskDelay(500);
}
}
static TaskHandle_t AppTask_Handle = NULL;
int main(void)
{
BaseType_t xReturn = pdPASS;
LED_Init();
xReturn = xTaskCreate((TaskFunction_t )AppTask,
(const char* )"AppTask",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )1,
(TaskHandle_t* )&AppTask_Handle);
if(pdPASS == xReturn)
vTaskStartScheduler();
else
return -1;
while(1);
}
最后成功使led一闪一灭,试验成功。
参考博客: