(根据正点原子视频学习总结)
准备材料
1.FreeRTOS源码
2.正点原子跑马灯例程
FreeRTOS百度网盘连接
提取码:x7b6
1.添加FreeRTOS源码
在跑马灯例程中添加FreeRTOS文件夹
然后,将FreeRTOS源码source文件夹下的文件复制粘贴到刚刚跑马灯例程下新建的FreeRTOS文件夹下。
将文件复制完成后,打开portable文件夹,删除不需要的文件,只保留Keil、MemMang、RVDS
2.将文件添加到工程
在工程中添加分组,FreeRTOS_CORE和FreeRTOS_PORTABLE,CORE中存放FreeRTOS内核源文件(FreeRTOS下的7个.c文件),PORTABLE用于存放FreeRTOS内核的移植文件,需要添加heap_x.c和port.c进去,其中heap_x.c是不同类型的内存管理算法,port.c需要根据不同的芯片类型来选择对应的文件夹中的port.c(各文件夹位于FreeRTOS下的portable中,heap_x位于MemMang下,port位于RVDS下)。
类型 | port.c所在文件夹 |
---|---|
STM32F1 | ARM_CM3 |
STM32F4 | ARM_CM4F |
STM32F7 | ARM_CM7/r0p1 |
STM32H7 | ARM_CM7/r0p1 |
添加完成后如图所示:
3.添加头文件路径
添加完成后,对.c文件添加对应的头文件路径(魔术棒)。
注:这里要添加FreeRTOS文件下的include文件夹。
这里路径添加完成后,选择编译报错并会提示打不开FreeRTOSConfig.h文件
4.添加FreeRTOSConfig.h文件
FreeRTOSConfig.h 是 FreeRTOS 操作系统的配置文件,它不属于源码的文件,是根据需要来修改的,当然它在源码文件中Demo中也存在,这里选择使用正点原子例程中的FreeRTOSConfig.h文件,将它复制我们工程中FreeRTOS文件夹下的include文件夹下。
将FreeRTOSConfig.h 复制到上图位置后,对工程进行编译,这里我出现了两个报错。
报错1:…\FreeRTOS\queue.c(2762): error: #268: declaration may not appear after executable statement in block
QueueRegistryItem_t * pxEntryToWrite = NULL;
解决办法:魔术棒里勾选C99mode即可解决
报错2:…\SYSTEM\usart\usart.c(48): error: #260-D: explicit type is missing (“int” assumed)
_sys_exit(int x)
解决办法:将_sys_exit(int x) 改为void _sys_exit(int x)
修改完成后,即和正点原子视频中报错一致,将重复定义的函数屏蔽掉,再次编译显示无报错。
5.修改SYSTEM文件夹
建议直接复制例程中SYSTEM文件
①修改sys.h
sys.h的修改较为简单,只需将SYSTEM_SUPPORT_OS的0改为1即可。
②修改usart.c
usart.c文件有两部分要修改,一是添加FreeRTOS.h头文件,修改以后如下:
另外一个就是USART1的中断服务函数,删除掉OSIntEnter()和OSIntExit(),修改以后如下:
③delay.c
delay.c修改较大,这里建议直接使用例程中的,复制粘贴。
之后屏蔽掉SysTick_Handler函数
6.代码测试
完成上述工作后,将main.c替换为下面代码进行测试
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.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);
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//
delay_init();
uart_init(115200);
LED_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();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL();
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);
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();
}
void led0_task(void *pvParameters)
{
while(1)
{
LED0=~LED0;
vTaskDelay(500);
}
}
void led1_task(void *pvParameters)
{
while(1)
{
LED1=0;
vTaskDelay(200);
LED1=1;
vTaskDelay(800);
}
}
LED灯工作说明移植成功。