当前位置:   article > 正文

基于STM32103移植FreeRTOS_stm32f10x rtos移植

stm32f10x rtos移植

目录

一、FreeRTOS协议栈下载

二、准备工程文件与协议代码

三、移植FreeRTOS协议栈


一、FreeRTOS协议栈下载

1、官网下载

FreeRTOS - Market leading RTOS (Real Time Operating System) for embedded systems with Internet of Things extensionshttps://www.freertos.org/zh-cn-cmn-s/

2、网盘下载(访问密码:1666)

二、准备工程文件与协议代码

三、移植FreeRTOS协议栈

(FreeRTOS协议栈内容请自行百度,此处只是应用)

1、将\FreeRTOSv202212.00\FreeRTOS\Source内协议代码均复制到工程文件内新建文件夹“FreeRTOS”中

2、根据需求,删除 FreeRTOS\portable 内多余文件(也可不删,只为了精简工程文件的大小),最后保留文件如下

  • Keil:基于Keil使用的底层接口文件,指向RVDS
  • MemMang:内存管理选择
  • RVDS:底层接口文件需要实际修改的文件
  • readme:内核的基本介绍

3、在工程内添加协议栈

核心文件:

来源于 FreeRTOSv202212.00\FreeRTOS\Source 的C文件

底层接口:

  • port:来源于 FreeRTOSv202212.00\FreeRTOS\Source\portable\RVDS\ARM_CM3
  • heap_4:来源于 FreeRTOSv202212.00\FreeRTOS\Source\portable\MemMang

4、编译

报错:缺失文件 "FreeRTOSConfig.h"

5、补充文件

从例程中直接复制 "FreeRTOSConfig.h" 使用

6、重复编译

编译通过,移植完成。

四、示例演示

1、要实际使用FreeRTOS,需要提供滴答计时器作为OS系统刷新中断

  1. #include "HW_SysTick_Interrupt.h"
  2. #include "stm32f10x.h"
  3. #include "FreeRTOS.h" //os 使用
  4. #include "task.h"
  5. extern void xPortSysTickHandler(void);
  6. static u8 fac_us=0; //us延时倍乘数
  7. static u16 fac_ms=0; //ms延时倍乘数,在ucos下,代表每个节拍的ms数
  8. /* 功 能: 滴答定时器 - 初始化
  9. * 输 入:
  10. * 输 出:
  11. * 返 回:
  12. * 备 注: 此处启用中断版本,故默认使用 1/1000 = 1ms 中断
  13. */
  14. void HW_SysTick_Interrupt_Init(void)
  15. {
  16. u32 reload;
  17. SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); //选择外部时钟 HCLK/8
  18. fac_us=SystemCoreClock/1000000; //为系统时钟的1/8
  19. reload=SystemCoreClock/1000000; //每秒钟的计数次数 单位为K
  20. reload*=1000000/configTICK_RATE_HZ; //根据delay_ostickspersec设定溢出时间
  21. //reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右
  22. fac_ms=1000/configTICK_RATE_HZ; //代表OS可以延时的最少单位
  23. SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断
  24. SysTick->LOAD=reload; //每1/delay_ostickspersec秒中断一次
  25. SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
  26. }
  27. ///* 功 能: 滴答定时 - 中断
  28. // * 输 入:
  29. // * 输 出:
  30. // * 返 回:
  31. // * 备 注: OS初始化中断1000Hz
  32. // */
  33. //void HW_SysTick_Interrupt_Handler(void)
  34. //{
  35. // if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)
  36. // {
  37. // xPortSysTickHandler();
  38. // }
  39. //}
  40. /* 功 能: 延时nus
  41. * 输 入:
  42. * 输 出:
  43. * 返 回:
  44. * 备 注:
  45. */
  46. void delay_us(u32 nus)
  47. {
  48. u32 ticks;
  49. u32 told,tnow,tcnt=0;
  50. u32 reload=SysTick->LOAD; //LOAD的值
  51. ticks=nus*fac_us; //需要的节拍数
  52. told=SysTick->VAL; //刚进入时的计数器值
  53. while(1)
  54. {
  55. tnow=SysTick->VAL;
  56. if(tnow!=told)
  57. {
  58. if(tnow<told)tcnt+=told-tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了.
  59. else tcnt+=reload-tnow+told;
  60. told=tnow;
  61. if(tcnt>=ticks)break; //时间超过/等于要延迟的时间,则退出.
  62. }
  63. };
  64. }
  65. /* 功 能: 延时nms
  66. * 输 入:
  67. * 输 出:
  68. * 返 回:
  69. * 备 注:
  70. */
  71. void delay_ms(u16 nms)
  72. {
  73. if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED) //如果OS已经在跑了,并且不是在中断里面(中断里面不能任务调度)
  74. {
  75. if(nms>=fac_ms) //延时的时间大于OS的最少时间周期
  76. {
  77. vTaskDelay(nms/fac_ms); //OS延时
  78. }
  79. nms%=fac_ms; //OS已经无法提供这么小的延时了,采用普通方式延时
  80. }
  81. delay_us((u32)(nms*1000)); //普通方式延时
  82. }
  83. /* 功 能: 延时nms
  84. * 输 入:
  85. * 输 出:
  86. * 返 回:
  87. * 备 注: 此处启用中断版本,故默认使用 1/1000 = 1ms 中断
  88. */
  89. void delay_xms(u32 nms)
  90. {
  91. u32 i;
  92. for(i = 0;i < nms;i++)
  93. delay_us(1000);
  94. }

编译报警

需要开启(置一)

再次编译正常

2、main函数中创建开始任务 start_task

3、开始任务(start_task)中创建其他任务

4、执行其他任务

5、设置头文件,以及配置好任务参数后,编译通过。

6、实际运行后,在 vTaskStartScheduler (开启任务调度) -> xPortStartScheduler (开启时钟) -> prvStartFirstTask (开启第一个任务) 中跳到 HardFault_Handler(硬件错误)

7、排查错误

为中断异常导致的,FreeRTOS 使用的中断如下,需要修改中断

8、修改中断方法

①、修改启动文件,直接映射到port文件中

②宏定义

需要删除 stm32f10x_it 中的中断入口,避免二定义

9、编译运行后,预期正常

项目代码(访问密码:1666)


 

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号