参照正点原子FreeRTOS视频教程和stm32f4 FreeRTOS开发指南,首次接触操作系统,做笔记方便回顾
如何移植
FreeRTOS的源码可于购买开发板后赠与的光盘内找到,路径:
A盘->软件资料->FreeRTOS学习资料->FreeRTOS源码,之后点击程序下载
移植步骤:
1.复制粘贴
于基础工程中新建一个文件夹,可命名为FreeRTOS。
2.打开之前下载好的源码文件,经过路径FreeRTOS->FreeRTOS->Source将内容(如图)复制进入新建的工程FreeRTOS文件。
为减少源码占用空间,portable文件夹中只留下keil,MemMang,RVDS文件夹,其余删除.
2.工程添加
于keil左侧工程文件界面新建两个文件夹 ,可命名FreeRTOS_CORE,FreeRTOS_PORTABLE
其中,FreeRTOS_CORE中添加工程文件夹FreeRTOS下所有文件(不包括include和portable文件夹),如图,总共六个文件。
FreeRTOS_PORTABLE添加portable文件下:1.MemMang文件夹中有heap1/2/3/4/5,分别是5种内存分配方法,各有千秋。视频里用的是heap4.c
2.RVDS->ARM-CM4F->下port.c文件
3.路径添加
按照上方将.c文件对应路径纳入头文件。
4.将非源码文件添加和解决其他编译问题
(1)从FreeRTOS的官方文件的Demo中可以找到对应的示例程序,把FreeRTOSconfig.h转移到已经新建的工程文件FreeRTOS中的include文件夹下,并将FreeRTOSconfig.h第87行代码改为:
```c
#if defined(_ICCARM_) || defined(__CC_ARM) || defined(_GNUC_)
(2)随后根据提示屏蔽重复定义函数,用的f407固定有三个中断可自定义函数会出问题:
在屏蔽之后又会闹腾一波,显示一些函数又没有定义,最后会有以下问题:
这里是因为在FreeRTOS.h中使能相关函数的宏定义置1,但是相关函数已经被注释掉从而产生冲突,此时需要将FreeRTOS.h文件中
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configUSE_MALLOC_FAILED_HOOK 1 //即所有HOOK宏定义
后边的1换为0即可。
(3)以上两步结束后会出现一个错误:
堆栈溢出HOOK函数相关未定义,和(2)中最后一步一样找到宏定义:
#define configCHECK_FOR_STACK_OVERFLOW 2
改为0即可
5.修改system文件
编译错误不代表已经可以用,需要进一步做以下工作:
1.修改sys.h文件(以下内容为完全照抄开发指南,不过复制更方便)
# define SYSTEM_SUPPORT_OS 0//由0改为1,表示对于OS支持使能,在sys.h第23行
2.修改usart.c文件
首先添加FreeRTOS.h头文件
#if SYSTEM_SUPPORT_OS
#include "FreeRTOS.h"
#endif
然后修改USART1的中断服务函数,在使用UCOS时进出中断需要添加 OSIntEnter()和OSIntExit();使用FreeRTOS则将其删去,也就是将usart.c中124到126行,150到152行删去。
3.修改delay.c文件
将delay.c中函数SysTick_Handler()修改如下:
extern void xPortSysTickHandler(void);
void SysTick_Handler(void)
{
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)
{
xPortSysTickHandler();//在滴答定时器中断服务函数调用API函数xPortSysHandler();
}
}
delay_init()修改如下:
void delay _init(u8 SYSCLK)
{
u32 reload;
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//SysTick频率为HCLK
fac_us=SYSCLK;
reload=SYSCLK;//每秒计数次数
reload*=1000000/configTICK_RATE_HZ;
fac_ms=1000/configTICK_RATE_HZ;
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;
SysTick->LOAD=reload;
SysTick->CTRL|=SysTick_CTR_ENABLE_Msk;
}
下边是修改后的延时函数
void delay_us(u32 nus)
{
u32 ticks;
u32 told,tnow,tcnt=0;
u32 reload=SysTick->LOAD;
ticks=nus*fac_us; //
delay_osschedlock(); //
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; //
}
};
delay_osschedunlock();
}
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);
}
在修改后编译显示SysTick_Handler()重复定义
,将FreeRTOSconfig.h中宏定义
#define xPortSysTickHandler SysTick_Handler
注释掉即可
到此,配置完毕
在实际情况中会出现除上述问题外的地方,比如delay.c中有多处和UCOS相关宏定义和函数,根据报错删去即可;如果出现找不到某个已宏定义的量的问题,则将相关头文件包含进去即可。