1.FreeRTOS的移植过程是将系统需要的文件和代码进行移植和裁剪,其移植的主要过程为:
(1)官网上下载FreeRTOS源码:https://www.freertos.org/
(2)移植文件夹,在portable文件夹中只需要保留:Keil、MemMang、RVDS。
(3)代码中的裁剪,修改相关的宏定义。
2.移植文件夹:
(1)首先在Keil的基本工程模板中创建一个文件夹FreeRTOS,用来存放FreeRTOS的源码:
(2)将如下三个文件夹导入到FreeRTOS目录下:
其中,Demo中存放的参考例程。License中是相关的许可信息。Source中便是FreeRTOS的源码。
(3)裁剪Source中的文件:
Source中的文件信息如下
portable中存放是FreeRTOS和硬件之间的接口桥梁,在portable中只需要保留如下三个文件夹即可。
MemMang中存放是内存管理相关的算法文件,本文选择heap_c.c。
RVDS和Keil中存放是软件和硬件之间的接口文件。本文的STM32是Coretex-M3系列,所以需要选择ARM_CM3。
3.创建工程文件:
在基础工程文件中创建两个如下两个文件夹用来存放FreeRTOS相关的文件:
添加文件:
4.导入头文件的路径:
5.移植FreeRTOSConfig.h文件:
FreeRTOSConfig.h是FreeRTOS的配置文件,通常FreeRTOS的裁剪都是通过修改此文件中的宏定义来实现。选择芯片序号和开发环境对应的文件:
将FreeRTOSConfig.h复制到自己的工程文件下,本文将FreeRTOSConfig.h放在include文件夹下:
6.代码裁剪:
(1)添加宏定义,将STM32的PendSV_Handler、SVC_Handler、SysTick_Handler映射到FreeRTOS中。在FreeRTOS中添加如下三个宏定义:
(2)注释stm32f10x_it.c中的SysTick_Handler()、SVC_Handler()和 PendSV_Handler()三个中断服务函数。因为在FreeRTOS中已经重新定义了这三个中断服务函数,所以此处需要注释,防止重复定义。
7.创建任务:
(1)led.c
#include "led.h"
void LED_Init(void)
{
//¶¨Òå¶Ë¿ÚµÄ½á¹¹Ìå:
GPIO_InitTypeDef GPIO_InitStruct;
//1.ʹÄÜʱÖÓ£º
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOA,ENABLE);
//2.ÅäÖö˿ڽṹÌåµÄÏà¹ØÐÅÏ¢£º£¨LED1£©
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD,&GPIO_InitStruct);
//ÅäÖÃLED0£º
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
GPIO_Init(GPIOA,&GPIO_InitStruct);
//³õʼʱ½«LEDµÄ¶Ë¿Ú¶¼ÖÃΪ1£¬¼´Ï¨Ãð
GPIO_SetBits(GPIOA,GPIO_Pin_8);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
}
(2)main.c:
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "FreeRTOS.h"
#include "task.h"
TaskHandle_t led0_handler;
TaskHandle_t led1_handler;
void led0(void)
{
while(1)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_8); //´ò¿ªLED
vTaskDelay(500);
GPIO_SetBits(GPIOA,GPIO_Pin_8); //´ò¿ªLED
vTaskDelay(500);
}
}
void led1(void)
{
while(1)
{
GPIO_ResetBits(GPIOD,GPIO_Pin_2); //´ò¿ªLED
vTaskDelay(1000);
GPIO_SetBits(GPIOD,GPIO_Pin_2); //´ò¿ªLED
vTaskDelay(1000);
}
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// ÉèÖÃÖжÏÓÅÏȼ¶·Ö×é2
LED_Init();
/*´´½¨ÈÎÎñ*/
xTaskCreate((TaskFunction_t) led0, //ÈÎÎñº¯Êý
(const char *)"led0_task", //ÈÎÎñÃû³Æ
(uint16_t)50, //ÈÎÎñ¶ÑÕ»´óС
(void *)NULL, //´«µÝ¸øÈÎÎñº¯ÊýµÄ²ÎÊý
(UBaseType_t)1, //ÈÎÎñÓÅÏȼ¶
(TaskHandle_t *)&led0_handler); //ÈÎÎñ¾ä±ú
xTaskCreate((TaskFunction_t) led1,
(const char *)"led1_task",
(uint16_t)50,
(void *)NULL,
(UBaseType_t)1,
(TaskHandle_t *)&led1_handler);
vTaskStartScheduler(); //¿ªÊ¼ÈÎÎñµ÷¶È
}
8.运行结果:本文的运行结果是两个LED灯闪烁,其中led0每500ms闪烁一次,led1每1000ms闪烁一次。
9.总结:
FreeRTOS的移植过程主要是对相关的文件和代码进行裁剪。需要去了解每个文件夹中代码的大搞功能,才可以正确的移植文件。
此外,当使用xTaskGetSchedulerState()函数时,需要将FreeRTOS.h中的对应宏定义改为1: