FreeRTOS移植到STM32-任务的创建

本文详细指导如何将FreeRTOS移植到STM32F103ZET6微控制器,涉及源码结构、所需文件、移植前准备、配置步骤和中断向量处理等内容,以LED闪烁为例验证移植成功。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文的主要内容重在应用,将FreeRTOS移植到STM32F103ZET6(其他类型的型号一样可以参考本文,只用略做一点修改就行,会在下面进行讲解,区别在哪里)上进行相关的小实验。

1.FreeRTOS的源码下载

  源码的官方下载地址为 FreeRTOS官方下载链接,本次移植的版本的是V10.3.0。

下载好后的文件如下:

其中我们只关心FreeRTOS文件夹,里面是内核所在的文件夹,包含源码和示例程序;FreeRTOS-Plus文件包含第3方中间源码及示例程序;FreeRTOS-Labs文件是V9.0及以前版本中所没有的。

1.1 FreeRTOS源码文件夹

其中Demo是FreeRTOS的示例,Source是FreeRTOS内核所在的文件夹。

1.2 Source文件夹

include文件夹存放的是对应.c文件的头文件。portable文件夹是FreeRTOS和具体硬件联系在一起的桥梁,也叫移植层文件夹。

1.3 portable文件夹

 FreeRTOS在不同的编译环境,不同的硬件平台实现,需要portable文件夹对应的文件支持,因此移植层文件是进行移植的关键文件。

对于在MDK-ARM编译环境下,需要Keil,MenMang,RVDS文件。其中重点关注RVDS文件夹,它里面包含了针对不同架构的MCU实现FreeRTOS与硬件相关的操作与宏定义,不同的架构的MCU使用对于其架构相对于的文件夹。列如,STM32F1xx系列的芯片属于ARM Cortex-M3内核,使用ARM_CM3文件夹的文件就行,用STM32F4xx系列的芯片使用ARM_CM4F文件夹的文件就行,这里主要就是不同芯片移植主要的不同点之一。

1.3 ARM_CM3文件夹

到这里基本要移植需要的文件已经列举出来了。

2. FreeRTOS的移植

2.1 移植前基础工程的准备

本文采用的是MDK-ARM为编译环境,以STM32F103ZET6开发板为移植平台。先准备一个LED闪烁的基础工程。本文用的工程是以B站的江科大up主的基础模板,(只要你的工程可以点灯就行)使用的是标准库。当然,用标准库,寄存器或者HAL库都是可以的,移植和用那个库没有必要的联系,移植的过程是一样的。

基础工程的项目分组如下:

2.2 复制FreeRTOS源码

在基础工程的的文件夹下新建立一个FreeRTOS的文件夹。

将FreeRTOS源码文件夹下的Source文件夹下的全部文件复制到基础工程下新建的FreeRTOS文件夹下。

打开portable文件夹,只保留Keil,MenMang,RVDS这3个目录。

2.3 向工程中添加.c文件

点击3个小方块

这就是完整的项目工程,如果不会添加.c文件的请他其他文章。

2.3 配置头文件

点击魔术棒

在include paths配置头文件路径

2.4 配置FreeRTOS

FreeRTOS使用FreeRTOSConfig.h文件进行配置和裁剪。FreeRTOSConfig.h文件可以从下载的FreeRTOS源码G:\FreeRTOSv10.3.0\FreeRTOSv10.3.0\FreeRTOS\Demo\CORTEX_STM32F103_Keil示例程序中复制。

把FreeRTOSConfig复制到自己的FreeRTOS工程下的include目录下(复制到其他目录下也是可以的,但是要注意配置好头文件包含路径)

2.5 修改stm32f1xx_it.c文件

在stm32f1xx_it.c会生成SysTick,PendSV和SVC这3个中断服务函数,这3个中断服务函数已经在FreeRTOS中使用,会造成重复编译,所以我们要屏蔽点这3个中断服务函数。然后编译。

你应该会报一个错误

.\stm32_freertos.axf: Error: L6218E: Undefined symbol xTaskGetCurrentTaskHandle (referred from stream_buffer.o).

解决办法是在FreeRTOS.h文件中的

#ifndef INCLUDE_xTaskGetCurrentTaskHandle
	#define INCLUDE_xTaskGetCurrentTaskHandle 1
#endif

把开始的0修改成1 这样就0警告0错误。

3.FreeRTOS移植验证

首先在main函数中包含FreeRTOS.h和task.h

#include "FreeRTOS.h"
#include "task.h"

3.1 编写测试任务函数

static TaskHandle_t LedTaskHandle = NULL;//任务句柄
//函数功能是让LED灯以1秒的间隔闪烁
//形参pvParameters是创建该任务是传递的参数
static void LedTask(void *pvParameters)
{
	while(1)
	{
		LED_ON();
		Delay_ms(1000);
		LED_off();
		Delay_ms(1000);
	}
}



//---------------------------LED函数---------------------//
void LED_init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitTypeDef GPIO_InitStruvture;
	GPIO_InitStruvture.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStruvture.GPIO_Pin=GPIO_Pin_2;
	GPIO_InitStruvture.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruvture);	
	
	
	GPIO_SetBits(GPIOA,GPIO_Pin_2);

} 
void LED_ON(){

   GPIO_ResetBits(GPIOA,GPIO_Pin_2);

}
void LED_off(){

   GPIO_SetBits(GPIOA,GPIO_Pin_2);

}

3.1 创建一个任务

创建任务函数的原型

BaseType_t xTaskCreate(    TaskFunction_t pvTaskCode,
                            const char * const pcName,
                            configSTACK_DEPTH_TYPE usStackDepth,
                            void *pvParameters,
                            UBaseType_t uxPriority,
                            TaskHandle_t *pxCreatedTask
                          );

xTaskCreate(LedTask,"LedTask",128,NULL,4,&LedTaskHandle);

3.2 开启调度器

用vTaskStartScheduler()函数来开启调度器,正常情况下,函数不会执行到这语句的后面的代码。

int main(void)
{
	
	LED_init();
	xTaskCreate(LedTask,"LedTask",128,NULL,4,&LedTaskHandle);
	
	vTaskStartScheduler();
	//后面的while函数不会执行
	while(1)
	{	
	}	
}

3.3 下载测试

第一次下载程序可能LED不会闪烁,如何来排除问题的经验是很重要的,我们在开启任务调度的前面写一个打开灯的代码。

int main(void)
{
	
	LED_init();
	xTaskCreate(LedTask,"LedTask",128,NULL,4,&LedTaskHandle);
	LED_ON();
	vTaskStartScheduler();
	//后面的while函数不会执行
	while(1)
	{	
	}	
}

会发现灯亮了,这就说明是卡死在 vTaskStartScheduler();这句代码。然后我们带着问题去百度。发现是ARM Cortex-M3,ARM Cortex-M4和ARM Cortex-M4F上的移植需要FreeRTOS处理安装的SysTick,PendSV和SVCCall中断向量,中断向量表可以分别直接使用FreeRTOS定义的xPortSysTickHandler(),xPortPendSVHandler()和vPortSVCHandler()三个函数。但是,如果中断向量表是与CMSIS兼容的话,用户需在FreeRTOSConfig.h中添加以下三行代码以使FreeRTOS和CMSIS中中断向量名字做映射。

解决方案是:

将下面的代码放到FreeRTOSConfig.h

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


原文链接

下载后程序正是1秒的间隔闪烁,到此,FreeRTOS的移植完毕,后续将会继续编写有关FreeRTOS的小应用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值