【STM32】STM32平台FreeRTOS之如何移植

准备工作

我这里是基于STM32F407平台移植FreeRTOS,准备资料如下:

  • 已经移植STM32F407标准库的工程;
  • FreeRTOSv10.2.1_191129内核源码;(前面有文章说过如何下载FreeRTOS内核源码)

FreeRTOS详细的移植步骤

  • 解压FreeRTOS就能得到这个目录(FreeRTOS\FreeRTOSv10.2.1_191129\FreeRTOS\Source
    这个目录下的源码都是需要拷贝到你的Keil项目里面的。但是portable需要我们筛选一下。

  • 如何客制化portable目录
    下面的截图是FreeRTOS官网的提示,必须包含的文件:

    compiler我使用的是Keil,所以就来到了portable/Keil目录,但是它是空的并且提示See-also-the-RVDS-directory,所以我们最终需要的port.c在RVDS目录下:

    MemMang是内存管理需要包含的部分,根据FreeRTOS官网的提示我这里选择了heap_4.c,它会合并相邻的空闲块以避免碎片化。

  • 最终添加它们到工程
    如下截图是最终添加到里面的文件,并且相关的头文件也需要拷贝过来。

    以上就是所有移植过程。

FreeRTOS Demo

这个Demo code里面只是简单的创建了2个Task,循环的去执行。这么编写code之后,发现编译没有报错,但是2个Task好像并没有跑起来。

#include "main.h"
#include "./usart/bsp_debug_usart1.h"
#include "./led/bsp_led.h"
#include "./systick/bsp_systick.h"

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "list.h"

static TaskHandle_t xHandleTask1 = NULL;
static TaskHandle_t xHandleTask2 = NULL;
void AppTask1(void *pvParameters);
void AppTask2(void *pvParameters);

int main(void)
{
    
    
	// init led
	LED_GPIO_Config();
	LED2(ON);
	LED3(ON);

	// init uart 
	Debug_USART1_Config();
	printf("starting up!!!\r\n");

	// init systick
	//SysTick_Init();

	xTaskCreate(AppTask1,"Task1",512,NULL, 2,&xHandleTask1);
	xTaskCreate(AppTask2,"Task2",512,NULL, 2,&xHandleTask2);

	vTaskStartScheduler();
	while(1){
    
    
		//Delay_ms(1000);
		//printf("main runing!!!\r\n");
	}

	//return 0;
}

void AppTask1(void *pvParameters)
{
    
    
	static uint32_t count = 0;
	
	while(1)
	{
    
    
		count++;
		printf("Task1=%d\r\n",count);
		vTaskDelay( 1000 );
	}	
}

void AppTask2(void *pvParameters)
{
    
    
	static uint32_t count = 0;

	while(1)
	{
    
    
		count++;
		printf("Task2=%d\r\n",count);
		vTaskDelay( 1000 );
	}	
}

经过百度之后发现,有一个关键的Systick没有客制化,在FreeRTOSConfig.h里面添加如下代码:

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

(NOTE: 在stm32f4xx_it.c中有定义这些函数,需要屏蔽掉,否则会重复定义。)

到这里重新编译验证OK,UART打印如下:

移植过程中出现的错误

  • 错误1
    ..\FreeRTOS\inc\FreeRTOS.h(56): error: #5: cannot open source input file "FreeRTOSConfig.h": No such file or directory

    解决方法:
    FreeRTOSConfig.h这个头文件用来配置FreeRTOS的功能,最开始并不知道需要配置哪些宏,可以在FreeRTOS的源码包里面Demo Code拷贝一个过来,并且修改一下配置参数。例如:FreeRTOS\FreeRTOSv10.2.1_191129\FreeRTOS\Demo\CORTEX_STM32F103_Keil\FreeRTOSConfig.h

    // STM32F407主频为168M 
    #define configCPU_CLOCK_HZ			( ( unsigned long ) 168000000 )	
    
  • 错误2
    ..\Output\stm32f407.axf: Error: L6218E: Undefined symbol xTaskGetCurrentTaskHandle (referred from stream_buffer.o).

    解决办法:
    因为文件用到了xTaskGetCurrentTaskHandle,但是没有被定义,所以这里报错。在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetCurrentTaskHandle必须设置为1,此函数才有效。

    #define INCLUDE_xTaskGetCurrentTaskHandle	1
    

完整的工程代码

https://gitee.com/dianqi0901zc/stm32_project.git
(在这里仓库下的 stm32f407_freertos_base目录就是本次移植的完整的工程代码)

猜你喜欢

转载自blog.csdn.net/ZHONGCAI0901/article/details/103463187