GD32移植FreeRTOS——CMake-GCC+Keil双版本

GD32移植FreeRTOS——CMake-GCC+Keil双版本

Github仓库:GD32_FreeRTOS_templete

概述

该模板包含CMake和Keil两种构建方式,在Project/Keil目录下有Keil的工程文件,根目录GD32_FreeRTOS_templete.code-workspace使vsCode的工作区文件,里面有推荐的插件。

关于用GCC和CMake构建GD32工程以前在GD32_CMake_Example记录过,之后应该会都合并到这个工程里。

版本

工程结构:

├─.vscode
├─bin
│  └─Debug
├─CMake
├─Doc
│  └─assets
├─Project
│  └─Keil
├─Scripts
│  └─openocd
├─Source
│  ├─BSP
│  │  ├─inc
│  │  └─src
│  ├─Config
│  ├─Core
│  ├─Drivers
│  │  ├─CMSIS
│  │  │  └─GD
│  │  │      └─GD32F3x0
│  │  │          ├─Include
│  │  │          └─Source
│  │  │              ├─ARM
│  │  │              ├─GNU
│  │  │              └─IAR
│  │  ├─GD32F3x0_standard_peripheral
│  │  │  ├─Include
│  │  │  └─Source
│  │  └─RTT
│  ├─Functions
│  ├─Middlewares
│  │  └─FreeRTOS
│  │      └─Source
│  │          ├─include
│  │          └─portable
│  │              ├─GCC
│  │              │  └─ARM_CM4F
│  │              ├─MemMang
│  │              └─RVDS
│  │                  └─ARM_CM4F
│  └─Retarget
│      ├─inc
│      └─src
└─Utilities

从零搭建这个工程

用GCC编译需要单独准备启动文件和链接脚本,GD官方的固件库里没有提供。

STM32的库里什么都有有,STM32Cube已经支持CMake了。

1.下载GD32固件库和FreeRTOS

FreeRTOS v202210.01-LTS

GD32 资料下载

2.移植固件库

下载下来的GD32固件库解压后目录结构如下:

├─Docs
├─Examples
├─Firmware
│  ├─CMSIS
│  ├─GD32F3x0_standard_peripheral
│  └─GD32F3x0_usbfs_library
├─Template
└─Utilities

我们只需要用到Firmware目录下的文件(该工程没用GD32F3x0_usbfs_library),粘贴到自己工程的目录里就行,我放在Source/Drivers下。

写一个GCC风格的启动文件startup_gd32f3x0.s

启动文件startup_gd32f3x0.s中,包含了复位服务函数Reset_Handler以及中断向量表。中断向量表存的就是中断处理函数的入口,这些函数的顺序使硬件设计决定的,数据手册有说明。我们写GCC风格的启动文件时一定要严格按照官方提供的ARM风格的启动文件来写,否则中断处理函数会乱掉。

3.移植FreeRTOS-Kernel

官方教程创建一个新的 FreeRTOS 项目
这个东西官方讲的很详细,Cortex-M等常见的架构的只要从官提供的文件中选择正确架构的文件就行了

除了portable需要挑选,其他全部复制
portable中需要选择MemMang[compiler]/[architecture]下的文件,比如我用的GD32F310F8P6时Cortex-M4架构的,编译器是GCC或者ARMClang选择portable/GCC/ARM_CM4F下的文件即可。

需要的FreeRTOS-Kernel的文件如下:

FreeRTOS
  │  CMakeLists.txt
  │
  └─Source
      │  CMakeLists.txt
      │  croutine.c
      │  event_groups.c
      │  GitHub-FreeRTOS-Kernel-Home.url
      │  History.txt
      │  LICENSE.md
      │  list.c
      │  manifest.yml
      │  queue.c
      │  Quick_Start_Guide.url
      │  README.md
      │  sbom.spdx
      │  stream_buffer.c
      │  tasks.c
      │  timers.c
      │
      ├─include
      │      atomic.h
      │      croutine.h
      │      deprecated_definitions.h
      │      event_groups.h
      │      FreeRTOS.h
      │      list.h
      │      message_buffer.h
      │      mpu_prototypes.h
      │      mpu_wrappers.h
      │      portable.h
      │      projdefs.h
      │      queue.h
      │      semphr.h
      │      StackMacros.h
      │      stack_macros.h
      │      stdint.readme
      │      stream_buffer.h
      │      task.h
      │      timers.h
      │
      └─portable
          │  CMakeLists.txt
          │
          ├─GCC
          │  └─ARM_CM4F
          │          port.c
          │          portmacro.h
          │
          ├─MemMang
          │      heap_4.c
          │
          └─RVDS
              └─ARM_CM4F
                      port.c
                      portmacro.h

4.准备一个链接脚本(GCC需要的,Keil跳过)

照抄STM32相同架构的链接脚本,然后改一下分区大小就行。

5a.编写CMakeLists

套娃一层一层写就行了,FreeRTOS比较独立,可以编译成静态库,其他全都用INTERFACE就行。比如

add_library(CMSIS INTERFACE
)

