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

【经验分享】STM32F407移植FreeRTOS步骤

[复制链接]
STMCU小助手 发布时间:2022-5-16 11:34
1、源码准备
       首先准备好我们下载好的FreeRTOS源码以及STM32F407的工程模板(这里以原子的F4跑马灯工程为例,可去原子的开源论坛自行下载),源码下载及参考请参考我的上一篇博客。

2、创建FreeRTOS文件夹
在工程中创建FreeRTOS文件夹,将FreeRTOS源码全部复制到该文件夹下

J4VG7F(R0KA[1L[S_4RKHKF.png

打开portable文件夹,删除没用的文件,留下如下文件即可

20190816170452609.png

3、在工程中添加FreeRTOS源码
打开工程,在工程中新建FreeRTOS_CORE和FreeRTOS_PORTABLE,然后向着两个组中添加对应的文件,如下图所示:

20190816170518369.png

       FreeRTOS_CORE的文件打开FreeRTOS就可看到,port.c是RVDS文件夹下的ARM_CM4F中的,因为STM32F407是Cortex-M4内核并且带FPU。Heap_4.c是MemMang文件夹中,这里有5个文件,是5个不同的内存管理方法,为什么选择第4个,因为FreeRTOS内存管理所决定。

4、添加对应的头文件路径

SU4[70TMSS9THQ_{YAT$)15.png

5、编译及错误解决

5.1 找不到FreeRTOSConfig.h文件
完成后编译一下,会出现如下错误

2019081617065397.png

       很明显是没有FreeRTOSConfig.h这个文件,那我们就把它添加进去,具体位置在FreeRTOS的DEMO中找到CORTEX_M4F_STM32F407ZG-SK文件,如下图所示

RB9(NYFTTB57AG]9}PD))0V.png

      至于放到哪个位置自己随意,一般是放在FreeRTOS的include里面,而这个文件是FreeRTOS的配置文件,一般操作系统都有裁剪、配置功能,而这些都是通过一个文件内的宏定义来完成。

5.2 SystemCoreClock未定义
接着上面的步骤再编译一次,还会出现以下错误,意思是SystemCoreClock未定义
20190816170815891.png

解决办法:修改条件编译

O({SZ$P%M[VB6]C}PA1WCJO.png

5.3 重复定义
接着再编译一下,发现还有错误,这次的错误是重复定义

20190816170906281.png

解决办法:

     屏蔽掉stm32f4xx_it.c中的PendSV_Handler(),SVC_Handler(),SysTick_Handler()这三个函数,

J1{J5FFPO6%)VS2$FL4RPO9.png

5.4 钩子函数未定义
     继续编译一次,还是会有错,这次的错是函数未定义,他们都是Hook结尾的,称为钩子函数。

20190816171003138.png

解决办法:

        去FreeRTOSConfig.h中关闭这些钩子函数,他们都是宏定义决定,这里将configUSE_IDLE_HOOK、configUSE_TICK_HOOK、configUSE_MALLOC_FAILED_HOOK和configUSE_FOR_STACK_OVERFLOW定义为0.

AD3PLMJQC][R4G94VZUK8[O.png

再编译一下应该就没错了。

6、修改SYSTEM文件
因为原子的SYSTEM文件夹是针对UCOS编写的,所以要进行对应的修改

6.1 修改sys.h文件
把宏定义改为1即可,要支持OS,UCOS也一样的

20190816171410738.png

6.2 修改usart.c文件
修改头文件为

20190816171442265.png

修改串口中断服务函数为:

}YRE3F87]$D8C8J4Z((9L5A.png

6.3 修改delay.c文件

同样先修改宏定义的头文件

20190816171540153.png

接着修改systick中断服务函数为

20190816171548315.png

在滴答定时器中断服务函数中调用FreeRTOS的API函数xPortSysTickHandler();

在修改delay_init()函数,如下:

TF[2BS{SWY0__(HLC0YUP.png

接下来就是延时函数的修改

TOZ(Y}6`9}UOCF))H}%(8_A.png

修改完后再编译一下,会出现重复定义的错误,如下图:

20190816171647173.png

解决办法:屏蔽FreeRTOSConfig.h掉底部的#define xPortSysTickHandler SysTick_Handler

C}N@EYXV4Q8[OGMY[CB4[KJ.png

7、修改main.c进行功能验证
主函数主要是实现实时系统多任务的创建,具体如下

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "FreeRTOS.h"
  6. #include "task.h"

  7. #define START_TASK_PRIO                        1
  8. #define START_STK_SIZE                        120
  9. void start_task(void * pvParameters);  //任务函数
  10. TaskHandle_t StartTask_Handler;                //任务句柄         


  11. #define TASK1_TASK_PRIO                        2
  12. #define TASK1_STK_SIZE                        120
  13. void task1_task(void * pvParameters);
  14. TaskHandle_t Task1Task_Handler;                //任务句柄         

  15. #define TASK2_TASK_PRIO                        3
  16. #define TASK2_STK_SIZE                        120
  17. void task2_task(void * pvParameters);
  18. TaskHandle_t Task2Task_Handler;                //任务句柄        

  19. int main(void)
  20. {
  21.                 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  22.                 delay_init(168);                //初始化延时函数
  23.     LED_Init();                     //初始化LED
  24.     uart_init(115200);              //初始化串口

  25.         xTaskCreate((TaskFunction_t        ) start_task,
  26.                                 (char*                        ) "start_task",
  27.                                 (uint16_t                ) START_STK_SIZE,
  28.                                 (void *                 ) NULL,
  29.                                 (UBaseType_t        ) START_TASK_PRIO,
  30.                                 (TaskHandle_t*        ) &StartTask_Handler);
  31.     vTaskStartScheduler();          //开启任务调度
  32. }

  33. void start_task(void * pvParameters)
  34. {
  35.         //创建Task1
  36.         xTaskCreate((TaskFunction_t        ) task1_task,
  37.                                 (char*                        ) "task1_task",
  38.                                 (uint16_t                ) TASK1_STK_SIZE,
  39.                                 (void *                 ) NULL,
  40.                                 (UBaseType_t        ) TASK1_TASK_PRIO,
  41.                                 (TaskHandle_t*        ) &Task1Task_Handler);
  42.                                 
  43.         //创建Task2
  44.         xTaskCreate((TaskFunction_t        ) task2_task,
  45.                                 (char*                        ) "task2_task",
  46.                                 (uint16_t                ) TASK1_STK_SIZE,
  47.                                 (void *                 ) NULL,
  48.                                 (UBaseType_t        ) TASK2_TASK_PRIO,
  49.                                 (TaskHandle_t*        ) &Task2Task_Handler);
  50.         vTaskDelete(StartTask_Handler); //NULL
  51. }

  52. void task1_task(void * pvParameters)
  53. {
  54.         char task1_num=0;
  55.         
  56.         while(1)
  57.         {
  58.                 task1_num++;
  59.                
  60.                 LED0 = ~LED0;
  61.                 printf("Task1 Runing %d !\r\n",task1_num);
  62.                
  63.                 vTaskDelay(1000);
  64.         }
  65. }

  66. void task2_task(void * pvParameters)
  67. {
  68.         char task2_num=0;
  69.         while(1)
  70.         {
  71.                 task2_num++;
  72.                
  73.                 LED1 = ~LED1;
  74.                 printf("Task2 Runing %d!\r\n",task2_num);
  75.                 vTaskDelay(500);
  76.         }
  77. }
复制代码

实验现象;

      开发板上LED0和LED1进行不同状态的闪烁,串口也会打印任务执行次数,很明显任务二的速度是任务一的两倍。

1VM2{H5BDGWPZL[[W@NP2)D.png

20190816171854468.png

我这里使用的是STM32F407VET6,原理都差不多,用那块板子都一样。至此,FreeRTOS移植和任务创建成功。



收藏 1 评论0 发布时间:2022-5-16 11:34

举报

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