当前位置:   article > 正文

手动移植FreeRTOS到STM32_freertos移植到stm32

freertos移植到stm32

        前言:这只是一篇FreeRTOS入门的文章,用于自己忘记的时候回看复习。本文是采用CubeMX生成的STM32F407的基础工程后来进行移植的。

一、FreeRTOS简介

1.什么是实时操作系统

        实时操作系统(Real-time operating system, RTOS),又称即时操作系统,它会按照排序运行、管理系统资源,并为开发应用程序提供一致的基础。实时操作系统与一般的操作系统相比,最大的特色就是“实时性”,如果有一个任务需要执行,实时操作系统会马上(在较短时间内)执行该任务,不会有较长的延时。这种特性保证了各个任务的及时执行。实时操作系统中都要包含一个实时任务调度器,这个任务调度器与其它操作系统的最大不同是强调:严格按照优先级来分配CPU时间,并且时间片轮转不是实时调度器的一个必选项。

2.FreeRTOS功能

        FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要。

二、FreeRTOS源码下载

        首先我们先去到FreeRTOS的官网:FreeRTOS - 市场领先的 RTOS(实时操作系统),适用于具有物联网扩展的嵌入式系统

        官网页面如下,点击 "下载FreeRTOS" 。

        在弹出的界面中我们点击第二个LTS版本的下载,第二个是长期维护的版本。

        进去后选择git和zip方式下载都可以,写博客的时候打不开网站就不贴图了。

        和我一样没法打开网站的可以用我下面这个网盘的链接下载:

链接:https://pan.baidu.com/s/1_7HMV8de3_wIyXlptGKudw?pwd=hyun 
提取码:hyun

三、CubeMX配置工程

        注意:FreeRTOS中使用的时钟源是STM32的SysTick定时器,它用来实现我们的任务切换,所以在CubeMX配置的时候我们需要将Timebase Source的时钟源改成其他定时器,如下图,我改成了TIM2。

1.时基源配置

2.GPIO配置

        我的开发板实物PA0-PA3连接的是按键,设置为输入,PB12-PB15连接的是LED的阴极,配置为推挽输出,这样就可以生成工程了(配置时钟树,调试那些没贴图了)。

四、移植FreeRTOS

1.创建FreeRTOS文件夹

        如下图所示,在前面CubeMX生成的工程文件夹下创建一个application文件夹和一个middlewares文件夹,前者用来存放测试源文件,后者用来存放FreeRTOS文件。

2.将FreeRTOS源码添加到工程

        前面下载的FreeRTOS源码的压缩包解压如下:

        打开上图中的FreeRTOS文件夹如下图所示,我们只需将其中的FreeRTOS-Kernel文件夹复制到工程的02_middlewares文件夹下即可。其他文件夹都不需要,就可以打开工程了。

3.创建FreeRTOS工程组

        如下图,在工程中创建两个新的组,只在middlewares/FreeRTOS组中加入以下6个源文件,各源文件在工程中的位置见后图。

        在FreeRTOS-Kernel文件夹下就有其中四个

        因为我使用的是F4系列的,所以是ARM_CM4F文件夹,如果使用的是F103C8T6那就是ARM_CM3文件夹,以此类推。

        还有MemMang文件夹下的heap_4.c,据说heap4比较好用一些。

4.设置头文件路径

        keil主页点击魔术棒进入如下对话框添加三个路径

5.创建一个FreeRTOSConfig.h
5.1创建一个空的头文件

        因为在压缩包中没有FreeRTOSConfig.h文件,但FreeRTOS的源文件又引用了这个头文件,所以我们要先创建一个FreeRTOSConfig.h,不然编译会报找不到FreeRTOSConfig.h的错误

        如下图,我们先在FreeRTOS-Kernel文件夹下创建一个空的FreeRTOSConfig.h头文件,然后在keil中将它打开。