target_sources(CMSIS INTERFACE
	GD/GD32F3x0/Source/GNU/startup_gd32f3x0.s
	GD/GD32F3x0/Source/system_gd32f3x0.c
)

target_include_directories(CMSIS INTERFACE
	./GD/GD32F3x0/Include
	./
)

5b.Keil添加源文件,设置宏和路径

添加的宏如下:

GD32F310,PRINTF_INCLUDE_CONFIG_H

头文件路径如下:

..\..\Source\BSP\inc
..\..\Source\Config
..\..\Source\Core
..\..\Source\Drivers\CMSIS
..\..\Source\Drivers\CMSIS\GD\GD32F3x0\Include
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Include
..\..\Source\Drivers\RTT
..\..\Source\Middlewares\FreeRTOS\Source\include
..\..\Source\Middlewares\FreeRTOS\Source\portable\GCC\ARM_CM4F
..\..\Source\Retarget\inc
..\..\Source\BSP\inc;..\..\Source\Config;..\..\Source\Core;..\..\Source\Drivers\CMSIS;..\..\Source\Drivers\CMSIS\GD\GD32F3x0\Include;..\..\Source\Drivers\GD32F3x0_standard_peripheral\Include;..\..\Source\Drivers\RTT;..\..\Source\Middlewares\FreeRTOS\Source\include;..\..\Source\Middlewares\FreeRTOS\Source\portable\GCC\ARM_CM4F;..\..\Source\Retarget\inc

用到的源文件如下

..\..\Source\Core\freertos.c
..\..\Source\Core\gd32f3x0_it.c
..\..\Source\Core\main.c

..\..\Source\BSP\src\bsp_log.c
..\..\Source\BSP\src\bsp_systick.c
..\..\Source\BSP\src\bsp_timebase.c
..\..\Source\BSP\src\bsp_uart.c

..\..\Source\Drivers\CMSIS\GD\GD32F3x0\Source\ARM\startup_gd32f3x0.s
..\..\Source\Drivers\CMSIS\GD\GD32F3x0\Source\system_gd32f3x0.c

..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_adc.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_cec.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_cmp.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_crc.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_ctc.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_dac.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_dbg.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_dma.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_exti.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_fmc.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_fwdgt.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_gpio.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_i2c.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_misc.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_pmu.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_rcu.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_rtc.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_spi.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_syscfg.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_timer.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_tsi.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_usart.c
..\..\Source\Drivers\GD32F3x0_standard_peripheral\Source\gd32f3x0_wwdgt.c

..\..\Source\Drivers\RTT\SEGGER_RTT.c
..\..\Source\Drivers\RTT\SEGGER_RTT_printf.c

..\..\Source\Middlewares\FreeRTOS\Source\croutine.c
..\..\Source\Middlewares\FreeRTOS\Source\event_groups.c
..\..\Source\Middlewares\FreeRTOS\Source\list.c
..\..\Source\Middlewares\FreeRTOS\Source\queue.c
..\..\Source\Middlewares\FreeRTOS\Source\stream_buffer.c
..\..\Source\Middlewares\FreeRTOS\Source\tasks.c
..\..\Source\Middlewares\FreeRTOS\Source\timers.c
..\..\Source\Middlewares\FreeRTOS\Source\portable\MemMang\heap_4.c
..\..\Source\Middlewares\FreeRTOS\Source\portable\GCC\ARM_CM4F\port.c

..\..\Source\Retarget\src\printf.c
..\..\Source\Retarget\src\scanf.c

注意事项

FreeRTOS有三个关键的中断函数

  • SysTick_Handler: 时钟驱动,用于节拍计数,定时任务调度,延迟等
  • SVC_Handler: 用于初始化FreeRTOS并启动第一个任务。
  • PendSV_Handler: 用于在任务调度过程中执行任务上下文切换,确保正确的任务在正确的时间运行。

三个函数在port.c中分别以xPortSysTickHandlervPortSVCHandlerxPortPendSVHandler命名。
也就是说这三个函数默认是要手动调用的,但是可以在FreeRTOSConfig.h中用宏重命名三个函数,直接用中断向量表中的名字命名,就不需要手动调用了(当然你也可以去改中断向量表)。官方的原文如下 FreeRTOS常见问题:我的应用程序没有运行,可能出了什么问题?

针对 ARM Cortex-M 用户的特别提示: ARM Cortex-M3、ARM Cortex-M4 和 ARM Cortex-M4F 端口要求 FreeRTOS 处理程序 安装在 SysTick、 PendSV 和 SVCCall 中断向量上。 可以 将 FreeRTOS 定义的 xPortSysTickHandler(), xPortPendSVHandler() 和 vPortSVCHandler() 函数直接填入向量表的对应位置,或者如果 中断向量表与 CMSIS 相容,可以将以下三行 添加到 FreeRTOSConfig.h,用于将 FreeRTOS 函数名称映射到 其对应的 CMSIS 名称。

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

以这种方式使用 #defines 的前提是, 您的开发工具提供的默认处理程序 被定义为弱符号。 如果默认处理程序没有被定义为弱符号, 则需要将其注释掉或删除。

  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值