赞
踩
移植前准备
(1)下载freeRTOS源码freeRTOS官网:https://www.freertos.org/zh-cn-cmn-s/
(2)准备32工程代码,以江科大的3-1 LED闪烁为模板开始移植。
提取freeRTOS的核心代码
(1)解压官网下载的freeRTOS文件找到FreeRTOSv202212.01\FreeRTOS下的Source文件夹复制32模板文件夹中
(2)获取FreeRTOSConfig.h文件
点开加压的freeRTOS源码文件来到\FreeRTOSv202212.01\FreeRTOS\Demo目录下查找对应的Demo文件,我们用的是STM32F103C8T6找到对应的文件名:CORTEX_STM32F103_Keil
点开复制其中的FreeRTOSConfig.h到32模板工程Source下的include里面去。
打开模板工程添加文件,设置文件路径
(1)创建文件夹添加文件
打开模板工程项目后点击Manage Project ltems那个小按钮如下
创建两个文件夹 freeRTOS和freeRTOS_PORTABLE
分别添加对应文件
freeRTOS添加Source下的7个文件如下
freeRTOS_PORTABLE添加两个文件分别是port.c和heap_4.c
port.c路径:Source->portable->RVDS->ARM_CM3->port.c
heap_4.c路径:Source->portable->MemMANG->heap_4.c
(2)添加两个文件路径
分别是:Source\include和Source\portable\RVDS\ARM_CM3
路径添加好后如下图
修改文件内容
(1)往FreeRTOSConfig.h添加:
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
(2)屏蔽stm32f10x_it.c文件下的三个中断服务函数:
void SVC_Handler(void)
PendSV_Handler(void)
SysTick_Handler(void)
编写主函数代码测试移植是否成功
#include "stm32f10x.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); //任务函数 //LED闪烁任务 #define LedShine_TASK_PRIO 1 //任务优先级 #define LedShine_STK_SIZE 128 //任务堆栈大小 TaskHandle_t LedShineTask_Handler; //任务句柄 void LedShine_task(void *pvParameters); //任务函数 /************************************************/ //主函数 int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置中断优先级分组为组 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 )LedShine_task, //任务函数 (const char* )"LedShine_Task", //任务名称 (uint16_t )LedShine_STK_SIZE, //任务堆栈大小 (void* )NULL, //转递给任务函数的参数 (UBaseType_t )LedShine_TASK_PRIO, //任务优先级 (TaskHandle_t* )&LedShineTask_Handler //任务句柄 ); vTaskDelete(StartTask_Handler); //删除开始任务 taskEXIT_CRITICAL(); //退出临界区,允许任务调度 } //LED闪烁任务 void LedShine_task(void *pvParameters) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); 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; GPIO_Init(GPIOC, &GPIO_InitStructure); while(1) { GPIO_ResetBits(GPIOC, GPIO_Pin_13); vTaskDelay(1000); GPIO_SetBits(GPIOC, GPIO_Pin_13); vTaskDelay(500); } } 做完以上就完成了freeRTOS的移植了完成freeRTOS
F407ZGT6前期的移植工作和C8T6很大一部分都是一样的
首先就是移植前的准备:
准备一个工程代码以及freeRTOS的源码
然后将freeRTOS中的Source文件复制到407的过程文件下
在去freeRTOS源码文件中的Demo中去找对应的FreeRTOSConfig.h文件(F407ZGT6的FreeRTOSConfig.h在CORTEX_M4F_STM32F407ZG-SK文件夹下),并将FreeRTOSConfig.h文件放到Source下的include文件夹下
然后在打开407工程创建两个文件夹freeRTOS和freeRTOS_PORTABLE并添加文件
注意:F407ZGT6的port.c文件要选择ARM_CM4F文件夹下的而不是ARM_CM4F文件夹下的。
完成这一步之后编译之后你会发现代码报错,错误原因如下
…\Source\portable\RVDS\ARM_CM4F\port.c(788): error: #20: identifier “SystemCoreClock” is undefined
做到这一步之后就要开始FreeRTOSConfig.h文件的修改了
(1)打开FreeRTOSConfig.h文件找到#ifdef ICCARM
将其改为#if defined(ICCARM) || defined(__CC_ARM) || defined(GNUC)
此时在编译会发现还会报错报错原因如下:
…\OBJ\LED.axf: Error: L6218E: Undefined symbol vApplicationIdleHook (referred from tasks.o).
…\OBJ\LED.axf: Error: L6218E: Undefined symbol vApplicationStackOverflowHook (referred from tasks.o).
…\OBJ\LED.axf: Error: L6218E: Undefined symbol vApplicationTickHook (referred from tasks.o).
…\OBJ\LED.axf: Error: L6218E: Undefined symbol vApplicationMallocFailedHook (referred from heap_4.o).
此时需要将四个钩子函数宏定义值改为0
configUSE_IDLE_HOOK
configUSE_TICK_HOOK
configUSE_MALLOC_FAILED_HOOK
configCHECK_FOR_STACK_OVERFLOW
此时编译便不会出问题了
编写主程序测试移植是否工程
#include "stm32f4xx.h" #include "FreeRTOS.h" #include "task.h" #include "led.h" //任务创建 /************************************************/ //起始任务 #define START_TASK_PRIO 1 //任务优先级 #define START_STK_SIZE 128 //任务堆栈大小 TaskHandle_t StartTask_Handler; //任务句柄 void Start_Task(void *pvParameters); //任务函数 //LED闪烁任务 #define LedShine_TASK_PRIO 1 //任务优先级 #define LedShine_STK_SIZE 128 //任务堆栈大小 TaskHandle_t LedShineTask_Handler; //任务句柄 void LedShine_task(void *pvParameters); //任务函数 /************************************************/ int main(void) { 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 )LedShine_task, //任务函数 (const char* )"LedShine_Task", //任务名称 (uint16_t )LedShine_STK_SIZE, //任务堆栈大小 (void* )NULL, //转递给任务函数的参数 (UBaseType_t )LedShine_TASK_PRIO, //任务优先级 (TaskHandle_t* )&LedShineTask_Handler //任务句柄 ); vTaskDelete(StartTask_Handler); //删除开始任务 taskEXIT_CRITICAL(); //退出临界区 } void LedShine_task(void *pvParameters) { while(1) { GPIO_ResetBits(GPIOF,GPIO_Pin_9); GPIO_SetBits(GPIOF,GPIO_Pin_10); vTaskDelay(500); GPIO_SetBits(GPIOF,GPIO_Pin_9); GPIO_ResetBits(GPIOF,GPIO_Pin_10); vTaskDelay(500); } }
编译 下载 发现 如果有现象就移植成功
代码移植时的注意事项:
1、找好工程模板以及freeRTOS的源代码可以省下很多不必要的麻烦,其次找对port.c文件还有FreeRTOSConfig.h文件。
2、freeRTOSConfig.h文件中一定要有那三个中断宏的定义,记得屏蔽stm32fxxx_it.c中的那三个中断服务函数否则会报重复定义的错。
3、F407ZGT6的freeRTOSConfig.h文件记得将#ifdef __ICCARM__改为#if defined(ICCARM) || defined(__CC_ARM) || defined(GNUC)。记得将四个钩子函数设为0.
4、还有就是在主函数中一定要记得创建了一个任务了之后再去调用vTaskDelay(500)。vTaskDelay(500)和delay_ms()是有区别的,如果你没有任务的时候调用vTaskDelay(500);则会使代码卡死,进入硬件异常。
5、还有就是taskENTER_CRITICAL(); //进入临界区与taskEXIT_CRITICAL(); //退出临界区一定要配套使用否则就不会进行任务调度,现象可能也为卡死现象
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。