STM32之FreeRTOS移植

1.FreeRTOS的移植过程是将系统需要的文件和代码进行移植和裁剪,其移植的主要过程为:

(1)官网上下载FreeRTOS源码:https://www.freertos.org/

(2)移植文件夹,在portable文件夹中只需要保留:Keil、MemMang、RVDS。

(3)代码中的裁剪,修改相关的宏定义。

2.移植文件夹:

(1)首先在Keil的基本工程模板中创建一个文件夹FreeRTOS,用来存放FreeRTOS的源码:

(2)将如下三个文件夹导入到FreeRTOS目录下:

其中,Demo中存放的参考例程。License中是相关的许可信息。Source中便是FreeRTOS的源码。

(3)裁剪Source中的文件:

Source中的文件信息如下

portable中存放是FreeRTOS和硬件之间的接口桥梁,在portable中只需要保留如下三个文件夹即可。

MemMang中存放是内存管理相关的算法文件,本文选择heap_c.c。

RVDS和Keil中存放是软件和硬件之间的接口文件。本文的STM32是Coretex-M3系列,所以需要选择ARM_CM3。

3.创建工程文件:

在基础工程文件中创建两个如下两个文件夹用来存放FreeRTOS相关的文件:

添加文件:

4.导入头文件的路径:

5.移植FreeRTOSConfig.h文件:

FreeRTOSConfig.h是FreeRTOS的配置文件,通常FreeRTOS的裁剪都是通过修改此文件中的宏定义来实现。选择芯片序号和开发环境对应的文件:

将FreeRTOSConfig.h复制到自己的工程文件下,本文将FreeRTOSConfig.h放在include文件夹下:

6.代码裁剪:

(1)添加宏定义,将STM32的PendSV_Handler、SVC_Handler、SysTick_Handler映射到FreeRTOS中。在FreeRTOS中添加如下三个宏定义:

(2)注释stm32f10x_it.c中的SysTick_Handler()、SVC_Handler()和 PendSV_Handler()三个中断服务函数。因为在FreeRTOS中已经重新定义了这三个中断服务函数,所以此处需要注释,防止重复定义。

7.创建任务:

(1)led.c

cpp 复制代码
#include "led.h"

void LED_Init(void)
{
	//¶¨Òå¶Ë¿ÚµÄ½á¹¹Ìå:
	GPIO_InitTypeDef GPIO_InitStruct;
	
	//1.ʹÄÜʱÖÓ£º
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOA,ENABLE);
	
	//2.ÅäÖö˿ڽṹÌåµÄÏà¹ØÐÅÏ¢£º£¨LED1£©
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOD,&GPIO_InitStruct);
	
	//ÅäÖÃLED0£º
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//³õʼʱ½<<LEDµÄ¶Ë¿Ú¶¼ÖÃΪ1£¬¼´Ï¨Ãð
	GPIO_SetBits(GPIOA,GPIO_Pin_8);
	GPIO_SetBits(GPIOD,GPIO_Pin_2);
}

(2)main.c:

cpp 复制代码
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "FreeRTOS.h"
#include "task.h"

TaskHandle_t led0_handler;
TaskHandle_t led1_handler;

void led0(void)
{
	while(1)
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_8);			//´ò¿ªLED
		vTaskDelay(500);
		GPIO_SetBits(GPIOA,GPIO_Pin_8);			//´ò¿ªLED
		vTaskDelay(500);
	}
}

void led1(void)
{
	while(1)
	{
		GPIO_ResetBits(GPIOD,GPIO_Pin_2);			//´ò¿ªLED
		vTaskDelay(1000);
		GPIO_SetBits(GPIOD,GPIO_Pin_2);			//´ò¿ªLED
		vTaskDelay(1000);
	}
}

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// ÉèÖÃÖжÏÓÅÏȼ¶·Ö×é2
	LED_Init();
	
	/*´´½¨ÈÎÎñ*/
	xTaskCreate((TaskFunction_t) led0,				//ÈÎÎñº¯Êý
	(const char *)"led0_task",								//ÈÎÎñÃû³Æ
		(uint16_t)50,											      //ÈÎÎñ¶ÑÕ>>´óС
			(void *)NULL,													//´<<µÝ¸øÈÎÎñº¯ÊýµÄ²ÎÊý
				(UBaseType_t)1,											//ÈÎÎñÓÅÏȼ¶
			(TaskHandle_t *)&led0_handler);				//ÈÎÎñ¾ä±ú
	xTaskCreate((TaskFunction_t) led1,
	(const char *)"led1_task",
		(uint16_t)50,
			(void *)NULL,
				(UBaseType_t)1,
			(TaskHandle_t *)&led1_handler);
	vTaskStartScheduler();													//¿ªÊ¼ÈÎÎñµ÷¶È
}

8.运行结果:本文的运行结果是两个LED灯闪烁,其中led0每500ms闪烁一次,led1每1000ms闪烁一次。

9.总结:

FreeRTOS的移植过程主要是对相关的文件和代码进行裁剪。需要去了解每个文件夹中代码的大搞功能,才可以正确的移植文件。

此外,当使用xTaskGetSchedulerState()函数时,需要将FreeRTOS.h中的对应宏定义改为1:

相关推荐
远望创客学堂8 小时前
【单片机毕业设计选题24047】-基于阿里云的工地环境监测系统
stm32·单片机·嵌入式硬件·阿里云·云计算·课程设计·arduino
极客小张8 小时前
利用 STM32 实现多协议物联网网关:Modbus/Zigbee 到以太网/Wi-Fi 的数据桥接
stm32·单片机·嵌入式硬件·物联网·网络协议·https·硬件工程
XD74297163610 小时前
【TB作品】电子琴,ATMEGA16单片机,Proteus仿真
单片机·proteus·电子琴·atmega
maybe_YX10 小时前
51单片机基础8——单片机控制超声波模块
c语言·单片机·嵌入式硬件·51单片机
@一二三四五10 小时前
STM32 看门狗 HAL
stm32·单片机·嵌入式硬件
maybe_YX10 小时前
51单片机基础10——串口实验
c语言·单片机·嵌入式硬件·51单片机
Qingniu0111 小时前
开关电源的电路组成原理
单片机·嵌入式硬件·新能源·电源模块·无刷电机
芯源义码12 小时前
嵌入式软件常用测试工具
单片机
Gerrard yue14 小时前
arm (exti中断)
arm开发·单片机·嵌入式硬件
maybe_YX14 小时前
51单片机基础11——蓝牙模块控制亮灭
c语言·单片机·嵌入式硬件·51单片机