STM32
直播中

fdvcxhtg

8年用户 995经验值
擅长:嵌入式技术
私信 关注
[问答]

教你怎样一步一步移植FreeRTOS系统呢

怎样去移植FreeRTOS系统呢?有哪些基本步骤?FreeRTOS系统有哪些作用?

回帖(1)

王山崎

2021-10-27 10:16:49
  在玩32板子的时候,碰到一些好几个任务同时工作的工程时,有必要在系统上运行,而轻便高效且易移植的小型系统中,freertos无疑是最好的选择。下面,就来一步一步移植freeRTOS系统吧。
  首先下载freertos系统,目前的版本是v10.2.1。对于移植来说,只有FreeRTOS中的文件是有用的,但也并不是全部需要。
  源码中的文件结构如下:
  
  Demon:适配各个平台的模板工程,需要CORTEX_STM32F103_Primer_GCC文件夹中的FreeRTOSConfig.h文件
  License:没用
  Soure:文件结构如下图
  
  文件中包括7个c文件,其中list.c、queue.c和tasks.c是每个工程都需要的文件,其他的建议都加上。
  include文件夹中包含了系统所需要的头文件
  portable文件夹中包含了不同平台的接口,需要其中的文件。注意:MemMang文件夹中是有关freertos系统内存的文件,这个不能删除。
  下面开始移植:
  以管理员身份运行keil并新建一个空白工程
  芯片选型见下图
  
  运行环境管理配置如下图
  
  拷贝stm32内核文件及标准外设文件
  在工程路径下创建CMSIS 、STM32F10x_StdPeriph_Driver和User三个文件夹
  CMSIS:将历程中有关文件拷贝到此文件夹中,还要拷贝stm32f10x_conf.h文件到此文件夹中。
  STM32F10x_StdPeriph_Driver:将有关外设的头文件和源码拷贝到此文件中
  User:创建main.c文件,拷贝
  在keil中添加CMSIS 、STM32F10x_StdPeriph_Driver和User三个组并添加第二步中添加的文件,工程结构图结果如下图所示:
  
  设置编译选项
  
  
  编译
  
  未报错,很好。
  拷贝freertos文件
  在工程路径下建立freeRTOS文件夹,将下载的freertos源文件中souurce-》include 和一些c文件拷贝到其中;
  将source-》portable-》RVDS-》ARM_CM3中对应的port.c和portmacro.h文件拷贝到其中。
  将source-》MemMang中heap_4.c文件拷贝到其中。
  将FreeRTOSv10.2.1FreeRTOSDemoCORTEX_STM32F107_GCC_Rowley的FreeRTOSConfig.h拷贝到include中。
  在keil工程中建立freeRTOS分组添加freeRTOS文件夹下所有c文件,并在编译路径中添加其头文件。如图:
  
  
  编译
  编译产生错误
  
  这是因为从源文件Demon中拷贝的FreeRTOSConfig.h文件未按照实际做修改的原因,要修改一下几点
  #define configUSE_TICK_HOOK 1 此处将1改为0
  #define configCPU_CLOCK_HZ ( ( unsigned long ) 62500000 ) 此处将62500000 改为72000000
  #define configCHECK_FOR_STACK_OVERFLOW 2 此处将2改为0
  然后编译,产生如下错误:
  
  解决这个问题,要在freeRTOS源文件中的tasks.c文件中添加关于ulRunTimeStatsClock的定义,在文件末添加一行代码即可
  
  编译,未出错。很好。
  修改stm32启动文件,因为freeRTOS系统的调度需要用到是stm32的中断,所以需要替换一些接口,具体如下图所示:
  
  新添加内容为:
  IMPORT xPortPendSVHandler
  IMPORT xPortSysTickHandler
  IMPORT vPortSVCHandler
  新替换内容为:
  DCD SVC_Handler -》 vPortSVCHandler
  DCD PendSV_Handler -》 xPortPendSVHandler
  DCD SysTick_Handler -》 xPortSysTickHandler
  修改文成后,重新编译此工程。
  
  编译,未出错。很好。
  至此移植过程已经结束,下面就是系统的应用了。
  freeRTOS应用实例:
  系统中运行三个任务,简单的使用串口打印task_i2c 、 task_can、 task_uart。
  主函数如下:
  #include “stm32f10x.h”
  #include “FreeRTOS.h”
  #include “task.h”
  #include “main.h”
  #include “uart.h”
  #define START_TASK_PRIO ((unsigned portBASE_TYPE)2U)
  #define START_STK_SIZE 32
  xTaskHandle StartTask_Handler;
  #define I2C_TASK_PRIO ((unsigned portBASE_TYPE)3U)
  #define I2C_STK_SIZE 64
  xTaskHandle i2cTask_Handler;
  #define CAN_TASK_PRIO ((unsigned portBASE_TYPE)3U)
  #define CAN_STK_SIZE 64
  xTaskHandle canTask_Handler;
  #define UART_TASK_PRIO ((unsigned portBASE_TYPE)3U)
  #define UART_STK_SIZE 64
  xTaskHandle uartTask_Handler;
  void task_i2c(void)
  {
  while(1)
  {
  printf(“rn task_i2c rn”);
  vTaskDelay(100);
  }
  }
  void task_can(void)
  {
  while(1)
  {
  printf(“rn task_can rn”);
  vTaskDelay(100);
  }
  }
  void task_uart(void)
  {
  while(1)
  {
  printf(“rn task_uart rn”);
  vTaskDelay(100);
  }
  }
  void vStartTaskCreate(void *pvParameters)
  {
  taskENTER_CRITICAL();
  xTaskCreate((TaskFunction_t)task_i2c, (const char *)“task_i2c”, I2C_STK_SIZE, (void *)NULL, I2C_TASK_PRIO, (xTaskHandle *)i2cTask_Handler);
  xTaskCreate((TaskFunction_t)task_can, (const char *)“task_can”, CAN_STK_SIZE, (void *)NULL, CAN_TASK_PRIO, (xTaskHandle *)canTask_Handler);
  xTaskCreate((TaskFunction_t)task_uart, (const char *)“task_uart”, UART_STK_SIZE, (void *)NULL, UART_TASK_PRIO, (xTaskHandle *)uartTask_Handler);
  vTaskDelete(StartTask_Handler);
  taskEXIT_CRITICAL();
  }
  int main(void)
  {
  SystemInit();
  uartInit();
  printf(“rn uartInit() ok!!! rn”);
  xTaskCreate((pdTASK_CODE)vStartTaskCreate, (const char *)“vStartTaskCreate”,
  (uint16_t)START_STK_SIZE, (void *)NULL, (portTickType)START_TASK_PRIO,
  (xTaskHandle *)&StartTask_Handler);
  vTaskStartScheduler();
  while(1);
  }
  烧进板子后,运行结果如下图所示:
  
  系统可调度执行不同的任务。
举报

更多回帖

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