你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32的FreeRTOS学习之FreeRTOS移植(二)

[复制链接]
STMCU小助手 发布时间:2022-11-17 17:37
1. 准备工作
1)FreeRTOS源码(选择所需要的即可)。

2. FreeRTOS移植
2.1 添加FreeRTOS源码
在案例文件夹中新建一个FreeRTOS文件夹,以后将FreeRTOS的源码添加至该文件夹里。根据前一章的知识点,portable文件夹里只需留下keil、MemMang和RVDS三个文件夹,其余都可以删除。
20210311230409275.png

2.2 在工程分组中添加文件
打开案例工程,新建分组FreeRTOS_CORE和FreeRTOS_PORTABLE,然后添加文件。 FreeRTOS_PORTABLE分组中,port.c是RVDS文件夹下ARM_CM3中的文件;heap_4.c是MemMang文件夹里的。MemMang文件夹里有heap_1.c、heap_2.c、heap_3.c、heap_4.c和heap_5.c,表示五种不同的内存管理方法。

20210311230557444.png

2.3 添加头文件路径
如下图所示添加头文件路径:

20210311230718207.png

头文件路径添加完成后编译一下,有如下错误,提示打不开“FreeRTOSConfig.h”。
这个文件可以在FreeRTOSv9.0.0–>FreeRTOS–>Demo–>CORTEX_STM32F103_Keil文件里找到。

3. 修改SYSTEM文件夹里的文件
SYSTEM文件夹里有三个文件:sys、delay和usart三个源文件和头文件,这是正点原子团队开发的,但不仅限于战舰v3开发板。

3.1 修改sys.h文件
sys.h文件里面用宏SYSTEM_SUPPORT_OS来定义是否使用OS,具体代码如下:

  1. #define SYSTEM_SUPPORT_OS   1 // 定义系统文件夹是否支持OS,0,不支持;1,支持
复制代码

3.2 修改usart.c文件
usart.c文件有两个修改地方:
一是添加FreeRTOS.h头文件:

  1. #if SYSTEM_SUPPORT_OS
  2. #include "FreeRTOS.h"
  3. #endif
复制代码

二是USART1的中断服务函数:

  1. void USART1_IRQHandler(void)
  2. {
  3.         u8 Res
  4.         if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
  5.         {
  6.                 Res=USART_ReceiveData(USART1);
  7.                 if((USART_RX_STA&0x8000)==0)   // 接收未完成
  8.                 {
  9.                         if(USART_RX_STA&0x4000)    // 接收到 0x0d
  10.                         {
  11.                                 if(Res!=0x0a) USART_RX_STA=0;
  12.                                 else USART_RX_STA |= 0x8000;
  13.                         }
  14.                         else // 还没接收到0x0d
  15.                         {
  16.                                 if(Res==0x0d) USART_RX_STA |= 0x4000;
  17.                                 else
  18.                                 {
  19.                                         USART_RX_BUF[USART_RX_STA&0x3FFF]=Res;
  20.                                         USART_RX_STA++;
  21.                                         if(USART_RX_STA>(USART_REC_LEN-1)) USART_RX_STA=0;
  22.                                 }
  23.                         }
  24.                 }
  25.         }
  26. }
复制代码

3.3 修改delay.c文件
delay.c文件修改地方比较多,因为涉及FreeRTOS系统时钟:
1)SysTick_Handler()函数

  1. extern void xPortSysTickHandler(void); // systick 中断服务函数,使用OS时用到
  2. void SysTick_Handler(void)
  3. {
  4.         if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED) // 系统已经运行
  5.         {        xPortSysTickHandler();        }
  6. }
复制代码

FreeRTOS的心跳是由滴答定时器产生的,根据FreeRTOS的系统时钟节拍设置好滴答定时器的周期,就会周期触发滴答定时器中断。其滴答定时器中断服务函数中调用FreeRTOS的API函数xPortSysTickHandler()。

2)delay_init()函数

  1. void delay_init()
  2. {
  3.         u32 reload;
  4.         SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);  // 选择外部时钟HCLK
  5.         fac_us=SystemCoreClock/1000000;
  6.         reload=SystemCoreClock/1000000;      // 每秒钟的计数次数,单位M
  7.         reload*=1000000/configTICK_RATE_HZ;  // 根据configTICK_RATE_HZ设定溢出时间reload为24位寄存器,
  8.                                              // 最大值:16777216,在72M下,约0.233s左右
  9.         fac_ms=1000/configTICK_RATE_HZ;      // 代表OS可以延时的最少单位
  10.         SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; // 开启SYSTICK中断
  11.         SysTick->LOAD=reload;                // 每1/configTICK_RATE_HZ秒中断一次
  12.         SysTick->CTRL|=SysTick_CRTL_ENABLE_Msk;  // 开启SYSTICK
  13. }
复制代码

delay_init()用来初始化滴答定时器和延时函数,根据FreeRTOS的系统时钟节拍初始化滴答定时器,其节拍由configTICK_RATE_HZ来设置,其值可自由设置。
接来下是三个延迟函数:

  1. void delay_us(u32 nus)
  2. {
  3.         u32 ticks;
  4.         u32 told,tnow,tcnt=0;
  5.         u32 reload=SysTick->LOAD;   // LOAD的值
  6.         ticks=nus*fac_us;
  7.         told=SysTick->VAL;          // 刚进入时的计数器值
  8.         while(1)
  9.         {
  10.                 tnow=SysTick->VAL;
  11.                 if(tnow!=told)
  12.                 {        // 这里注意SYSTICK是一个递减的计数器
  13.                         if(tnow<told) tcnt+=told-tnow;
  14.                         else tcnt+=reload-tnow+old;
  15.                         told=tnow;
  16.                         if(tcnt>=ticks) break;  // 超时
  17.                 }
  18.         };
  19. }

  20. void delay_ms(u32 nms)
  21. {
  22.         if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)  // 系统已经运行
  23.         {
  24.                 if(nms>=fac_ms)        {  vTaskDelay(nms/fac_ms);        }
  25.                 nms%=fac_ms;   // OS已经无法提供这么小的延时了,采用普通方式延时
  26.         }
  27.         delay_us((u32)(nms*1000));
  28. }

  29. void delay_xms(u32 nms)
  30. {
  31.         u32 i;
  32.         for(i=0;i<nms;i++) delay_us(1000);
  33. }
复制代码

delay_us()和delay_xms()不会导致任务切换。delay_ms()是对FreeRTOS中延时函数vTaskDelay()的简单封装,所以在使用delay_ms()时会导致任务切换。
delay.c修改后编译一下,如有错误提示在port.c、delay.c和stm32f10x_it.c中三个重复定义的函数:SysTick_Handler()、SVC_Handler()和PendSV_Handler(),这三个函数分别为滴答定时器中断服务函数、SVC中断服务函数和PendSV中断服务函数。可在stm32f10x_it.c中将这三个函数注释掉。

20210311231109847.png

至此,SYSTEM文件夹修改完成。
————————————————
版权声明:天亮继续睡


收藏 评论0 发布时间:2022-11-17 17:37

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版