5 个版本 (3 个重大变更)
使用旧 Rust 2015
0.4.0 | 2016 年 11 月 20 日 |
---|---|
0.3.0 | 2016 年 11 月 14 日 |
0.2.1 |
|
0.1.1 | 2016 年 11 月 10 日 |
#114 在 #register
每月 21 次下载
用于 svd_board
22KB
485 行
svd_codegen
从 SVD 文件生成 Rust 寄存器映射(
struct
)
这是 japaric/svd2rust 的一个分支,生成了一个略有不同的 API。
用法
- 获取每个外设寄存器块的起始地址。
$ svd_codegen -i STM32F30x.svd
const GPIOA: usize = 0x48000000;
const GPIOB: usize = 0x48000400;
const GPIOC: usize = 0x48000800;
const GPIOD: usize = 0x48000c00;
const GPIOE: usize = 0x48001000;
const GPIOF: usize = 0x48001400;
(..)
- 为单个外设生成寄存器映射。
$ svd_codegen -i STM32F30x.svd rcc | head
#[repr(C)]
/// Reset and clock control
pub struct Rcc {
/// 0x00 - clock control register
pub cr: ::volatile::ReadWrite<Cr>,
/// 0x04 - PLL configuration register
pub pllcfgr: ::volatile::ReadWrite<Pllcfgr>,
/// 0x08 - clock configuration register
pub cfgr: ::volatile::ReadWrite<Cfgr>,
/// 0x0c - clock interrupt register
pub cir: ::volatile::ReadWrite<Cir>,
/// 0x10 - AHB1 peripheral reset register
pub ahb1rstr: ::volatile::ReadWrite<Ahb1rstr>,
(..)
API
svd_codegen
为每个外设生成以下 API
寄存器块
寄存器块“定义”作为 struct
。以下是一个示例
/// Inter-integrated circuit
#[repr(C)]
pub struct I2c1 {
/// 0x00 - Control register 1
pub cr1: ::volatile::ReadWrite<Cr1>,
/// 0x04 - Control register 2
pub cr2: ::volatile::ReadWrite<Cr2>,
/// 0x08 - Own address register 1
pub oar1: ::volatile::ReadWrite<Oar1>,
/// 0x0c - Own address register 2
pub oar2: ::volatile::ReadWrite<Oar2>,
/// 0x10 - Timing register
pub timingr: ::volatile::ReadWrite<Timingr>,
/// 0x14 - Status register 1
pub timeoutr: ::volatile::ReadWrite<Timeoutr>,
/// 0x18 - Interrupt and Status register
pub isr: ::volatile::ReadWrite<Isr>,
/// 0x1c - Interrupt clear register
pub icr: ::volatile::WriteOnly<Icr>,
/// 0x20 - PEC register
pub pecr: ::volatile::ReadOnly<Pecr>,
/// 0x24 - Receive data register
pub rxdr: ::volatile::ReadOnly<Rxdr>,
/// 0x28 - Transmit data register
pub txdr: ::volatile::ReadWrite<Txdr>,
}
用户必须为每个外设实例“实例化”此定义。他们有多种选择
static
和/或static mut
。以下是一个示例
extern "C" {
// I2C1 can be accessed in read-write mode
pub static mut I2C1: I2c;
// whereas I2C2 can only be accessed in "read-only" mode
pub static I2C1: I2c;
}
这些寄存器块的地址必须由链接脚本提供
/* layout.ld */
I2C1 = 0x40005400;
I2C2 = 0x40005800;
这会导致 I2C1
和 I2C2
符号被“占用”,因此其他 C/Rust 符号(static
、function
等)不能有相同的名称。
- “构造函数”函数。例如,相当于以下
static
之一
// Addresses of the register blocks. These are private.
const I2C1: usize = 0x40005400;
const I2C2: usize = 0x40005800;
// NOTE(unsafe) can alias references to mutable memory
pub unsafe fn i2c1() -> &'mut static I2C {
unsafe { &mut *(I2C1 as *mut I2c) }
}
pub fn i2c2() -> &'static I2C {
unsafe { &*(I2C2 as *const I2c) }
}
read
/ write
/ update
寄存器块中的每个寄存器,例如 I2c
结构中的 cr1
字段,都封装在一个可变的包装器中,该包装器公开了一些方法
- 只读寄存器只公开
read
方法。 - 只写寄存器只公开
write
方法。 - 读写寄存器公开所有方法:
read
、write
和update
。
read
方法执行单个、可变的 LDR
指令,而 write
方法执行单个、可变的 STR
指令。更新方法接收一个闭包,该闭包修改寄存器。它执行 read
,将值传递给闭包,并将修改后的值写回
pub fn update<F>(&mut self, f: F)
where F: FnOnce(&mut T)
{
let mut value = self.read();
f(&mut value);
self.write(value);
}
许可
根据您的选择,许可如下
- Apache 许可证版本 2.0(《LICENSE-APACHE》或 http://www.apache.org/licenses/LICENSE-2.0》)
- MIT 许可证(《LICENSE-MIT》或 http://opensource.org/licenses/MIT》)
。
贡献
除非您明确声明,否则您按照Apache-2.0许可证定义提交的任何有意贡献,用于包括在工作中的贡献,应如上双授权,不附加任何额外条款或条件。
依赖项
约3MB
约56K SLoC