FreeRTOS移植

keil工程中新建FreeRTOS文件夹

 freertos源码文件里的sourse文件夹中的全部文件全部拷贝到第一步创建文件夹下

图中的protable文件夹下只留下以下三个文件夹

 KeilRVDS相当于一个文件夹,MemMang是内存管理相关,里面有五个heap.c文件

 

在移植时必须使用其中的一个,heap.c文件里是一些类似mallocfree函数的函数,freertos有自己的内存管理函数,它没有去使用c语言的库函数mallocfree等。因为FreeRTOS在创建对象的时候使用的是动态内存分配,而这些动态内存分配的函数则在这几个文件里面实现,不同的分配算法导致不同的效率和结果,一般用heap4.c

RVDS文件夹下是Cortex-M0M3M4M7等内核的单片机接口文件,根据使用的单片机内核选择对应的文件,这里选择M3内核(其他的可以删除),M3文件夹下有两个文件分别是port.c接口文件,portmacro.h头文件,主要是一些数据类型和宏定义

 

keil打开工程文件,点击所示图标新建两个分组FreeRTOS_COREFreeRTOS_PORTABLE然后向这两个分组中添加文件,如图添加相应的头文件路径,添加完FreeRTOS源码中的C文件以后还要添加FreeRTOS源码的头文件路径,头文件路径如图所示:

 拷贝FreeRTOSConfig.h文件到User文件夹,FreeRTOSConfig.hFreeRTOS的配置文件,他是freertos的核心,每个demo都必定含有FreeRTOSConfig.h

打开FreeRTOSv9.0.0源码,在“FreeRTOSv9.0.0\FreeRTOS\Demo”文件夹下面找到“CORTEX_STM32F103_Keil”这个文件夹,在其根目录下找到这个“FreeRTOSConfig.h”文件,然后拷贝到我们工程的User文件夹下即可

一般的操作系统都有裁剪、配置功能,而这些裁剪及配置都是通过一个文件来完成的,基本都是通过宏定义来完成对系统的配置和裁剪的。

该头文件对裁剪整个FreeRTOS所需的功能的宏均做了定义,里面的一堆宏主要分为两类,以config开头的宏多是与任务相关的参数、系统工作方式等相关,也有少部分与函数使能和除能相关,以INCLUDE为开头的宏几乎都是与函数使能失能相关的。一开始我们只需要配置最简单的功能即可。要想随心所欲的配置FreeRTOS的功能,必须对这些宏定义的功能有所掌握。

修改stm32f10x_it.c,注释掉SysTick_Handler函数PendSV_Handler函数与SVC_Handler函数

 FreeRTOS开发者已经帮我们实现了这三个中断函数,这三个函数非常很重要

修改sys.h文件,sys.h文件里面用宏SYSTEM_SUPPORT_OS来定义是否使用OS,我们使用了FreeRTOS,所以应该将宏SYSTEM_SUPPORT_OS改为1

 

修改usart.c文件,usart.c文件有两部分要修改,一个是添加FreeRTOS.h头文件,默认是添加的UCOS中的includes.h头文件,另外一个就是USART1的中断服务函数,在使用UCOS的时候进出中断的时候需要添加OSIntEnter()OSIntExit(),使用FreeRTOS的话就不需要了,所以将这两行代码删除掉,修改以后如下

 

 

修改delay.c文件,delay.c文件里面有5个函数的定义,分别是

 

SysTick_Handler函数是滴答定时器的中断服务函数,FreeRTOS的心跳就是由滴答定时器产生的,它使用定时器产生固定间隔的中断,它的任务是1.选择下一个要运行的任务,2.执行完中断处理函数后,切换到新的任务。两次中断之间的时间被称为时间片,时间片的长度由一个宏configTICK_RATE_HZ决定,假设configTICK_RATE_HZ100,那么时间片长度就是10ms,计算方法为1/100秒

delay_init()是用来初始化滴答定时器和延时函数。

delay_us()us级延时函数,delay_msdelay_xms()都是ms级的延时函数,delay_us()delay_xms()不会导致任务切换。delay_ms()其实就是对FreeRTOS中的延时函数vTaskDelay()的简单封装,所以在使用delay_ms()的时候就会导致任务切换。

以上五个函数的代码如下:

#include "delay.h"
#include "sys.h"
// 	 
//如果使用OS,则包括下面的头文件即可
#if SYSTEM_SUPPORT_OS
#include "FreeRTOS.h"					//FreeRTOS使用		  
#include "task.h"
#endif


static u8  fac_us=0;							//us延时倍乘数			   
static u16 fac_ms=0;							//ms延时倍乘数,在os下,代表每个节拍的ms数

 
extern void xPortSysTickHandler(void);
 
//systick中断服务函数,使用OS时用到
void SysTick_Handler(void)
{	
    if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
    {
        xPortSysTickHandler();	
    }
}
			   
//初始化延迟函数
//SYSTICK的时钟固定为AHB时钟,基础例程里面SYSTICK时钟频率为AHB/8
//这里为了兼容FreeRTOS,所以将SYSTICK的时钟频率改为AHB的频率!
//SYSCLK:系统时钟频率
void delay_init(u8 SYSCLK)
{
	u32 reload;
 	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); 
	fac_us=SYSCLK;							//不论是否使用OS,fac_us都需要使用
	reload=SYSCLK;							//每秒钟的计数次数 单位为M	   
	reload*=1000000/configTICK_RATE_HZ;		//根据delay_ostickspersec设定溢出时间
											//reload为24位寄存器,最大值:16777216,在168M下,约合0.0998s左右	
	fac_ms=1000/configTICK_RATE_HZ;			//代表OS可以延时的最少单位	   
	SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;//开启SYSTICK中断
	SysTick->LOAD=reload; 					//每1/configTICK_RATE_HZ断一次	
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK     
}								    

//延时nus
//nus:要延时的us数.	
//nus:0~204522252(最大值即2^32/fac_us@fac_us=168)	    								   
void delay_us(u32 nus)
{		
	u32 ticks;
	u32 told,tnow,tcnt=0;
	u32 reload=SysTick->LOAD;				//LOAD的值	    	 
	ticks=nus*fac_us; 						//需要的节拍数 
	told=SysTick->VAL;        				//刚进入时的计数器值
	while(1)
	{
		tnow=SysTick->VAL;	
		if(tnow!=told)
		{	    
			if(tnow<told)tcnt+=told-tnow;	//这里注意一下SYSTICK是一个递减的计数器就可以了.
			else tcnt+=reload-tnow+told;	    
			told=tnow;
			if(tcnt>=ticks)break;			//时间超过/等于要延迟的时间,则退出.
		}  
	};										    
}  
//延时nms
//nms:要延时的ms数
//nms:0~65535
void delay_ms(u32 nms)
{	
	if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
	{		
		if(nms>=fac_ms)						//延时的时间大于OS的最少时间周期 
		{ 
   			vTaskDelay(nms/fac_ms);	 		//FreeRTOS延时
		}
		nms%=fac_ms;						//OS已经无法提供这么小的延时了,采用普通方式延时    
	}
	delay_us((u32)(nms*1000));				//普通方式延时
}

//延时nms,不会引起任务调度
//nms:要延时的ms数
void delay_xms(u32 nms)
{
	u32 i;
	for(i=0;i<nms;i++) delay_us(1000);
}

 至此freertos的简单移植就差不多就完成了

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值