STM32
直播中

美信电子

13年用户 415经验值
擅长:射频微波与天线
私信 关注
[问答]

如何使用STM32F407去移植FreeRTOS呢

如何使用STM32F407去移植FreeRTOS呢?有哪些操作步骤?

回帖(1)

周灿金

2021-10-21 17:23:08
  1、源码准备
  首先准备好我们下载好的FreeRTOS源码以及STM32F407的工程模板(这里以原子的F4跑马灯工程为例,可去原子的开源论坛自行下载),源码下载及参考请参考我的上一篇博客。
  2、创建FreeRTOS文件夹
  在工程中创建FreeRTOS文件夹,将FreeRTOS源码全部复制到该文件夹下
  
  打开portable文件夹,删除没用的文件,留下如下文件即可
  
  3、在工程中添加FreeRTOS源码
  打开工程,在工程中新建FreeRTOS_CORE和FreeRTOS_PORTABLE,然后向着两个组中添加对应的文件,如下图所示:
  
  FreeRTOS_CORE的文件打开FreeRTOS就可看到,port.c是RVDS文件夹下的ARM_CM4F中的,因为STM32F407是Cortex-M4内核并且带FPU。Heap_4.c是MemMang文件夹中,这里有5个文件,是5个不同的内存管理方法,为什么选择第4个,因为FreeRTOS内存管理所决定。
  4、添加对应的头文件路径
  
  5、编译及错误解决
  5.1 找不到FreeRTOSConfig.h文件
  完成后编译一下,会出现如下错误
  
  很明显是没有FreeRTOSConfig.h这个文件,那我们就把它添加进去,具体位置在FreeRTOS的DEMO中找到CORTEX_M4F_STM32F407ZG-SK文件,如下图所示
  
  至于放到哪个位置自己随意,一般是放在FreeRTOS的include里面,而这个文件是FreeRTOS的配置文件,一般操作系统都有裁剪、配置功能,而这些都是通过一个文件内的宏定义来完成。
  5.2 SystemCoreClock未定义
  接着上面的步骤再编译一次,还会出现以下错误,意思是SystemCoreClock未定义
  
  解决办法:修改条件编译
  
  5.3 重复定义
  接着再编译一下,发现还有错误,这次的错误是重复定义
  
  解决办法:
  屏蔽掉stm32f4xx_it.c中的PendSV_Handler(),SVC_Handler(),SysTick_Handler()这三个函数,
  
  5.4 钩子函数未定义
  继续编译一次,还是会有错,这次的错是函数未定义,他们都是Hook结尾的,称为钩子函数。
  
  解决办法:
  去FreeRTOSConfig.h中关闭这些钩子函数,他们都是宏定义决定,这里将configUSE_IDLE_HOOK、configUSE_TICK_HOOK、configUSE_MALLOC_FAILED_HOOK和configUSE_FOR_STACK_OVERFLOW定义为0.
  
  再编译一下应该就没错了。
  6、修改SYSTEM文件
  因为原子的SYSTEM文件夹是针对UCOS编写的,所以要进行对应的修改
  6.1 修改sys.h文件
  把宏定义改为1即可,要支持OS,UCOS也一样的
  
  6.2 修改usart.c文件
  修改头文件为
  
  修改串口中断服务函数为:
  
  6.3 修改delay.c文件
  同样先修改宏定义的头文件
  
  接着修改systick中断服务函数为
  
  在滴答定时器中断服务函数中调用FreeRTOS的API函数xPortSysTickHandler();
  在修改delay_init()函数,如下:
  
  接下来就是延时函数的修改
  
  修改完后再编译一下,会出现重复定义的错误,如下图:
  
  解决办法:屏蔽FreeRTOSConfig.h掉底部的#define xPortSysTickHandler SysTick_Handler
  
  7、修改main.c进行功能验证
  主函数主要是实现实时系统多任务的创建,具体如下
  #include “sys.h”
  #include “delay.h”
  #include “usart.h”
  #include “led.h”
  #include “FreeRTOS.h”
  #include “task.h”
  #define START_TASK_PRIO 1
  #define START_STK_SIZE 120
  void start_task(void * pvParameters); //任务函数
  TaskHandle_t StartTask_Handler; //任务句柄
  #define TASK1_TASK_PRIO 2
  #define TASK1_STK_SIZE 120
  void task1_task(void * pvParameters);
  TaskHandle_t Task1Task_Handler; //任务句柄
  #define TASK2_TASK_PRIO 3
  #define TASK2_STK_SIZE 120
  void task2_task(void * pvParameters);
  TaskHandle_t Task2Task_Handler; //任务句柄
  int main(void)
  {
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  delay_init(168); //初始化延时函数
  LED_Init(); //初始化LED
  uart_init(115200); //初始化串口
  xTaskCreate((TaskFunction_t ) start_task,
  (char* ) “start_task”,
  (uint16_t ) START_STK_SIZE,
  (void * ) NULL,
  (UBaseType_t ) START_TASK_PRIO,
  (TaskHandle_t* ) &StartTask_Handler);
  vTaskStartScheduler(); //开启任务调度
  }
  void start_task(void * pvParameters)
  {
  //创建Task1
  xTaskCreate((TaskFunction_t ) task1_task,
  (char* ) “task1_task”,
  (uint16_t ) TASK1_STK_SIZE,
  (void * ) NULL,
  (UBaseType_t ) TASK1_TASK_PRIO,
  (TaskHandle_t* ) &Task1Task_Handler);
  //创建Task2
  xTaskCreate((TaskFunction_t ) task2_task,
  (char* ) “task2_task”,
  (uint16_t ) TASK1_STK_SIZE,
  (void * ) NULL,
  (UBaseType_t ) TASK2_TASK_PRIO,
  (TaskHandle_t* ) &Task2Task_Handler);
  vTaskDelete(StartTask_Handler); //NULL
  }
  void task1_task(void * pvParameters)
  {
  char task1_num=0;
  while(1)
  {
  task1_num++;
  LED0 = ~LED0;
  printf(“Task1 Runing %d !rn”,task1_num);
  vTaskDelay(1000);
  }
  }
  void task2_task(void * pvParameters)
  {
  char task2_num=0;
  while(1)
  {
  task2_num++;
  LED1 = ~LED1;
  printf(“Task2 Runing %d!rn”,task2_num);
  vTaskDelay(500);
  }
  }
  实验现象;
  开发板上LED0和LED1进行不同状态的闪烁,串口也会打印任务执行次数,很明显任务二的速度是任务一的两倍。
  
  我这里使用的是STM32F407VET6,原理都差不多,用那块板子都一样。至此,FreeRTOS移植和任务创建成功。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分