FreeRTOS学习(1)——FreeRTOS移植

为什么要让你的单片机裸奔?

什么是FreeRTOS?

首先看到两个概念:

  1. RTOS:实时操作系统,目前主流的嵌入式操作系统有:UCOS、FreeRTOS、LWIP、EMWIN、RT-Thread 等
  2. FreeRTOS:FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要

也许在百度百科截取的这段解释不够接地气,通俗的解释就是更加有序的管理单片机的各个任务功能执行。

为什么要学习FreeRTOS?

采用嵌入式实时操作系统(RTOS)可以更合理、更有效地利用CPU的资源,简化应用软件的设计,缩短系统开发时间,更好地保证系统的实时性和可靠性

通常我们在写单片机程序的时候,都是将许多功能写成一个一个的函数,然后写在main函数中的while(1)里,与中断进行配合实现系统功能。这种情况就叫做前后台系统,通常也称之为——裸奔。但是加上了RTOS之后就是穿上了实时操作系统的衣服,更加合理,更加高级。

这里有一个关于竹林七贤之一——刘伶的故事:
有人去拜访刘伶,适逢他喝醉了酒,一丝不挂地在屋里乱晃,不禁讥讽道:“你也是礼教之人,如此行径成何体统?”刘伶一听,颇不以为然地反唇相讥:“我以天地为房屋,以房屋为衣裳,你怎么跑到我裤子里来权了?”客人听了瞠目结舌,无言以对。
从上可以看出,穿衣与否并不是评判是否成体统的标志,影射到单片机上也是一样,不是加了操作系统就一定优于裸机开发,还要视具体情况而定。

在stm32上的移植

首先是到FreeRTOS官网下载移植文件:官网地址外国网站可能有点慢
下载好之后是一个exe文件:

在这里插入图片描述点击就会生成一个文件夹:FreeRTOS学习(1)——FreeRTOS移植_第1张图片
进到FreeRTOS->Source,里面放的就是移植需要的文件
FreeRTOS学习(1)——FreeRTOS移植_第2张图片
然后打开一个stm32工程
在stm32工程中添加一个FreeRTOS文件夹
将Source里面的文件都复制过去,也就是上图文件
把portable文件夹里除了keil、MemMang 和 RVDS三个文件全部删除,因为用不到
向工程中添加分组FreeRTOS_CORE、FreeRTOS_PORTABLE,添加文件,添加路径
FreeRTOS学习(1)——FreeRTOS移植_第3张图片
编译一次会发现少了FreeRTOSCongif.h这个文件,我们可以从官方下载的例程中去添加这个文件到FreeRTOS的include目录下

具体过程

修改SYSTEM文件夹

修改sys.h文件

#define SYSTEM_SUPPORT_OS		0	
****************************************************************
//修改为:
#define SYSTEM_SUPPORT_OS		1		//支持操作系统	

修改usart.c文件
第一处:

#if SYSTEM_SUPPORT_OS
#include "includes.h"				 
#endif
****************************************************************
//修改为:
#if SYSTEM_SUPPORT_OS
#include "FreeRTOS.h" 		//os 使用 
#endif

第二处:将OSIntEnter()和 OSIntExit()删除掉

void USART1_IRQHandler(void)                	
	{
	u8 Res;
#if SYSTEM_SUPPORT_OS 		
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
		{
		Res =USART_ReceiveData(USART1);	
		
		if((USART_RX_STA&0x8000)==0)
			{
			if(USART_RX_STA&0x4000)
				{
				if(Res!=0x0a)USART_RX_STA=0;
				else USART_RX_STA|=0x8000;	
				}
			else 
				{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
					{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;  
					}		 
				}
			}   		 
     } 
#if SYSTEM_SUPPORT_OS 
	OSIntExit();  											 
#endif
} 
****************************************************************
//修改为:
void USART1_IRQHandler(void)                	
{
	u8 Res;

	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 
		{
		Res =USART_ReceiveData(USART1);	
		
		if((USART_RX_STA&0x8000)==0)
			{
			if(USART_RX_STA&0x4000)
				{
				if(Res!=0x0a)USART_RX_STA=0;
				else USART_RX_STA|=0x8000;	
				}
			else 
				{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
					{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;
					}		 
				}
			}   		 
     } 
} 

修改delay.c文件,这里有点多直接替换成下面的代码即可

#include "delay.h"
#include "sys.h"

#if SYSTEM_SUPPORT_OS
#include "FreeRTOS.h"						  
#include "task.h" 
#endif

static u8  fac_us=0;								   
static u16 fac_ms=0;						
 
extern void xPortSysTickHandler(void);

void SysTick_Handler(void)
{	
    if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)
        xPortSysTickHandler();	
    }
}
			   
void delay_init()
{
	u32 reload;
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
	fac_us=SystemCoreClock/1000000;				
	reload=SystemCoreClock/1000000;				
	reload*=1000000/configTICK_RATE_HZ;			
												
	fac_ms=1000/configTICK_RATE_HZ;			

	SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;   	
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;   	   
}								    

								   
void delay_us(u32 nus)
{		
	u32 ticks;
	u32 told,tnow,tcnt=0;
	u32 reload=SysTick->LOAD;				  	 
	ticks=nus*fac_us; 						 
	told=SysTick->VAL;        			
	while(1)
	{
		tnow=SysTick->VAL;	
		if(tnow!=told)
		{	    
			if(tnow<told)tcnt+=told-tnow;	
			else tcnt+=reload-tnow+told;	    
			told=tnow;
			if(tcnt>=ticks)break;			
		}  
	};										    
}  

void delay_ms(u32 nms)
{	
	if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)
	{		
		if(nms>=fac_ms)						
		{ 
   			vTaskDelay(nms/fac_ms);	 		
		}
		nms%=fac_ms;						
	}
	delay_us((u32)(nms*1000));				
}

void delay_xms(u32 nms)
{
	u32 i;
	for(i=0;i<nms;i++) delay_us(1000);
}

最后就是将stm32f10x_it.c里面的这三个中断服务函数屏蔽
FreeRTOS学习(1)——FreeRTOS移植_第4张图片
这样就完成了FreeRTOS的移植,当然在这里还是要感谢正点原子出的教程,我是站在巨人的肩膀上,才能看得更远。

在实际的工程中,我们直接使用原子的模板就好了,每次都自己移植有点费时间,只需要了解这么一个过程就好。

最后还是感谢嵌入式教育巨头——原子哥。
你看的到吗,原子哥?

你可能感兴趣的:(FreeRTOS)