5.2复制官网的FreeRTOSConfig.h

        下图中FreeRTOSConfig.h的内容没有截完,去官网复制的时候复制到#endif /*FREERTOS_CONFIG_H */即可,即将下图中框住的整个头文件都复制到刚刚新建的FreeRTOSConfig.h中

        复制过来后还需简单的修改几个地方,我的改好的FreeRTOSConfig.h如下,F407是可以正常使用的,其他型号单片机可能还需自己修改才能使用,文件中具体每个宏定义是干什么用,大家可以看看官网的FreeRTOSConfig.h,上图的那些蓝字都是可以点击进去看详细说明的。完成这一步就可以直接编译了

  1. #ifndef FREERTOS_CONFIG_H
  2. #define FREERTOS_CONFIG_H
  3. /* Here is a good place to include header files that are required across
  4. your application. */
  5. #include "stm32f4xx_hal.h"
  6. #define configUSE_PREEMPTION 1
  7. #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
  8. #define configUSE_TICKLESS_IDLE 0
  9. #define configCPU_CLOCK_HZ (SystemCoreClock)
  10. #define configTICK_RATE_HZ 1000
  11. #define configMAX_PRIORITIES 5
  12. #define configMINIMAL_STACK_SIZE 128
  13. #define configMAX_TASK_NAME_LEN 16
  14. #define configUSE_16_BIT_TICKS 0
  15. #define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_32_BITS
  16. #define configIDLE_SHOULD_YIELD 1
  17. #define configUSE_TASK_NOTIFICATIONS 1
  18. #define configTASK_NOTIFICATION_ARRAY_ENTRIES 3
  19. #define configUSE_MUTEXES 0
  20. #define configUSE_RECURSIVE_MUTEXES 0
  21. #define configUSE_COUNTING_SEMAPHORES 1
  22. #define configUSE_ALTERNATIVE_API 0 /* Deprecated! */
  23. #define configQUEUE_REGISTRY_SIZE 10
  24. #define configUSE_QUEUE_SETS 0
  25. #define configUSE_TIME_SLICING 0
  26. #define configUSE_NEWLIB_REENTRANT 0
  27. #define configENABLE_BACKWARD_COMPATIBILITY 0
  28. #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
  29. #define configUSE_MINI_LIST_ITEM 1
  30. #define configSTACK_DEPTH_TYPE uint16_t
  31. #define configMESSAGE_BUFFER_LENGTH_TYPE size_t
  32. #define configHEAP_CLEAR_MEMORY_ON_FREE 1
  33. #define configUSE_APPLICATION_TASK_TAG 0
  34. #define configSTATS_BUFFER_MAX_LENGTH 0xFFFF
  35. /* Memory allocation related definitions. */
  36. #define configSUPPORT_STATIC_ALLOCATION 0
  37. #define configSUPPORT_DYNAMIC_ALLOCATION 1
  38. #define configKERNEL_PROVIDED_STATIC_MEMORY 1
  39. #define configTOTAL_HEAP_SIZE 81920
  40. #define configAPPLICATION_ALLOCATED_HEAP 0
  41. #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
  42. #define configENABLE_HEAP_PROTECTOR 1
  43. /* Hook function related definitions. */
  44. #define configUSE_IDLE_HOOK 0
  45. #define configUSE_TICK_HOOK 0
  46. #define configCHECK_FOR_STACK_OVERFLOW 0
  47. #define configUSE_MALLOC_FAILED_HOOK 0
  48. #define configUSE_DAEMON_TASK_STARTUP_HOOK 0
  49. #define configUSE_SB_COMPLETED_CALLBACK 0
  50. /* Run time and task stats gathering related definitions. */
  51. #define configGENERATE_RUN_TIME_STATS 0
  52. #define configUSE_TRACE_FACILITY 0
  53. #define configUSE_STATS_FORMATTING_FUNCTIONS 0
  54. /* Co-routine related definitions. */
  55. #define configUSE_CO_ROUTINES 0
  56. #define configMAX_CO_ROUTINE_PRIORITIES 1
  57. /* Software timer related definitions. */
  58. #define configUSE_TIMERS 1
  59. #define configTIMER_TASK_PRIORITY 3
  60. #define configTIMER_QUEUE_LENGTH 10
  61. #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
  62. /* Interrupt nesting behaviour configuration. */
  63. #define configKERNEL_INTERRUPT_PRIORITY 16
  64. #define configMAX_SYSCALL_INTERRUPT_PRIORITY 15
  65. #define configMAX_API_CALL_INTERRUPT_PRIORITY 15
  66. /* Define to trap errors during development. */
  67. //#define configASSERT( ( x ) ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
  68. /* FreeRTOS MPU specific definitions. */
  69. #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
  70. #define configTOTAL_MPU_REGIONS 8 /* Default value. */
  71. #define configTEX_S_C_B_FLASH 0x07UL /* Default value. */
  72. #define configTEX_S_C_B_SRAM 0x07UL /* Default value. */
  73. #define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 1
  74. #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
  75. #define configENABLE_ERRATA_837070_WORKAROUND 1
  76. #define configUSE_MPU_WRAPPERS_V1 0
  77. #define configPROTECTED_KERNEL_OBJECT_POOL_SIZE 10
  78. #define configSYSTEM_CALL_STACK_SIZE 128
  79. #define configENABLE_ACCESS_CONTROL_LIST 1
  80. /* ARMv8-M secure side port related definitions. */
  81. #define secureconfigMAX_SECURE_CONTEXTS 5
  82. /* Optional functions - most linkers will remove unused functions anyway. */
  83. #define INCLUDE_vTaskPrioritySet 1
  84. #define INCLUDE_uxTaskPriorityGet 1
  85. #define INCLUDE_vTaskDelete 1
  86. #define INCLUDE_vTaskSuspend 1
  87. #define INCLUDE_xResumeFromISR 1
  88. #define INCLUDE_vTaskDelayUntil 1
  89. #define INCLUDE_vTaskDelay 1
  90. #define INCLUDE_xTaskGetSchedulerState 1
  91. #define INCLUDE_xTaskGetCurrentTaskHandle 1
  92. #define INCLUDE_uxTaskGetStackHighWaterMark 0
  93. #define INCLUDE_uxTaskGetStackHighWaterMark2 0
  94. #define INCLUDE_xTaskGetIdleTaskHandle 0
  95. #define INCLUDE_eTaskGetState 0
  96. #define INCLUDE_xEventGroupSetBitFromISR 1
  97. #define INCLUDE_xTimerPendFunctionCall 0
  98. #define INCLUDE_xTaskAbortDelay 0
  99. #define INCLUDE_xTaskGetHandle 1
  100. #define INCLUDE_xTaskResumeFromISR 1
  101. /* A header file that defines trace macro can be included here. */
  102. #define vPortSVCHandler SVC_Handler
  103. #define xPortPendSVHandler PendSV_Handler
  104. #define xPortSysTickHandler SysTick_Handler
  105. #endif /* FREERTOS_CONFIG_H */
