FreeRTOS系统移植教程

前言

            本文主要讲解如何将FreeRTOS实时操作系统移植到STM32单片机中,在本文之前已经基于MDK集成开发环境移植了stm32标准库并新建工程模板,如果您阅读本文之前没有该工程或者相关stm32工程,您可以参考https://blog.csdn.net/muchong123/article/details/85220778进行工程创建,然后继续本文的阅读。后续文章将更新对FreeRTOS工作原理的讲解。阅读过程中如有不正确或者有疑问的地方欢迎评论区留言!

一、FreeRTOS源码下载及移植

 1、本文移植的版本为FreeRTOSv9.0.0,如果您还未有该版本,可以参考以下链接进行下载。https://sourceforge.net/projects/freertos/files/FreeRTOS/

2、解压下载的压缩包可以看到里面主要有两个文件夹及几个网页,我们移植时只用到FreeRTOS文件夹里的文件。

                           

3、进入FreeRTOS目录将Source目录里所有文件拷贝到上篇文章里所创建的工程里的FREERTOS文件夹里,如下图所示

对于里面的文件如何使用及工作原理后续文章将会详细讲解,在这里主要就先讲解如何移植到我们的stm32工程。

4、打开MDK工程,新建FREERTOS分组并将源文件添加进分组如下图所示。在这里需要注意的是portable目录里的文件是跟平台相关的,我们添加进portable\RVDS\ARM_CM3\port.c,在portable目录里还有一个MemMang文件夹,里面主要是跟内存管理相关的,在这里我们选用heap_4.c。

                           

5、添加头文件如下图所示

                            

6、经过上面的步骤后可以开始编译了,编译结果如下图所示,从编译结果看是缺少了 "FreeRTOSConfig.h"头文件,从文件名称里可以看出这个头文件里的内容主要是一些配置信息,但从刚刚复制的Source的源码里并没有找到该头文件,在这里我们可以从FreeRTOSv9.0.0\FreeRTOS\Demo\CORTEX_STM32F103_Keil里把FreeRTOSConfig.h拷贝到我们工程的FREERTOS\include里,然后重新编译,发现编译通过了。

7、开始写我们的main.c,这里可以参考以下LED灯代码,之后进行编译然后烧录进stm32单片机里,发现LED灯并没有闪烁。

#include "stm32f10x.h"
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"
 /********************************************************
  函数名:void LED_Init(void)
  功能描述:灯端口初始化
  被调用函数清单:
  调用本函数清单:
  被访问的表:
  被修改的表:
  输入参数:
  输出参数:
  返回值:
  其它说明:
********************************************************/
void LED_Init(void)
{
 
 GPIO_InitTypeDef  GPIO_InitStructure;
 	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);	 //使能PE端口时钟
	
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;				 //LED-->PE.5 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
 GPIO_Init(GPIOE, &GPIO_InitStructure);	  				 //推挽输出 ,IO口速度为50MHz
 GPIO_SetBits(GPIOE,GPIO_Pin_5); 						 //PE.5 输出高 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;	    		 //LED-->PE.5 端口配置, 推挽输出
}
/********************************************************
  函数名:void vTaskLED(void * pvParameters)
  功能描述:灯闪烁
  被调用函数清单:
  调用本函数清单:
  被访问的表:
  被修改的表:
  输入参数:void * pvParameters =NULL
  输出参数:
  返回值:
  其它说明:
********************************************************/
void vTaskLED(void * pvParameters)
{ 
	portTickType xLastWakeTime; 
	
	xLastWakeTime = xTaskGetTickCount(); 
	while(1)
	{
		GPIOE->ODR ^= GPIO_Pin_5;
		vTaskDelayUntil( &xLastWakeTime, ( 250 / portTICK_RATE_MS ) ); 
  }
} 

/********************************************************
  函数名:int main( void )
  功能描述:主函数
  被调用函数清单:
  调用本函数清单:
  被访问的表:
  被修改的表:
  输入参数:
  输出参数:
  返回值:
  其它说明:
********************************************************/
int main( void ) 
{ 
	/*串口初始化*/
	LED_Init();
	
	xTaskCreate(vTaskLED, "LED", 128, NULL, 3, NULL);
	
  /* 启动调度器,创建的任务得到执行。 */ 
    vTaskStartScheduler(); 

  /* 如果一切正常,main()函数不应该会执行到这里。但如果执行到这里,很可能是内存堆空间不足导致空闲
  任务无法创建。第五章将提供更多关于内存管理方面的信息 */ 
  while(1);//for( ;; ) 
}

8、上面之所以LED没有闪烁主要是FreeRTOS封装了自己的中断服务函数接口,因此需要替换掉启动文件startup_stm32f10x_hd.s里三个中断向量SVC_Handler、PendSV_Handler、SysTick_Handler为vPortSVCHandler、xPortPendSVHandler、xPortSysTickHandler,如下图所示,然后重新编译并烧录进单片机,发现LED灯闪烁了。

          最后感谢您的阅读,如果阅读本文章过程中有疑惑或者文章有纰漏的地方欢迎评论区留言!

          本博客持续会更新相关文章,如有需要欢迎关注本博客!

发布了33 篇原创文章 · 获赞 7 · 访问量 8358

猜你喜欢

转载自blog.csdn.net/muchong123/article/details/85223388
今日推荐