从零开始制作 Rust MCU SDK - PAC 制作篇

931 字
5 分钟
从零开始制作 Rust MCU SDK - PAC 制作篇

从零开始制作 Rust MCU SDK - PAC 制作篇#

怎么制作#

制作一个 SDK 的顺序为:

SVD -> PAC -> HAL

第一步制作 PAC(Peripheral Access Crate)#

使用工具:svd2rust。这个工具可以根据 svd 文件生成 PAC。

接下来以 CW32L010 为例制作一个 PAC。

1. 安装工具#

Terminal window
cargo install svd2rust
cargo install form
rustup component add rustfmt

2. 创建一个 PAC 库工程#

需要用 Cargo 创建一个 lib 工程,命令如下:

Terminal window
cargo new cw32l010_pac --lib
cd cw32l010_pac

将 svd 文件放入工程根目录,例如:

cw32l010_pac/
├── Cargo.toml
└── STM32F103.svd

3. 根据芯片内核选择 target#

svd2rust 支持 Cortex-M、MSP430、RISC-V 和 Xtensa LX6 微控制器。生成的 crate 可通过 --target 标志针对特定架构进行定制。

该标志接受 "cortex-m"、"msp430"、"riscv"、"xtensa-lx" 和 "none" 作为值。使用 "none" 可生成与架构无关的 crate,适用于 svd2rust 当前未知的架构,例如 Cortex-A 架构。

如果省略 --target 标志,svd2rust 将默认目标架构为 Cortex-M。

常用选择:

STM32F103 / STM32F407 / STM32G4 -> --target cortex-m
CH32V203 / CH32V307 / CH32V003 -> --target riscv
架构不确定,只想生成寄存器访问层 -> --target none

比如 STM32:

Terminal window
svd2rust -i .\STM32F103.svd --target cortex-m

比如 WCH 的 CH32V307:

Terminal window
svd2rust -i .\CH32V307.svd --target riscv

执行后,Cortex-M 目标通常会生成:

build.rs
device.x
lib.rs

4. 拆解 lib.rs 为正常 Rust 工程目录#

官方文档也说明了 Cortex-M 会生成这三个文件:build.rs、device.x、lib.rs。

所有这些文件都必须包含在同一个设备 crate 中。lib.rs 文件包含多个内联模块且未格式化。建议使用 form 工具将其拆分,然后使用 rustfmt / cargo fmt 格式化输出:

Terminal window
svd2rust -i CW32L010.svd
rm -rf src
form -i lib.rs -o src/ && rm lib.rs
cargo fmt

5. 不同内核的 Cargo.toml 配置#

生成的 crate 必须提供一个可选的 rt 功能,并依赖于以下这些 crate:

  • critical-section v1.x
  • cortex-m >= v0.7.6
  • cortex-m-rt >= v0.6.13
  • vcell >= v0.1.2

此外,当启用 rt 特性时,必须同时启用 cortex-m-rt 的 device 特性。设备 crate 的 Cargo.toml 将如下所示:

[dependencies]
critical-section = { version = "1.0", optional = true }
cortex-m = "0.7.6"
cortex-m-rt = { version = "0.6.13", optional = true }
vcell = "0.1.2"
[features]
rt = ["cortex-m-rt/device"]

Cortex-M PAC 可以按照下面的方式配置#

[package]
name = "cw32l010_pac"
version = "0.1.0"
edition = "2021"
[dependencies]
critical-section = { version = "1.0", optional = true }
cortex-m = "0.7.6"
cortex-m-rt = { version = "0.6.13", optional = true }
vcell = "0.1.2"
[features]
default = ["critical-section"]
rt = ["cortex-m-rt/device"]

这些依赖和 rt feature 的写法来自 svd2rust 官方文档。Cortex-M 生成的 PAC 通常需要 critical-section、cortex-m、cortex-m-rt、vcell;其中 rt feature 要启用 cortex-m-rt/device。

这里的:

default = ["critical-section"]

是为了本地练习时能直接用:

Peripherals::take()

官方文档里提到,Peripherals::take 通过生成 crate 的 critical-section feature 启用,并且这个方法只能成功调用一次。

RISC-V PAC 可以按照下面的方式配置#

[package]
name = "ch32v307-pac"
version = "0.1.0"
edition = "2021"
[dependencies]
critical-section = { version = "1.0", optional = true }
riscv = "0.12.1"
riscv-rt = { version = "0.13.0", optional = true }
vcell = "0.1.0"
[features]
default = ["critical-section"]
rt = ["riscv-rt"]

svd2rust 文档里给 RISC-V 的依赖示例包含 critical-section、riscv、riscv-peripheral、riscv-rt、vcell,其中 rt 相关依赖应做成可选 feature。

WCH 这里要稍微注意:生成 PAC 只是寄存器访问层,启动代码、中断入口、链接脚本、运行时 crate 还要看后面具体用不用 qingke-rt、riscv-rt、ch32-hal 之类的生态。单纯做寄存器访问,PAC 本身可以先独立生成出来。

Tip

生成的代码默认使用 2021 版 Rust。若想启用 2024 版相关功能,请传入 --edition=2024。

6. 检查 PAC 能否编译#

添加对应的 target 工具#

命令如下:

Terminal window
rustup target add xxxxxxxxxx
  • Cortex-M0+ 使用 thumbv6m-none-eabi
  • Cortex-M3 使用 thumbv7m-none-eabi
  • Cortex-M4 使用 thumbv7em-none-eabihf
  • RISC-V 青稞 V4F 使用 riscv32imac-unknown-none-elf

检查命令:

Terminal window
cargo check --target thumbv7em-none-eabihf
# 开启 rt 可以使用下面的命令
cargo check --target thumbv7m-none-eabi --features rt

7. 在工程中使用 PAC#

后续可以在 HAL 或应用工程中引入生成好的 PAC crate,并基于寄存器访问层继续封装外设抽象。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

从零开始制作 Rust MCU SDK - PAC 制作篇
https://blog.zane-leo.top/posts/rust-mcu-sdk-pac/
作者
lioyae
发布于
2026-06-25
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
Zane Leo
Code, product, deployment, and life notes.
公告
欢迎来到我的博客!这是一则示例公告。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
3
分类
3
标签
10
总字数
3,101
运行时长
0 天
最后活动
0 天前

文章目录