当前位置:   article > 正文

STM32移植freeRTOS_stm32 freertos

stm32 freertos

STM32F103C8T6 移植freeRTOS:

  1. 移植前准备

    (1)下载freeRTOS源码freeRTOS官网:https://www.freertos.org/zh-cn-cmn-s/
    (2)准备32工程代码,以江科大的3-1 LED闪烁为模板开始移植。

  2. 提取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里面去。
    在这里插入图片描述

  3. 打开模板工程添加文件,设置文件路径
    (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. 修改文件内容
    (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)
    在这里插入图片描述

  2. 编写主函数代码测试移植是否成功

#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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

STM32F407ZGT6 移植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
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述

此时编译便不会出问题了

编写主程序测试移植是否工程

#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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

编译 下载 发现 如果有现象就移植成功

代码移植时的注意事项:
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(); //退出临界区一定要配套使用否则就不会进行任务调度,现象可能也为卡死现象

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/730356
推荐阅读
相关标签
  

闽ICP备14008679号