2、STM32F407移植FreeRTOS步骤

目录

1、源码准备

2、创建FreeRTOS文件夹

3、在工程中添加FreeRTOS源码

4、添加对应的头文件路径

5、编译及错误解决

5.1 找不到FreeRTOSConfig.h文件

5.2 SystemCoreClock未定义

5.3 重复定义

5.4 钩子函数未定义

6、修改SYSTEM文件

6.1 修改sys.h文件

6.2 修改usart.c文件

6.3 修改delay.c文件

7、修改main.c进行功能验证



1、源码准备

       首先准备好我们下载好的FreeRTOS源码以及STM32F407的工程模板(这里以原子的F4跑马灯工程为例,可去原子的开源论坛自行下载),源码下载及参考请参考我的上一篇博客。


2、创建FreeRTOS文件夹

在工程中创建FreeRTOS文件夹,将FreeRTOS源码全部复制到该文件夹下

打开portable文件夹,删除没用的文件,留下如下文件即可


3、在工程中添加FreeRTOS源码

打开工程,在工程中新建FreeRTOS_CORE和FreeRTOS_PORTABLE,然后向着两个组中添加对应的文件,如下图所示:

       FreeRTOS_CORE的文件打开FreeRTOS就可看到,port.c是RVDS文件夹下的ARM_CM4F中的,因为STM32F407是Cortex-M4内核并且带FPU。Heap_4.c是MemMang文件夹中,这里有5个文件,是5个不同的内存管理方法,为什么选择第4个,因为FreeRTOS内存管理所决定。


4、添加对应的头文件路径


5、编译及错误解决

5.1 找不到FreeRTOSConfig.h文件

完成后编译一下,会出现如下错误

       很明显是没有FreeRTOSConfig.h这个文件,那我们就把它添加进去,具体位置在FreeRTOS的DEMO中找到CORTEX_M4F_STM32F407ZG-SK文件,如下图所示

      至于放到哪个位置自己随意,一般是放在FreeRTOS的include里面,而这个文件是FreeRTOS的配置文件,一般操作系统都有裁剪、配置功能,而这些都是通过一个文件内的宏定义来完成。

5.2 SystemCoreClock未定义

接着上面的步骤再编译一次,还会出现以下错误,意思是SystemCoreClock未定义

解决办法:修改条件编译

5.3 重复定义

接着再编译一下,发现还有错误,这次的错误是重复定义

解决办法:

     屏蔽掉stm32f4xx_it.c中的PendSV_Handler(),SVC_Handler(),SysTick_Handler()这三个函数,

5.4 钩子函数未定义

     继续编译一次,还是会有错,这次的错是函数未定义,他们都是Hook结尾的,称为钩子函数。

解决办法:

        去FreeRTOSConfig.h中关闭这些钩子函数,他们都是宏定义决定,这里将configUSE_IDLE_HOOK、configUSE_TICK_HOOK、configUSE_MALLOC_FAILED_HOOK和configUSE_FOR_STACK_OVERFLOW定义为0.

再编译一下应该就没错了。


6、修改SYSTEM文件

因为原子的SYSTEM文件夹是针对UCOS编写的,所以要进行对应的修改

6.1 修改sys.h文件

把宏定义改为1即可,要支持OS,UCOS也一样的

6.2 修改usart.c文件

修改头文件为

修改串口中断服务函数为:

6.3 修改delay.c文件

同样先修改宏定义的头文件

接着修改systick中断服务函数为

在滴答定时器中断服务函数中调用FreeRTOS的API函数xPortSysTickHandler();

在修改delay_init()函数,如下:

接下来就是延时函数的修改

修改完后再编译一下,会出现重复定义的错误,如下图:

解决办法:屏蔽FreeRTOSConfig.h掉底部的#define xPortSysTickHandler SysTick_Handler


7、修改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			120
void start_task(void * pvParameters);  //任务函数
TaskHandle_t StartTask_Handler;		//任务句柄	 
 
 
#define TASK1_TASK_PRIO			2
#define TASK1_STK_SIZE			120
void task1_task(void * pvParameters);
TaskHandle_t Task1Task_Handler;		//任务句柄	 

#define TASK2_TASK_PRIO			3
#define TASK2_STK_SIZE			120 
void task2_task(void * pvParameters);
TaskHandle_t Task2Task_Handler;		//任务句柄	

int main(void)
{
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
		delay_init(168);                //初始化延时函数
    LED_Init();                     //初始化LED 
    uart_init(115200);              //初始化串口
       
	xTaskCreate((TaskFunction_t	) start_task,
				(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)
{
	//创建Task1
	xTaskCreate((TaskFunction_t	) task1_task,
				(char*			) "task1_task",
				(uint16_t		) TASK1_STK_SIZE,
				(void * 		) NULL,
				(UBaseType_t	) TASK1_TASK_PRIO,
				(TaskHandle_t*	) &Task1Task_Handler);
				
	//创建Task2
	xTaskCreate((TaskFunction_t	) task2_task,
				(char*			) "task2_task",
				(uint16_t		) TASK1_STK_SIZE,
				(void * 		) NULL,
				(UBaseType_t	) TASK2_TASK_PRIO,
				(TaskHandle_t*	) &Task2Task_Handler);
	vTaskDelete(StartTask_Handler); //NULL
}

void task1_task(void * pvParameters)
{
	char task1_num=0;
	
	while(1)
	{
		task1_num++;
		
		LED0 = ~LED0;
		printf("Task1 Runing %d !\r\n",task1_num);
		
		vTaskDelay(1000);
	}
}

void task2_task(void * pvParameters)
{
	char task2_num=0;
	while(1)
	{
		task2_num++;
		
		LED1 = ~LED1;
		printf("Task2 Runing %d!\r\n",task2_num);
		vTaskDelay(500);
	}
}

实验现象;

      开发板上LED0和LED1进行不同状态的闪烁,串口也会打印任务执行次数,很明显任务二的速度是任务一的两倍。

     

我这里使用的是STM32F407VET6,原理都差不多,用那块板子都一样。至此,FreeRTOS移植和任务创建成功。



 

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值