- 操作系统
- 嵌入式
- 物联网
- 嵌入式OS
- RTOS
【免费下载链接】rt-thread
RT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/
RT-Thread 开源仓库中提供了针对恩智浦(NXP)/ Open-ISA RV32M1_VEGA 开发板的板级支持包(BSP),目录为 bsp/rv32m1_vega,对应源码位于 bsp/rv32m1_vega/ri5cy。本文以该 BSP 的官方 README(bsp/rv32m1_vega/README.md)为核心骨架,完整讲解这块双核 RISC-V 开发板的硬件规格、编译环境、烧写调试流程、运行结果验证,并结合仓库源码逐项剖析 UART、时钟、GPIO、MMC/SD 等驱动的实际实现,帮助你在这块异构多核开发板上快速跑通并移植 RT-Thread。
1. 板级简介与硬件规格
RV32M1_VEGA 开发板是一款多核异构 RISC-V 32 位开发板,芯片内部集成了两个 RISC-V 32 位核心(RI5CY 与 Zero-riscy),并携带 BLE 外设。RT-Thread 在本 BSP 中默认运行在其中的 RI5CY 核心上,BSP 目录以ri5cy命名即源于此,启动文件startup_RV32M1_ri5cy.S与器件头文件RV32M1_ri5cy.h均可在 bsp/rv32m1_vega/rv32m1_sdk_riscv/devices/RV32M1 中找到。
README 中给出的核心硬件规格如下:
| 硬件 | 描述 |
|---|---|
| 芯片型号 | RV32M1 |
| CPU | RV32IMC,带有后置自增 load/store 扩展、乘累加扩展、ALU 扩展、硬件循环扩展;另有 RV32IEMC 核心 |
| 主频 | 48MHz 或 72MHz |
| 片内 SRAM | 256kB + 128kB |
| 片内 Flash | 1MB + 256kB |
从仓库实际配置看,BSP 将 LPFLL 配置为72MHz运行:board.c 中的g_appScgLpFllConfig_BOARD_BootClockRUN设置range = kSCG_LpFllRange72M(LPFLL 校准到 72MHz),并在rt_hw_board_init()中调用BOARD_BootClockRUN()与CLOCK_InitLpFll()完成时钟初始化。若需降频至 48MHz,改此配置项即可。
关于内存布局,链接脚本 link.lds 定义了三段存储区:
m_vector:起始地址0x000FFF00,长度 0x100(256 字节),放置向量表;m_text:起始地址0x00000000,长度 0xFFF00,存放代码与只读数据;m_data:起始地址0x20000000,长度0x00030000 - 0x1800(约 192kB),对应片内 SRAM。
堆区边界在 board.h 中声明:RT_HW_HEAP_BEGIN取__bss_end__,RT_HW_HEAP_END为0x20000000 + 0x00030000 - 0x1800,与链接脚本的数据段终点一致。
2. 编译说明:工具链、ENV 与 scons
2.1 工具链与架构约束
README 明确指出:当前测试所用工具链为 GNU GCC 7.2.0 搭配 newlib 2.5.0,按标准 RV32IMC 架构编译,因此 RV32M1 的扩展指令(后置自增 load/store、乘累加、ALU 扩展、硬件循环等)未被启用;配套使用的 RT-Thread ENV 版本为 1.0。
工具链的详细设定可从 rtconfig.py 中核实:
ARCH = 'risc-v' CPU = 'rv32m1' CROSS_TOOL = 'gcc' PREFIX = 'riscv-none-embed-' DEVICE = ' -march=rv32imc -mabi=ilp32'其中-march=rv32imc -mabi=ilp32与 README 描述的标准 RV32IMC 架构完全一致,riscv-none-embed-前缀对应 GNU GCC + newlib 的嵌入式工具链。该 BSP 的构建脚本 SConstruct 会额外引入rv32m1_sdk_riscv目录中的 NXP SDK 驱动源码参与编译(通过SConscript('../rv32m1_sdk_riscv/SConscript', ...))。
2.2 编译步骤
在 Windows 上推荐使用 RT-Thread ENV 工具编译(ENV 版本为 1.0)。在 console 中切换到bsp/rv32m1_vega/ri5cy目录,运行:
scons编译正确无误后,会在该目录下生成rtthread.elf与rtthread.bin两个文件,其中rtthread.bin需要烧写到设备中运行。rtconfig.py中的POST_ACTION会在链接后自动执行size工具打印镜像体积;若需要直接生成 bin,可参照该文件中被注释的OBJCPY -O binary步骤启用。
2.3 内核与组件配置速览
BSP 的配置头文件 rtconfig.h 展示了这块板子默认启用的功能集合,可作为裁剪与扩展的起点:
- 内核:
RT_TICK_PER_SECOND 100(时钟节拍 100Hz)、优先级数 32、线程名长度 12、主线程栈 2048 字节(RT_MAIN_THREAD_STACK_SIZE); - 命令行:启用
RT_USING_MSH/FINSH_USING_MSH,shell 线程名tshell,命令历史 5 行,MSH_USING_BUILT_IN_COMMANDS内置命令; - 文件系统:启用 DFS(
RT_USING_DFS)与 elm-FatFs(RT_USING_DFS_ELMFAT,长文件名 LFN,最大扇区 512 字节),并启用 devfs; - 设备驱动:
RT_USING_SERIAL(串口 v1 框架,支持 DMA)、RT_USING_RTC、RT_USING_PIN(PIN 设备框架); - 控制台:
RT_CONSOLE_DEVICE_NAME "uart0",即默认控制台挂在 UART0 上,与下文串口配置呼应; - 工具:
RT_USING_ULOG(日志组件,输出级别 7,含时间/级别/标签); - 软件包:默认使能 MicroPython(
PKG_USING_MICROPYTHON,堆大小 8192 字节); - 平台:
ARCH_RISCV、SOC_VEGA_RI5CY、BOARD_X_FRDM_VEGA、BSP_USING_UART0、BSP_USING_UART1。
3. 烧写与执行:JLink + OpenOCD + GDB
3.1 JTAG 连接与驱动模式
- 使用JLink接入 RV32M1_VEGA 开发板RISC-V 核的 JTAG 接口;
- 该 JTAG 接口位于RV32M1 芯片与天线座子旁边,是一个20pin 的 JTAG 接口;
- 将JLink 在 PC 上的驱动更改为 WinUSB 模式,以便与 OpenOCD 正常配合。
3.2 串口连接与参数
使用 USB 线连接到开发板上标记为 SDA 的 USB 口,PC 上即会识别出一个串口设备。串口参数固定为:
115200-N-8-1即波特率 115200、无校验位、8 位数据、1 位停止位。该板级控制台所使用串口引脚为PTC7/PTC8(对应 UART0)。
3.3 烧写与调试命令
正确编译产生rtthread.bin映像文件后,使用gdb 连接到 openocd,并通过load命令将映像烧写进 Flash:
# openocd 一侧负责 JTAG 连接与 flash 写入, # gdb 一侧执行: loadload命令会把rtthread.bin的内容加载到目标地址并写入片内 Flash。烧写完成后复位开发板即可运行 RT-Thread。关于更多 JTAG 与 gdb 调试 RV32M1_VEGA 的细节,README 建议参考开发板的《开发环境搭建》文档。
4. 运行结果:启动信息与文件系统验证
当编译与烧写无误后,按下复位按钮SW1复位设备,即可在串口(115200-N-8-1)上观察到 RT-Thread 启动 logo 信息:
\ | / - RT - Thread Operating System / | \ 4.0.0 build Dec 5 2018 2006 - 2018 Copyright by rt-thread team File System initialized! Hello RT-Thread! msh />这段输出对应了 BSP 中两条核心启动路径,可从源码逐一印证:
Hello RT-Thread!来自应用程序入口 applications/main.c,main()中调用rt_kprintf("Hello RT-Thread!\n");File System initialized!来自 applications/mnt.c:mnt_init()通过dfs_mount("sd0", "/", "elm", 0, 0)将 SD 卡设备挂载到根目录,挂载成功后打印该信息;失败则打印File System initialized failed!。该函数通过INIT_ENV_EXPORT(mnt_init)注册为环境初始化阶段自动执行。
同时,板级初始化流程可参考 board/board.c:rt_hw_board_init()依次完成引脚复用(BOARD_InitPins())、时钟初始化(BOARD_BootClockRUN()+CLOCK_InitLpFll())、中断复用(INTMUX_Init)、串口初始化(rt_hw_uart_init())、系统节拍初始化(rt_hw_systick_init(),内部使用 LPIT0 定时器产生 100Hz 节拍并调用rt_tick_increase())、控制台设备注册(rt_console_set_device(RT_CONSOLE_DEVICE_NAME),即 uart0)以及堆初始化(rt_system_heap_init)。
5. 外设驱动支持情况
README 汇总了当前 BSP 的外设驱动支持矩阵:
| 驱动 | 支持情况 | 备注 |
|---|---|---|
| UART | 支持 | UART0:RX(PTC7)、TX(PTC8) |
| 支持 | UART1:RX(PTA25)、TX(PTA26) | |
| clock | 支持 | |
| GPIO | 支持 | 列表可能不完善,使用具体 IO 时需按需调整 pinmux、clock |
| MMC/SD | 支持 |
对应实现分散在 ri5cy/driver 目录中(drv_uart.c、drv_gpio.c、drv_sdcard.c),而底层外设寄存器驱动来自 rv32m1_sdk_riscv/devices/RV32M1/drivers(NXP fsl 系列驱动,含fsl_lpuart.c、fsl_gpio.c、fsl_usdhc.c、fsl_clock.c等),SD 卡协议栈则位于 rv32m1_sdk_riscv/sdmmc_2.1.2。
从源码可以看出几个值得注意的实现细节:
- UART1 复用 LPUART1 外设:在 board/pin_mux.c 中,
PTA25被配置为LPUART1_RX(复用功能 Alt2),PTA26配置为LPUART1_TX,与 README 的 UART1 引脚(RX PTA25 / TX PTA26)一致;而控制台 UART0 使用 PTC7/PTC8。 - SD 卡引脚与中断:board.h 定义了 USDHC0 主机、卡检测引脚
PORTC/GPIO_PIN 27(上升沿中断)、卡插入电平为高(BOARD_USDHC_CARD_INSERT_CD_LEVEL 1)等参数;pin_mux.c 中可见 SDHC0 的 D0~D3、DCLK、CMD 六条引脚均配置为上拉 + 快速翻转,用于 4 位 SD 模式。 - GPIO 需按需调整复用:README 特意提醒 GPIO 列表可能不完整,使用具体 IO 时必须同步修改 pinmux 与 clock 配置——例如 pin_mux.c 将 PTA22/PTA23/PTA24 通过
PORT_SetPinMux(..., kPORT_MuxAsGpio)配置为普通 GPIO,正是 LED 引脚所在。
6. IO 映射速查表
README 提供了 BSP 中的 IO 与代码宏定义的映射关系,供开发者在编写应用时直接引用:
| IO 号 | BSP 代码中的定义 |
|---|---|
| PTA22 | LED_BLUE |
| PTA23 | LED_GREEN |
| PTA24 | LED_RED |
| PTA24 | LED_STS |
| PTA25 | UART1_RX |
| PTA26 | UART1_TX |
| PTE8 | BTN_SW3 |
| PTE9 | BTN_SW4 |
| PTE12 | BTN_SW5 |
| PTA0 | BTN_SW2/BTN_NMI |
这些宏对应开发板上的 LED(蓝/绿/红三色灯与状态灯)和按键 SW2~SW5。注意 PTA0 同时承担 SW2 按键与 NMI(不可屏蔽中断)功能,在应用中使用该引脚做普通输入时需要留意中断属性的配置。结合上文的 pin_mux.c 可见,LED 与 UART1 的引脚复用已在该文件中预先配置,而按键相关引脚建议在实际使用前再次核对复用配置。
7. 参考文档与延伸阅读
README 末尾列出了以下参考资料(原文档为外部 PDF 链接,此处给出仓库内可继续深入的相关文件):
- bsp/rv32m1_vega/README_zh.md:本 BSP 的中文版说明(内容与英文 README 对应,含中文注释);
- bsp/rv32m1_vega/ri5cy/rtconfig.h:BSP 当前生效的完整配置(内核、组件、驱动、软件包);
- bsp/rv32m1_vega/ri5cy/rtconfig.py:工具链与编译选项的最终来源;
- bsp/rv32m1_vega/ri5cy/board:板级初始化、时钟、引脚复用、中断与异常处理实现;
- bsp/rv32m1_vega/ri5cy/driver:UART、GPIO、SD 卡等 RT-Thread 驱动框架层实现;
- bsp/rv32m1_vega/rv32m1_sdk_riscv:NXP RV32M1 SDK(器件定义、fsl 外设驱动、sdmmc 协议栈)。
关于开发板的硬件细节(JTAG 布局、BLE 外设、电源与启动配置等)以及芯片寄存器级行为,请以 RV32M1_VEGA 开发板用户手册与 RV32M1 芯片数据手册(Rev.1.1)为准。
小结
RV32M1_VEGA BSP 是 RT-Thread 在异构多核 RISC-V 平台上的一份完整参考实现:从rtconfig.py的-march=rv32imc工具链约束、link.lds的双段内存布局,到board.c中 LPFLL 72MHz 时钟与 LPIT0 系统节拍,再到mnt.c中 SD 卡挂载验证,整个启动链路均可对照源码逐行核实。对于需要在 RV32M1 或类似 RISC-V 异构平台上评估 RT-Thread 的开发者,按本文第 2、3 节的步骤完成编译与烧写,即可在串口上看到完整的 RT-Thread 启动与文件系统初始化输出,并以此为基础继续扩展 GPIO、UART1、SD 卡等外设应用。
- 操作系统
- 嵌入式
- 物联网
- 嵌入式OS
- RTOS
【免费下载链接】rt-thread
RT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/
相关推荐
RT-Thread 在 Vango V85XX 评估板上的板级支持包实战指南:编译、烧写与驱动开发
RT Thread 在 Vango V85XX 评估板上的板级支持包实战指南:编译、烧写与驱动开发 本文以 RT Thread 仓库中 bsp/Vango/v8
操作系统嵌入式物联网嵌入式OSRTOSRT-Thread 在 ACM32F4xx 上的板级支持包(BSP)开发指南:编译、烧写与驱动配置
RT Thread 在 ACM32F4xx 上的板级支持包(BSP)开发指南:编译、烧写与驱动配置 本篇技术指南围绕 RT Thread 仓库中 bsp/acm
操作系统嵌入式物联网嵌入式OSRTOSRT-Thread LPC55S69-EVK 板级支持包详解:从编译烧写到外设驱动开发
RT Thread LPC55S69 EVK 板级支持包详解:从编译烧写到外设驱动开发 本篇技术指南围绕 RT Thread 仓库中的 LPC55S69 EVK
操作系统嵌入式物联网嵌入式OSRTOS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考