FreeRTOS移植(标准库)
移植前需要清楚自己的环境,我的是标准库,基于裸机移植的。
单片机是:STM32F103C8T6
前戏:
1.2.官网下载源码:
只需要FreeRTOS文件即可,里面存放的是内核;
2.打开FreeRTOS文件
3.打开Source
打星号的是重点;
注:FreeRTOS是软件层面的东西,protable文件夹里面的东西就是连接桥梁,连接硬件和软件的文件。(原子哥这么讲的,我不懂哦!)
protable文件夹里面的重点:
正题:
移植步骤:
1.添加FreeRTOS源码添加至基础工程
在自己的基础工程新建三个文件夹
在FreeRTOS官方代码里面,将Source里面的.c文件移植到自己新建的MiddlewaresFreeRTOS_CORE工程里面
将FreeRTOS官方文件里面内核文件里面portable里面的MemMang里面的heap_4.c移植到自己的工程MiddlewaresFreeRTOS_PORT
将FreeRTOS官方里面的port.c文件移植到自己MiddlewaresFreeRTOS_PORT工程里面。
port文件是软件与MCU硬件连接的桥梁,STM32不同系列的开发板在官方文件当中对应的位置也是不一样的。
自己工程里面的FreeRTOS文件夹是全部复制官方文件中的FreeRTOS里面的Source文件内容
在port文件里面稍作了修改,只复制了三个文件
2.添加头文件和.c文件就不多说了
3.移植FreeRTOSConfig.h文件,还是官方代码当中找到自己对应的型号直接移植就行,但是要在里面添加三个宏;
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
#define vPortSVCHandler SVC_Handler
3.修改sys.c和usart.c、delay.c文件
这个地方有个疑问,很多博主都是基于uC/OS移植的,我是裸机,我发现这些东西不修改也可以使用。(希望懂得大佬可以解答一下)
4.修改stm32f10x_it.c,只需要屏蔽三个函数即可。
5.在主函数里面编写实验代码。
#include "stm32f10x.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_STK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define LED0_TASK_PRIO 2
//任务堆栈大小
#define LED0_STK_SIZE 50
//任务句柄
TaskHandle_t LED0Task_Handler;
//任务函数
void led0_task(void *pvParameters);
//任务优先级
#define LED1_TASK_PRIO 3
//任务堆栈大小
#define LED1_STK_SIZE 50
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
void GPIO_INIT()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB,PE端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6; //LED0-->PB.5 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5
GPIO_SetBits(GPIOB,GPIO_Pin_5|GPIO_Pin_6); //PB.5 输出高
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建LED0任务
xTaskCreate((TaskFunction_t )led0_task,
(const char* )"led0_task",
(uint16_t )LED0_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED0_TASK_PRIO,
(TaskHandle_t* )&LED0Task_Handler);
//创建LED1任务
xTaskCreate((TaskFunction_t )led1_task,
(const char* )"led1_task",
(uint16_t )LED1_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED1_TASK_PRIO,
(TaskHandle_t* )&LED1Task_Handler);
vTaskDelete(StartTask_Handler); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//LED0 任务函数
void led0_task(void *pvParameters)
{
while(1)
{
GPIO_SetBits(GPIOB,GPIO_Pin_6);
vTaskDelay(500);
GPIO_ResetBits(GPIOB,GPIO_Pin_5);
vTaskDelay(500);
}
}
//LED1 任务函数
void led1_task(void *pvParameters)
{
while(1)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_6);
vTaskDelay(300);
GPIO_SetBits(GPIOB,GPIO_Pin_5);
vTaskDelay(300);
}
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组 4
GPIO_INIT();
//创建开始任务
xTaskCreate((TaskFunction_t )start_task, //任务函数
(const char* )"start_task", //任务名称
(uint16_t )START_STK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
vTaskStartScheduler(); //开启任务调度
}
这里需要注意的是:头文件顺序。