- 操作系统
- 嵌入式
- 物联网
- 嵌入式OS
- RTOS
【免费下载链接】rt-thread
RT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/
RTduino 是 RT-Thread 的 Arduino 生态兼容层,它让开发者可以沿用 Arduino 的pinMode/digitalWrite/Serial/Wire/analogRead等编程习惯,直接在 RT-Thread 上运行,并复用 Arduino 社区海量第三方库。本文以仓库中 arduino_pinout/README.md 为主体,结合 BSP 内 pins_arduino.c、pins_arduino.h、board/Kconfig 等源码,完整讲解如何在 RoboMaster C 板上开启 RTduino、Arduino 引脚与 STM32 引脚 / RT-Thread 设备框架的一一映射关系,以及基于setup()/loop()的入门编程实战。
1 RTduino:RT-Thread 的 Arduino 生态兼容层
大疆 STM32F407 Robomaster C 型开发板(主控 STM32F407IGH6TR,最高主频 168MHz,详见 BSP README)已完整适配 RTduino 软件包。适配的核心价值体现在两个层面:
- 编程习惯无缝衔接:开发者可以完全按照 Arduino 的方式编写控制逻辑(
pinMode、digitalWrite、Serial.begin、Wire、analogRead等),无需直接接触 RT-Thread 的设备框架 API; - 生态极大增强:Arduino 社区大量现成的传感器库、显示库、通信库可以直接为 RT-Thread 所用,弥补了 RT-Thread 原生软件包在某些领域覆盖不足的问题。
RTduino 兼容层并不是为每个 BSP 重新实现一套硬件抽象,而是通过一份引脚映射表把 Arduino 逻辑引脚号(D0~D13、A0~A1)桥接到具体的 STM32 GPIO 与 RT-Thread 设备(UART、I2C、PWM、ADC)。这份映射表就位于本 BSP 的applications/arduino_pinout/目录下,是该兼容层能否“即插即用”的关键。
2 如何开启针对本 BSP 的 Arduino 生态兼容层
在 RT-Thread Env 工具中进入 BSP 目录后敲入menuconfig,或者在 RT-Thread Studio IDE 中选择RT-Thread Settings,按下述路径勾选:
Hardware Drivers Config ---> Onboard Peripheral Drivers ---> [*] Compatible with Arduino Ecosystem (RTduino)勾选后保存退出,接着在终端依次执行(后续重编译前同样需要先拉取软件包源码):
pkgs --update # 拉取 RTduino 软件包及依赖的 HAL/CMSIS 库 scons # 直接命令行编译 # 或重新生成 IDE 工程: # scons --target=mdk5 / mdk4 / iar这一配置项对应 board/Kconfig 中的BSP_USING_ARDUINO。从 Kconfig 的select/imply语句可以看到,开启 RTduino 并非孤立动作,而是会连带自动启用一整套板级驱动依赖:
| Kconfig 依赖项 | 说明 |
|---|---|
select PKG_USING_RTDUINO | 拉取 RTduino 软件包本身 |
select BSP_USING_GPIO | GPIO 驱动(RT_USING_PIN),Arduino 数字 IO 的基础 |
select BSP_USING_ADC/BSP_USING_ADC1 | 片上 ADC1,供 A0 / A1 内部通道使用 |
select BSP_USING_PWM/PWM1(CH1~CH4)/PWM8(CH1~CH3) | 定时器 PWM 输出,供 D7~D13 使用 |
select RT_USING_I2C/BSP_USING_SOFT_I2C/BSP_USING_SOFT_I2C1 | 软件 I2C 总线swi2c1,供 Wire(D5/D6)使用 |
select RTDUINO_USING_WIRE | 开启 RTduino 的 Wire 接口 |
imply RTDUINO_USING_SERVO | 建议性开启 Servo 库(imply,不强制) |
也就是说,勾选一个选项后,配套的 GPIO、ADC、PWM、软件 I2C 都会被正确配置,这正是该 BSP 能做到“开箱即用 Arduino 体验”的原因。同时 Kconfig 中RT_SOFT_I2C1_SCL_PIN_DEFAULT = 81、RT_SOFT_I2C1_SDA_PIN_DEFAULT = 80两个默认值,把软件 I2C 的 SCL/SDA 分别固定到了 PF1 / PF0 引脚(对应 pins_arduino.h 中RTDUINO_DEFAULT_IIC_BUS_NAME "swi2c1"所描述的PF0-SDA PF1-SCL),与下文引脚表完全一致。
3 Arduino 引脚排布总览
本 BSP 的 Arduino 引脚映射如下表(来自 arduino_pinout/README.md,引脚布局的完整定义见 pins_arduino.c 和 pins_arduino.h):
| Arduino 引脚编号 | STM32 引脚编号 | 5V 容忍 | 备注 |
|---|---|---|---|
| 0 (D0) | PH11 | 是 | 板载用户 LED(LED_BUILTIN) |
| 1 (D1) | PB7 | 是 | Serial-RX,默认被 RT-Thread UART 设备框架uart1接管 |
| 2 (D2) | PA9 | 是 | Serial-TX,默认被 RT-Thread UART 设备框架uart1接管 |
| 3 (D3) | PG9 | 是 | Serial-RX,默认被 RT-Thread UART 设备框架uart6接管 |
| 4 (D4) | PG14 | 是 | Serial-TX,默认被 RT-Thread UART 设备框架uart6接管 |
| 5 (D5) | PF1 | 否 | I2C1-SCL,默认被 RT-Thread I2C 设备框架swi2c1接管 |
| 6 (D6) | PF0 | 否 | I2C1-SDA,默认被 RT-Thread I2C 设备框架swi2c1接管 |
| 7 (D7) | PE9 | 是 | PWM1-CH1,默认被 RT-Thread PWM 设备框架pwm1接管 |
| 8 (D8) | PE11 | 是 | PWM1-CH2,默认被 RT-Thread PWM 设备框架pwm1接管 |
| 9 (D9) | PE13 | 是 | PWM1-CH3,默认被 RT-Thread PWM 设备框架pwm1接管 |
| 10 (D10) | PE14 | 是 | PWM1-CH4,默认被 RT-Thread PWM 设备框架pwm1接管 |
| 11 (D11) | PC6 | 是 | PWM8-CH1,默认被 RT-Thread PWM 设备框架pwm8接管 |
| 12 (D12) | PI6 | 是 | PWM8-CH2,默认被 RT-Thread PWM 设备框架pwm8接管 |
| 13 (D13) | PI7 | 是 | PWM8-CH3,默认被 RT-Thread PWM 设备框架pwm8接管 |
| 14 (A0) | -- | 芯片内部温度 ADC,默认被 RT-Thread ADC 设备框架adc1接管 | |
| 15 (A1) | -- | 芯片内部参考电压 ADC,默认被 RT-Thread ADC 设备框架adc1接管 |
引脚表呈现出一个清晰的规律:
- D0~D13是普通数字引脚(部分兼具串口 / I2C / PWM 复用功能),其中 D1~D4 被串口设备框架接管,D5~D6 被 I2C 设备框架接管,D7~D13 被 PWM 设备框架接管;
- A0 / A1没有对应的外部 STM32 引脚(表中为
--),因为它们是STM32F4 芯片内部的 ADC 采样通道(内部温度传感器与内部参考电压),通过adc1设备读取; - 5V 容忍列提醒硬件设计者哪些引脚可以直接连接 5V 电平的外设逻辑,D5 / D6(PF1 / PF0)不支持 5V 容忍,外接 5V 器件时需要注意电平匹配或加转换电路。
注:A0 / A1 的内部通道归属以 arduino_pinout/README.md 的表格与 pins_arduino.c 的源码注释为准:A0 对应内部温度传感器、A1 对应内部参考电压。但从实现细节看,源码中 A0 传入的是
RT_ADC_INTERN_CH_VREF、A1 传入的是RT_ADC_INTERN_CH_TEMPER,与注释存在交叉,从代码结构推断这可能是历史版本的通道宏与注释未同步所致。实际开发中如需精确区分温度与参考电压通道,应以 RT-Thread ADC 框架(rtconfig.h中RT_ADC_INTERN_CH_VREF/RT_ADC_INTERN_CH_TEMPER宏定义)及目标芯片参考手册为准。
4 源码级解析:引脚映射表与设备绑定原理
4.1 映射表数据结构
RTduino 对每个 BSP 的适配核心是 pins_arduino.c 中的pin_map_table[]数组。其条目格式遵循 RTduino 约定:
/* {Arduino Pin, RT-Thread Pin [, Device Name, Channel]} */ const pin_map_t pin_map_table[] = { { D0, GET_PIN(H, 11) }, /* LED_BUILTIN */ { D1, GET_PIN(B, 7), "uart1" }, /* Serial-RX */ { D7, GET_PIN(E, 9), "pwm1", 1 }, /* PWM */ { A0, RT_NULL, "adc1", RT_ADC_INTERN_CH_VREF }, /* ADC, On-Chip */ ... };格式要点(源码头注释中亦有明确说明):
- 数字引脚(Digital pins)不能携带设备名与通道号,如 D0 只给出
GET_PIN(H, 11); - 模拟 / 复用引脚必须给出设备名与通道号,如 PWM 引脚必须写明
"pwm1"与通道号1~4,ADC 引脚必须写明"adc1"与内部通道宏; - Arduino 引脚编号必须按顺序排列,且与 pins_arduino.h 中的宏定义一一对应(
D0~D13依次为 0~13,A0=14、A1=15); - ADC 内部通道用
RT_NULL作为引脚号,表示没有对应物理 GPIO。
GET_PIN(H, 11)是 RT-Thread 的引脚编号宏,把 GPIO 端口 H 的第 11 脚换算为统一的引脚编号,供 RT-Thread pin 设备框架使用。整体上,pin_map_table把「Arduino 逻辑引脚 → RT-Thread pin 设备编号 → RT-Thread 具体设备(uart/pwm/adc/i2c)」三层关系一次性描述完毕。
4.2 头文件中的关键宏
pins_arduino.h 除引脚别名外还定义了几个影响运行时行为的宏:
#define D0 (0) #define D1 (1) /* ... 依次到 */ #define A0 (14) #define A1 (15) #define RTDUINO_PIN_MAX_LIMIT A1 /* pin number max limit check */ #define F_CPU 168000000L /* CPU:168MHz */ #define LED_BUILTIN D0 /* Default Built-in LED */ /* swi2c1 : PF0-SDA PF1-SCL */ #define RTDUINO_DEFAULT_IIC_BUS_NAME "swi2c1"RTDUINO_PIN_MAX_LIMIT:引脚号合法范围的上限检查宏,等于A1,即允许的最大引脚号为 15;F_CPU:声明 CPU 主频 168MHz,供依赖delayMicroseconds精确延时的库使用(与芯片最高主频一致,见 BSP README);LED_BUILTIN:Arduino 标准内置 LED 宏,映射到 D0(PH11,板载用户 LED);RTDUINO_DEFAULT_IIC_BUS_NAME:指定 RTduino Wire 接口默认挂接的 I2C 总线为软件 I2C 总线swi2c1(PF0-SDA、PF1-SCL)。
4.3 数字引脚背后的“接管”机制
引脚表中的 D1~D4、D5~D6、D7~D13 分别被uart1/uart6/swi2c1/pwm1/pwm8设备接管,这意味着一件事:这些引脚在 RTduino 中不做普通数字 IO 使用,而是被直接绑定到对应外设。例如:
- 在 Arduino 中调用
Serial1.begin(...)时,底层实际操作的是 RT-Thread 的uart1设备(PB7 / PA9),对应 C 板上丝印为 UART2 的 4Pin 调试串口; - 调用
Wire库时,走的是软件 I2C 总线swi2c1(PF0 / PF1); - 调用
analogWrite/ Servo 库时,走的是定时器 PWM 通道(pwm1的 CH1~CH4 与pwm8的 CH1~CH3)。
这样的设计让 Arduino 风格的库无需关心底层驱动细节,由 RTduino 在pin_map_table的指引下自动路由到 RT-Thread 设备框架。如果开发者想把这些引脚改作普通 GPIO 使用,就需要在 RT-Thread 侧关闭相应外设接管,或修改映射表——但通常不建议这样做,保持默认映射即可获得最完整的 Arduino 兼容体验。
5 入门编程实战:基于 setup() / loop() 点亮板载 LED
开启 RTduino 后,BSP 会编译 arduino_main.cpp 作为 Arduino 风格入口。编译逻辑见 applications/SConscript:只有当PKG_USING_RTDUINO被使能、且未定义RTDUINO_NO_SETUP_LOOP时,arduino_main.cpp才会加入构建。
该文件就是一个标准的 Arduino 骨架:
#include <Arduino.h> void setup(void) { /* put your setup code here, to run once: */ pinMode(LED_BUILTIN, OUTPUT); } void loop(void) { /* put your main code here, to run repeatedly: */ digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); delay(100); }setup()在系统启动后执行一次,这里把 D0(PH11,板载 LED)配置为输出;loop()无限循环执行:读取当前 LED 状态取反后写回,实现100ms 周期闪烁。
将程序编译下载到开发板后,即可观察到板载 LED 以约 5Hz 的频率闪烁。这与 BSP 默认工程的闪烁效果(见 BSP README 中“运行结果”一节)风格一致,区别在于这里完全使用 Arduino API 实现。
在此基础上,你可以在setup()/loop()中继续扩展:
void setup(void) { pinMode(LED_BUILTIN, OUTPUT); Serial1.begin(115200); /* uart1 (PB7-RX / PA9-TX),C 板丝印 UART2 接口 */ } void loop(void) { digitalWrite(LED_BUILTIN, HIGH); delay(500); digitalWrite(LED_BUILTIN, LOW); delay(500); if (Serial1.available() > 0) { Serial1.write(Serial1.read()); /* 串口回显 */ } }提示:需要先通过 menuconfig 确保对应外设(UART、PWM、ADC、I2C)已在「On-chip Peripheral Drivers」中开启;
BSP_USING_ARDUINO虽然会自动select大部分驱动,但个别如BSP_USING_UART6仍需按需手动确认(默认关闭,见 board/Kconfig)。修改配置后记得重新执行pkgs --update与scons --target=mdk5等命令重新生成工程。
6 适配文件与构建结构速览
与 RTduino 兼容相关的文件都集中在 BSP 内,便于后续查阅或二次适配:
| 文件(仓库根目录相对路径) | 作用 |
|---|---|
| applications/arduino_pinout/README.md | 本指南对应的原始文档:开启方法与完整引脚表 |
| applications/arduino_pinout/pins_arduino.h | Arduino 引脚别名、LED_BUILTIN、F_CPU、默认 I2C 总线名 |
| applications/arduino_pinout/pins_arduino.c | pin_map_table[]引脚映射表实现 |
| applications/arduino_pinout/SConscript | 将pins_arduino编入RTduino-pinout组,依赖PKG_USING_RTDUINO |
| applications/arduino_main.cpp | Arduino 风格的setup()/loop()入口示例 |
| applications/SConscript | 按PKG_USING_RTDUINO决定是否编译arduino_main.cpp |
| board/Kconfig | BSP_USING_ARDUINO配置项及其驱动依赖声明 |
其中 SConscript 的依赖条件写得很明确:
group = DefineGroup('RTduino-pinout', src, depend = ['PKG_USING_RTDUINO'], CPPPATH = inc)即只有在使能 RTduino 软件包后,引脚映射源文件才会参与编译——这与第 2 节的开启步骤完全闭环。
7 小结
- 开启方式:menuconfig / RT-Thread Settings 中勾选
Hardware Drivers Config → Onboard Peripheral Drivers → Compatible with Arduino Ecosystem (RTduino),随后pkgs --update并重新编译; - 引脚体系:D0~D13 + A0~A1 共 16 个 Arduino 引脚,D0 为板载 LED(
LED_BUILTIN),D1~D4 绑定串口,D5~D6 绑定软件 I2C,D7~D13 绑定 PWM,A0 / A1 为芯片内部 ADC 通道; - 适配源码:
pin_map_table[]在 pins_arduino.c 中定义了全部引脚映射与设备绑定,头文件 pins_arduino.h 提供别名与运行时常量; - 开发模式:直接编写 arduino_main.cpp 式的
setup()/loop()代码,即可在 RT-Thread 上获得 Arduino 生态的开发体验。
对 RoboMaster 竞赛队伍而言,这意味着你可以一边享受 RT-Thread 的线程、IPC、设备框架等 RTOS 能力,一边用 Arduino 社区成熟的传感器 / 执行器库快速搭建控制逻辑,两者通过 RTduino 引脚映射表无缝衔接。
- 操作系统
- 嵌入式
- 物联网
- 嵌入式OS
- RTOS
【免费下载链接】rt-thread
RT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/
相关推荐
Escrcpy 设备控制完全指南:scrcpy 设备操作命令与 Android 设置项深入解析
Escrcpy 设备控制完全指南:scrcpy 设备操作命令与 Android 设置项深入解析 本指南以 docs/zhHans/reference/scrcp
操作系统嵌入式物联网嵌入式OSRTOSSTM32F401 Nucleo 的 RT-Thread Arduino 生态兼容指南:RTduino 引脚映射与通信实战
STM32F401 Nucleo 的 RT Thread Arduino 生态兼容指南:RTduino 引脚映射与通信实战 本文基于 RT Thread 仓库中
操作系统嵌入式物联网嵌入式OSRTOSRT-Thread ra6m3-hmi-board 的 Arduino 生态兼容(RTduino)配置与引脚映射实战指南
RT Thread ra6m3 hmi board 的 Arduino 生态兼容(RTduino)配置与引脚映射实战指南 本文以 ra6m3 hmi board
操作系统嵌入式物联网嵌入式OSRTOS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考