当前位置:   article > 正文

FreeRTOS移植

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()的时候就会导致任务切换。

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

  1. #include "delay.h"
  2. #include "sys.h"
  3. //
  4. //如果使用OS,则包括下面的头文件即可
  5. #if SYSTEM_SUPPORT_OS
  6. #include "FreeRTOS.h" //FreeRTOS使用
  7. #include "task.h"
  8. #endif
  9. static u8 fac_us=0; //us延时倍乘数
  10. static u16 fac_ms=0; //ms延时倍乘数,在os下,代表每个节拍的ms数
  11. extern void xPortSysTickHandler(void);
  12. //systick中断服务函数,使用OS时用到
  13. void SysTick_Handler(void)
  14. {
  15. if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
  16. {
  17. xPortSysTickHandler();
  18. }
  19. }
  20. //初始化延迟函数
  21. //SYSTICK的时钟固定为AHB时钟,基础例程里面SYSTICK时钟频率为AHB/8
  22. //这里为了兼容FreeRTOS,所以将SYSTICK的时钟频率改为AHB的频率!
  23. //SYSCLK:系统时钟频率
  24. void delay_init(u8 SYSCLK)
  25. {
  26. u32 reload;
  27. SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
  28. fac_us=SYSCLK; //不论是否使用OS,fac_us都需要使用
  29. reload=SYSCLK; //每秒钟的计数次数 单位为M
  30. reload*=1000000/configTICK_RATE_HZ; //根据delay_ostickspersec设定溢出时间
  31. //reload为24位寄存器,最大值:16777216,在168M下,约合0.0998s左右
  32. fac_ms=1000/configTICK_RATE_HZ; //代表OS可以延时的最少单位
  33. SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;//开启SYSTICK中断
  34. SysTick->LOAD=reload; //1/configTICK_RATE_HZ断一次
  35. SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
  36. }
  37. //延时nus
  38. //nus:要延时的us数.
  39. //nus:0~204522252(最大值即2^32/fac_us@fac_us=168)
  40. void delay_us(u32 nus)
  41. {
  42. u32 ticks;
  43. u32 told,tnow,tcnt=0;
  44. u32 reload=SysTick->LOAD; //LOAD的值
  45. ticks=nus*fac_us; //需要的节拍数
  46. told=SysTick->VAL; //刚进入时的计数器值
  47. while(1)
  48. {
  49. tnow=SysTick->VAL;
  50. if(tnow!=told)
  51. {
  52. if(tnow<told)tcnt+=told-tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了.
  53. else tcnt+=reload-tnow+told;
  54. told=tnow;
  55. if(tcnt>=ticks)break; //时间超过/等于要延迟的时间,则退出.
  56. }
  57. };
  58. }
  59. //延时nms
  60. //nms:要延时的ms数
  61. //nms:0~65535
  62. void delay_ms(u32 nms)
  63. {
  64. if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
  65. {
  66. if(nms>=fac_ms) //延时的时间大于OS的最少时间周期
  67. {
  68. vTaskDelay(nms/fac_ms); //FreeRTOS延时
  69. }
  70. nms%=fac_ms; //OS已经无法提供这么小的延时了,采用普通方式延时
  71. }
  72. delay_us((u32)(nms*1000)); //普通方式延时
  73. }
  74. //延时nms,不会引起任务调度
  75. //nms:要延时的ms数
  76. void delay_xms(u32 nms)
  77. {
  78. u32 i;
  79. for(i=0;i<nms;i++) delay_us(1000);
  80. }

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/730338
推荐阅读
相关标签
  

闽ICP备14008679号