6.解决编译报错

        下述报错信息是说我们有三个函数重定义了,需要我们去stm32f4xx_it.c中找到这三个函数并在函数前用__weak修饰,(这里就说明如果我们再次使用CubeMX重新生成这个工程的话,那每生成一次都需要去stm32f4xx_it.c给这三个函数加__weak),加了__weak之后再次编译

        如下图,就没有报错了,可以写一些最简单的任务了

7.写测试程序

        在一开始创建的01_application文件夹下创建一个测试的源文件rtos_test.c,并将它添加到01_application工程组里,再将函数rtos_test在main函数中声明和调用就可以实现两个LED同步闪烁了,在我的开发板上实现成功了

  1. #include "gpio.h"
  2. #include "main.h"
  3. #include "FreeRTOS.h"
  4. #include "task.h"
  5. #include "timers.h"
  6. /* 任务函数需要是void task(void *arg)类型的 */
  7. static void task1(void *arg)
  8. {
  9. for( ; ; )
  10. {
  11. HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_12);
  12. vTaskDelay(500);
  13. }
  14. }
  15. static void task2(void *arg)
  16. {
  17. for( ; ; )
  18. {
  19. HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_13);
  20. vTaskDelay(500);
  21. }
  22. }
  23. void rtos_test(void)
  24. {
  25. xTaskCreate(task1,"Task1",128,NULL,1,NULL);//创建任务1
  26. xTaskCreate(task2,"Task2",128,NULL,1,NULL);//创建任务2
  27. vTaskStartScheduler();//启动任务调度器
  28. }

        本文只是快速的移植FreeRTOS,FreeRTOS更多的内容还需大家慢慢去了解和深入

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

闽ICP备14008679号