使用STM32CubeIDE 进行 FreeRTOS 手动移植F103系列最小系统


前言

FreeRTOS 是市场领先的面向微控制器和小型微处理器的实时操作系统 (RTOS),与世界领先的芯片公司合作开发,支持 40 多种架构。FreeRTOS 通过 MIT 开源许可免费分发,包括一个内核和一组不断丰富的 IoT 库,适用于所有行业领域。FreeRTOS 的构建强调可靠性和易用性。

本文主要是记录一下作者的开发踩坑日志~持续更新中...

开发环境

  • OS: MacOS Catalina
  • MCU: STM32f103c8t6
  • STM32CubeIDE + HAL + GCC
  • VSCODE + Embeded IDE + GCC
  • Keil + ArmV5

本文涉及到多种开发编译环境,参考学习请注意区分。

源码下载

一般主推的是 FreeRTOS V9.0 版本

开始移植

  1. 下载 FreeRTOS V9.0 源码
  2. 创建 STMCubeMX 裸机工程

    • 初始化 PC13 输出 - LED点灯
    • Systick: Tim2; (TimeBase 基准时钟)
  3. 移植FreeRTOS系统

    • STMCubeIDE打开创建的工程,新建目录 FreeRTOS
    • 将下载的 FreeRTOS 源码以下对应文件拷贝

      include.c 文件适用于各种编译器和处理器,是通用的; portable 是接口文件,通常由汇编和 C 联合编写适配硬件的相关内容,需要精简。
      • FreeRTOS/source/ 下的全部文件 -> 我们新建的项目 FreeRTOS 文件夹中
      • 精简 portable 文件夹

        • GCC环境保留: MemMang(内存管理相关)、GCCRVDS(编译器相关),其中内核选择CotrexM3(F103c8t6)
        • Keil环境保留: MemMangRVDS,Keil其实keil文件夹为空,内容同RVDS
        • 删减之后可以对比本节附图文件夹结构,确保没有遗漏
      • 增加 FreeRTOS 宏定义

        • 裁剪整个 FreeRTOS 所需的功能的宏,由于微处理器资源有限,适当裁剪可以发挥最大功效。
        • 源代码中 FreeRTOS/demo/ 中找 GCC 环境的工程例子

          • CORTEX_STM32F103_GCC_Rowley
          • CORTEX_STM32F103_Primer_GCC
          • 以上二选一即可,然后将其目录下的 FreeRTOSConfig.h 宏定义头文件复制到我们项目中 FreeRTOS/include/ 文件夹下
    • 添加编译选项

      • 选中项目 -> (右键)properties -> C/C++ General -> Paths and symbols
      • include path: 添加对应的 .h 头文件路径
      • Source location: 添加手动创建的 .c 文件路径
    • 编译解决报错

      • 新增宏定义 FreeRTOSConfig.h
      /* Suroy: fix some error */
      #define INCLUDE_xTaskGetCurrentTaskHandle 1
      #define xPortPendSVHandler PendSV_Handler
      #define xPortSysTickHandler SysTick_Handler
      #define vPortSVCHandler SVC_Handler
      
      
      // 以下是变更原配置参数,否则时钟拉起不了
      #define configUSE_PREEMPTION        1
      #define configUSE_IDLE_HOOK            0
      #define configUSE_TICK_HOOK            0 //Suroy: 启用报错,于是关了 22.2.8
      #define configCPU_CLOCK_HZ            ( ( unsigned long ) 72000000 )    
      #define configTICK_RATE_HZ            ( ( TickType_t ) 1000 )
      
      • 注释掉 stm32f1xx_it.c 文件中的 SysTick_Handler 函数,与FreeRTOS宏定义产生冲突
  4. 点亮一个LED频闪灯

以下均是对 main.c 主程序进行的更改


/* USER CODE BEGIN Includes */
#include "FreeRTOS.h"
#include "task.h"
/* USER CODE END Includes */

//任务1
void vTask1( void *pvParameters )
{
    for( ;; ) {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
        vTaskDelay(500);
//        HAL_Delay(500);
        HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
        vTaskDelay(500);
    }
}


// 任务2
void vTask2( void *pvParameters )
{
    for( ;; ) {
    }
}


int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();

  //创建任务1
  xTaskCreate(vTask1,"LED1",128,NULL,1,NULL);
  //创建任务2
  xTaskCreate(vTask2,"LED2",128,NULL,1,NULL);
  //启动任务调度器
  vTaskStartScheduler();

  while (1)
  {
    // 运行不到这里来
  }
}

工程源码

二选一下载

注意事项

  1. FreeRTOS 文件内容

    • 文件夹: FreeRTOS/portable 内容结构解析
    • 我们通常移植会保留三个该路径下的子文件夹 keilMemMangRVDS ,但是这里我踩坑发现其实 keil 文件夹下与 RVDS 文件夹下保留的内容其实作用一模一样的,均是 port.cportmacro.h 文件,那么是不是我们可以仅保留其一呢?
    • 经我测试在 CubeIDE (MacOS + gcc) 下仅保留 gccMemMang 是可行的!如果是Keil环境,请留意keil下是否有文件存在。
  2. 编译提示 undefined reference to xxx();

    • e.g. undefined reference to xTaskCreate
    • 该问题是由于C/C++编译器在处理.h头文件的引入时,并为添加相应的 .c 资源文件所致
    • 解决方法:

      • 选中项目 -> (右键)properties -> C/C++ General -> Paths and symbols
      • include path: 添加对应的 .h 头文件路径
      • Source location: 添加手动创建的 .c 文件路径
  3. sourceforge.net 下载速度慢

    • 挂代理是没有用的,其实速度慢的原因主要是因为官方自动给你选择了一个不知道是哪个偏远国家的下载节点。
    • 手动切换即可: 点击下载 -> 直接点击 Problems Download -> 选 Taiwan 或 Hongkong 或亚洲节点

声明:Grows towards sunlight |版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 使用STM32CubeIDE 进行 FreeRTOS 手动移植F103系列最小系统


Grows towards sunlight and Carpe Diem