资讯动态

RT-Thread CH32F10X 系列 BSP 移植指南:从工程骨架到驱动适配

发布时间:2026/9/29 2:45:41 来源:尧图企业网站定制
操作系统嵌入式物联网嵌入式OSRTOS【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址https://gitcode.com/gh_mirrors/rt/rt-thread点击查看免费下载本篇指南基于 RT-Thread 仓库bsp/wch/arm下的 CH32F10x 移植实践围绕 ch32f10x_port_cn.md 的完整移植流程展开先理清 BSP 工程结构与已适配驱动清单再以 ch32f103c8-core 为范例逐步讲解 MDK 工程模板创建、board/Kconfig配置编写、board.h/board.c接口声明与实现并结合仓库源码验证驱动使能链路。读完本文你将掌握为任意 CH32F10x 系列芯片新建 RT-Thread BSP 的完整方法并理解厂商标准外设库与 RT-Thread 设备框架之间的桥接方式。1 工程结构BSP、厂商库与适配驱动三层划分在 bsp/wch/arm 目录下CH32F10x 系列的移植代码按职责分为四块wch/arm/ch32f103c8-core # 移植到具体芯片的 BSP wch/arm/libraries # 厂商驱动库 RT-Thread 适配驱动 wch/arm/libraries/ch32_drivers # 适配 RT-Thread 设备框架的驱动 wch/arm/libraries/CH32F10x_StdPeriph_Driver # WCH 厂商标准外设库CMSIS StdPeriph_Driver wch/arm/tools # ENV 环境下 scons --dist 依赖工具sdk_dist.pych32f103c8-core以具体芯片CH32F103C8为对象的板级支持包包含applications用户应用与main.c、board板级初始化、链接脚本、Kconfig 配置以及 MDK 工程文件libraries/CH32F10x_StdPeriph_DriverWCH 提供的标准外设驱动库目录内含CMSIS/WCH/CH32F10x核心头文件、系统初始化与启动文件以及StdPeriph_Driver/inc、StdPeriph_Driver/srcGPIO、USART、SPI、I2C、TIM、RTC、IWDG 等外设驱动libraries/ch32_drivers将厂商库封装为 RT-Thread 设备框架驱动的适配层例如drv_gpio_ch32f10x.c、drv_uart_ch32f10x.c、drv_spi_ch32f10x.c、drv_hwi2c_ch32f10x.c、drv_pwm_ch32f10x.c、drv_timer_ch32f10x.c、drv_iwdt_ch32f10x.c、drv_rtc_ch32f10x.c等toolsENV 环境下执行scons --dist分发 BSP 时所需的依赖工具。分层设计的好处在于厂商库和适配驱动libraries与具体芯片无关、可跨多个 BSP 复用每个具体 BSP 只需在board层提供时钟、引脚等板级差异化实现即可完成移植。2 已适配 RT-Thread 的驱动ch32_driverslibraries/ch32_drivers目前支持的驱动、对应宏开关以及驱动要求 board 层实现的接口如下表驱动功能宏开关外设选择宏board 层需实现的接口GPIORT_USING_PIN——UART 1/2/3RT_USING_SERIALBSP_USING_UART1/2/3父开关BSP_USING_UARTvoid ch32f1_usart_clock_and_io_init(USART_TypeDef* usartx);SPI 1/2RT_USING_SPIBSP_USING_SPI1/2父开关BSP_USING_SPIvoid ch32f1_spi_clock_and_io_init(SPI_TypeDef* spix);rt_uint32_t ch32f1_spi_clock_get(SPI_TypeDef* spix);I2C硬件1/2RT_USING_I2CBSP_USING_HWI2C1/2父开关BSP_USING_HWI2Cvoid ch32f1_i2c_clock_and_io_init(I2C_TypeDef* i2cx);void ch32f1_i2c_config(I2C_TypeDef* i2cx);WDTRT_USING_WDTBSP_USING_IWDT另需LSI_VALUE—RTCRT_USING_RTCBSP_USING_RTC可选BSP_USING_RTC_LSI使用 LSI 时钟否则默认 LSE另需LSI_VALUE—CLOCK_TIMER 1/2/3/4RT_USING_CLOCK_TIMEBSP_USING_TIM1/2/3/4_CLOCK_TIMER父开关BSP_USING_CLOCK_TIMERvoid ch32f1_tim_clock_init(TIM_TypeDef *timx);rt_uint32_t ch32f1_tim_clock_get(TIM_TypeDef *timx);struct rt_clock_timer_info* ch32f1_clock_timer_info_config_get(TIM_TypeDef *timx);PWM 4(timer) × 4(channel)RT_USING_PWMBSP_USING_TIM1/2/3/4_PWM_CH1~CH4父开关BSP_USING_PWMvoid ch32f1_pwm_io_init(TIM_TypeDef *timx, rt_uint8_t channel);其中 PWM 与 CLOCK_TIMER 共用 TIM1TIM4 定时器资源二者是同一定时器的两种工作模式详见 ch32f103c8-core/board/Kconfig 中的choice配置因此 PWM 驱动还依赖定时器相关接口void ch32f1_tim_clock_init(TIM_TypeDef *timx); rt_uint32_t ch32f1_tim_clock_get(TIM_TypeDef *timx);从源码看这些接口正是适配驱动与 board 层之间的“契约”适配驱动只负责调用 RT-Thread 设备框架的注册与读写逻辑而具体的外设时钟使能、GPIO 复用引脚配置等芯片相关细节全部下沉到 board 层实现。以串口为例board.c 中ch32f1_usart_clock_and_io_init完成了每个 USART 的时钟与引脚初始化USART1TX→PA9复用推挽、RX→PA10浮空输入时钟源为RCC_APB2Periph_USART1USART2TX→PA2、RX→PA3时钟源为RCC_APB1Periph_USART2USART3TX→PC10、RX→PC11并调用GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE)进行部分重映射。同样SPI 的ch32f1_spi_clock_get依据外设所在总线返回对应时钟SPI1 挂载在 APB2返回PCLK2_FrequencySPI2 挂载在 APB1返回PCLK1_Frequency而 TIM1TIM4 均位于 HCLKch32f1_tim_clock_get统一返回HCLK_Frequency。这些返回值会被适配驱动用于计算波特率、SPI 分频与定时器计数频率。3 必须实现的接口无论启用哪些驱动以下接口都必须由 board 层实现它是整个系统时钟配置的基础rt_uint32_t ch32_get_sysclock_frequency(void);在 board.c 中该接口通过厂商库的RCC_GetClocksFreq获取当前 SYSCLK 频率rt_uint32_t ch32_get_sysclock_frequency(void) { RCC_ClocksTypeDef RCC_Clocks; RCC_GetClocksFreq(RCC_Clocks); return RCC_Clocks.SYSCLK_Frequency; }它被 drv_common.c 中的SystemClock_Config()使用SysTick_Config(ch32_get_sysclock_frequency() / RT_TICK_PER_SECOND)据此计算出 SysTick 重装载值再配合SysTick_Handler中调用rt_tick_increase()驱动 RT-Thread 内核节拍。也就是说只要板级时钟树配置正确系统节拍便自动就绪。4 构建具体芯片 BSP所需文件清单以 ch32f103c8-core 为例在 ENV 环境下使用 MDK 开发至少需要准备以下文件类型路径BSP 根目录ch32f103c8-core/应用层ch32f103c8-core/applications/SConscript、ch32f103c8-core/applications/main.c链接脚本ch32f103c8-core/board/linker_scripts/link.sctGCC 对应link.lds板级源码ch32f103c8-core/board/board.c、ch32f103c8-core/board/board.h芯片配置ch32f103c8-core/board/ch32f10x_conf.h、ch32f103c8-core/board/system_ch32f10x.cKconfigch32f103c8-core/board/Kconfig、ch32f103c8-core/Kconfig构建脚本ch32f103c8-core/board/SConscript、ch32f103c8-core/SConscript、ch32f103c8-core/SConstruct、ch32f103c8-core/rtconfig.pyMDK 工程模板ch32f103c8-core/template.uvprojx对照仓库中真实的 ch32f103c8-core 目录文件一一对应可作为新建其他 CH32F10x 芯片 BSP 时的目录模板。顶层 Kconfig 负责串联整个配置体系RTT_DIR : ../../..指向 RT-Thread 内核source $(RTT_DIR)/Kconfig引入内核配置rsource ../libraries/Kconfig引入芯片系列定义rsource board/Kconfig引入板级外设配置。这意味着板级 Kconfig 是用户通过 menuconfig 选择外设驱动的唯一入口。5 创建 template.uvprojxMDK 工程模板在 Keil MDK 中新建一个名为template的工程删除多余的默认子目录target1将目录名改为rtthread-ch32f103x在 Options魔术棒的 Device 选项中选择目标芯片型号如 CH32F103C8在 User 选项中配置编译后动作例如输出二进制镜像fromelf --bin !L --output rtthread.bin这样每次编译完成后自动生成rtthread.bin便于烧录与分发。模板工程的作用是让scons --dist分发 BSP 时能够以template.uvprojx为蓝本生成用户可用的project.uvprojx。6 编写 board/Kconfig芯片定义与外设使能6.1 芯片 SOC 定义在板级board/Kconfig中首先定义本 BSP 对应的芯片型号menu Hardware Drivers Config config SOC_CH32F103C8 bool select SOC_ARM_SERIES_CH32F103 select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN default ySOC_CH32F103C8是本 BSP 的芯片标识SOC_ARM_SERIES_CH32F103在 libraries/Kconfig 中定义它负责select ARCH_ARM_CORTEX_M3并归属到SOC_ARM_FAMILY_CH32家族从而自动拉起内核架构配置RT_USING_COMPONENTS_INIT、RT_USING_USER_MAIN为 RT-Thread 设备框架默认选项保证自动初始化和 main 线程机制生效。6.2 外设驱动使能模板启用适配驱动只需按“BSP_USING_XXX选择RT_USING_XXX外设细分宏逐项使能”的规则编写即可。以串口驱动为例menu On-chip Peripheral Drivers config BSP_USING_UART bool using onchip usart select RT_USING_SERIAL default n if BSP_USING_UART config BSP_USING_UART1 bool using uart1 default n config BSP_USING_UART2 bool using uart2 default n config BSP_USING_UART3 bool using uart3 default n endif当用户开启BSP_USING_UART时Kconfig 自动select RT_USING_SERIAL把 RT-Thread 串口设备框架拉入编译再通过BSP_USING_UART1/2/3精确选择具体外设。SPI、硬件 I2C 的写法完全一致见 ch32f103c8-core/board/Kconfig 中BSP_USING_SPI、BSP_USING_HWI2C段。WDT 与 RTC 稍有特殊它们依赖内部低速时钟参数config BSP_USING_IWDT bool using onchip iwdt select RT_USING_WDT select LSI_VALUE default n config BSP_USING_RTC bool using onchip rtc select RT_USING_RTC default n if BSP_USING_RTC config BSP_USING_RTC_LSI bool using LSI clock for rtc, if not, LSE default select LSI_VALUE default n endif config LSI_VALUE int default 40000LSI_VALUE默认 40000即 40 kHz 内部低速时钟IWDG 与选择 LSI 作为时钟源的 RTC 都会用到它。6.3 定时器与 PWM 的特殊宏开关定时器CLOCK_TIMER与 PWM 共享 TIM1TIM4因此额外定义了一层工作模式选择宏详见 ch32f103c8-core/board/Kconfig 的BSP_USING_TIM段config BSP_USING_TIM bool using TIMx default n if BSP_USING_TIM config BSP_USING_CLOCK_TIMER bool select RT_USING_CLOCK_TIME default n config BSP_USING_PWM bool select RT_USING_PWM default n ... endif整体宏开关层级可归纳为BSP_USING_TIM定时器总开关BSP_USING_TIM1/2/3/4具体定时器每个定时器内通过choice互斥选择BSP_USING_TIMx_CLOCK_TIMER作为系统时钟定时器select BSP_USING_CLOCK_TIMER进而select RT_USING_CLOCK_TIMEBSP_USING_TIMx_PWM作为 PWM 输出select BSP_USING_PWM进而select RT_USING_PWM其下再细分BSP_USING_TIMx_PWM_CH1~CH4四个通道。因此“PWM 4(timer) × 4(channel)”最多可同时使用 4 个定时器、共 16 路 PWM 通道但同一定时器在同一时间只能被选择为时钟定时器或 PWM 中的一种模式。6.4 配置生成结果在 ENV 下执行menuconfig完成上述选择后配置会写入rtconfig.h。仓库中现成的 ch32f103c8-core/rtconfig.h 展示了启用 UART2 时的生成结果RT_USING_SERIAL、BSP_USING_UART、BSP_USING_UART2、LSI_VALUE 40000等宏均已定义并设置控制台设备为RT_CONSOLE_DEVICE_NAME uart2。7 在 board/board.h 声明接口、在 board/board.c 实现7.1 board.h 中的接口声明根据启用的驱动宏在 board/board.h 中声明对应接口例如串口驱动#ifdef BSP_USING_UART void ch32f1_usart_clock_and_io_init(USART_TypeDef* usartx); #endif定时器与 PWM 驱动使用额外定义的宏开关其完整声明块如下#ifdef BSP_USING_TIM void ch32f1_tim_clock_init(TIM_TypeDef *timx); rt_uint32_t ch32f1_tim_clock_get(TIM_TypeDef *timx); #ifdef BSP_USING_CLOCK_TIMER struct rt_clock_timer_info* ch32f1_clock_timer_info_config_get(TIM_TypeDef *timx); #endif #ifdef BSP_USING_PWM void ch32f1_pwm_io_init(TIM_TypeDef *timx, rt_uint8_t channel); #endif #endifboard.h还同时定义了内存布局宏CH32_FLASH_START_ADRESS0x08000000、FLASH_PAGE_SIZE64、HEAP_BEGIN根据编译器取 RW 区 ZI 段结束地址或__bss_end、HEAP_ENDSRAM 末尾。这些宏配合 drv_common.c 的rt_hw_board_init()完成堆初始化rt_system_heap_init(HEAP_BEGIN, HEAP_END)、Pin/串口驱动初始化与控制台绑定。7.2 board.c 中的接口实现在 board/board.c 中逐一实现这些接口。以定时器时钟为例#ifdef BSP_USING_TIM void ch32f1_tim_clock_init(TIM_TypeDef *timx) { if (timx TIM1) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); if (timx TIM2) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); if (timx TIM3) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); if (timx TIM4) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); } #endif注意 TIM1 挂载在 APB2TIM2/3/4 挂载在 APB1时钟源总线不同。PWM 的ch32f1_pwm_io_init则按定时器与通道配置复用引脚如 TIM1_CH1→PA8、TIM2_CH1→PA0、TIM3_CH1→PA6、TIM4_CH1→PB6这些引脚关系与 ch32f103c8-core/README.md 中列出的 IO 映射表一致。7.3 驱动注册链路适配驱动通过INIT_BOARD_EXPORT/INIT_DEVICE_EXPORT等自动初始化机制注册到 RT-Thread 设备框架rt_hw_board_init()中的rt_components_board_init()会触发这些初始化函数而ch32_drivers内各驱动源文件会在其初始化过程中回调上面声明的 board 层接口完成时钟与引脚配置随后调用rt_hw_xxx_register()注册设备。这就是“board 层提供硬件差异、适配层提供设备框架逻辑”的完整调用链。8 编译验证与运行在 ENV 环境下进入 BSP 目录执行scons即可完成编译MDK 工程亦可直接在 Keil 中打开 project.uvprojx 编译下载连接开发板串口到 PC终端设置为 115200-8-1-N复位后可看到 RT-Thread 启动 banner 与msh命令行提示符若需将 BSP 分发给他人可使用 tools/sdk_dist.py 执行scons --dist生成独立的 BSP 包。9 小结CH32F10x 系列 BSP 移植四步法搭建骨架复制ch32f103c8-core目录结构准备applications、board、SConscript/SConstruct、template.uvprojx等文件定义芯片在board/Kconfig声明SOC_CH32Fxxxxselect到 libraries/Kconfig 中已有的SOC_ARM_SERIES_CH32F103使能驱动按BSP_USING_XXX → select RT_USING_XXX → BSP_USING_XXXn的层级编写外设 Kconfig定时器/PWM 另加模式选择补齐接口在board.h声明、board.c实现ch32_get_sysclock_frequency()与各驱动的时钟/IO 初始化接口保证 drv_common.c 中的系统节拍与设备初始化链路完整运行。按照这套流程即可快速将同一系列的其他 CH32F10x 芯片接入 RT-Thread复用libraries/ch32_drivers的全部适配驱动。赞分享操作系统嵌入式物联网嵌入式OSRTOS【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址https://gitcode.com/gh_mirrors/rt/rt-thread点击查看免费下载相关推荐RT-Thread GD32 RISC-V 系列 BSP 说明开发板支持、驱动配置与 BSP 移植实践RT Thread GD32 RISC V 系列 BSP 说明开发板支持、驱动配置与 BSP 移植实践 RT Thread 的 bsp/gd32/risc v操作系统嵌入式物联网嵌入式OSRTOSRT-Thread GD32 ARM 系列 BSP 开发指南支持矩阵、外设驱动使能与新 BSP 移植RT Thread GD32 ARM 系列 BSP 开发指南支持矩阵、外设驱动使能与新 BSP 移植 RT Thread 在 bsp/gd32/arm 目录下操作系统嵌入式物联网嵌入式OSRTOSRT-Thread i.MX RT 系列 BSP 外设驱动全景指南从 I/O 设备框架到三类驱动实战RT Thread i.MX RT 系列 BSP 外设驱动全景指南从 I/O 设备框架到三类驱动实战 RT Thread 为 i.MX RT 系列RT101操作系统嵌入式物联网嵌入式OSRTOS上一篇Power Apps组件框架深度解析从IncrementControl到CodeInterpreterControl下一篇TakePhoto无障碍标签为图片处理界面添加内容描述创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