4个版本
0.2.0 | 2021年3月5日 |
---|---|
0.1.4 | 2021年2月5日 |
0.1.1 | 2021年1月29日 |
#1612 in 嵌入式开发
63KB
913 行
rumio
轻松控制MMIO和CPU寄存器。
此包提供各种宏来生成用于MMIO块和CPU寄存器的良好API。它主要用作register
包的替代品,以提供更好的API并简化工作。
用法
有关更多更新和更大的示例,请参阅测试。
定义CPU寄存器
CPU寄存器仅对使用位字段存储数据的控制寄存器有用。例如,RISC-V架构的控制状态寄存器。
#![feature(asm)]
mod mstatus {
use rumio::cpu::{RegisterRead, RegisterWrite};
// first we need to define a register, and a way to read/write to it.
// we will use the `mstatus` CSR from the RISC-V architecture as an example
struct Mstatus;
// the `usize` argument indicates the underyling value of the register.
impl RegisterRead<usize> for Mstatus {
#[inline]
fn read() -> usize {
let reg;
unsafe { asm!("csrr {}, mstatus", out(reg) reg) }
reg
}
}
impl RegisterWrite<usize> for Mstatus {
#[inline]
fn write(val: usize) {
unsafe { asm!("csrw mstatus, {}", in(reg) val) }
}
#[inline]
fn set(mask: usize) {
// `impl_cpu_set` and `impl_cpu_clear` can generated `set` and `clear`
// by performing a read, setting the bits and then write the value again.
rumio::impl_cpu_set!(Self, mask);
}
#[inline]
fn clear(mask: usize) {
rumio::impl_cpu_clear!(Self, mask);
}
}
// now define the different bits and fields of this register
rumio::define_cpu_register! { Mstatus as usize =>
/// Globally enables interrupts in U-Mode.
rw UIE: 0,
/// Globally enables interrupts in S-Mode.
rw SIE: 1,
/// Globally enables interrupts in M-Mode.
rw MIE: 3,
/// The privilege mode a trap in M-Mode was taken from.
r MPP: 11..12 = enum PrivilegeMode [
User = 0b00,
Supervisor = 0b01,
Machine = 0b11,
],
/// This is not an actual flag of the `mstatus` register, but
/// we add it here for showing the usage of `flags`
rw FLAGS: 13..16 = flags CpuFlags [
A = 0b0001,
B = 0b0010,
C = 0b0100,
D = 0b1000,
],
}
}
// the generated api then can be used like this.
// to explore the full api generated by this macro, check the `example_generated`
// module on docs.rs, and check the examples (the tests are the examples)
mstatus::modify(mstatus::UIE::SET | mstatus::SIE::SET | mstatus::MIE::SET);
println!("Trap was taken from {:?}", mstatus::MPP::get());
定义MMIO寄存器
// define one MMIO register whose base type is `u16` and name is `Reg`.
rumio::define_mmio_register! {
Reg: u16 {
rw MODE: 0..1 = enum Mode [
A = 0b00,
B = 0b01,
C = 0b10,
D = 0b11,
],
r FOO: 2,
rw BAR: 3,
rw BAZ: 4,
rw FLAGS: 5..8 = flags Flags [
A = 0b0001,
B = 0b0010,
C = 0b0100,
D = 0b1000,
],
}
}
rumio::define_mmio_struct! {
pub struct Device {
(0x00 => one: Reg),
(0x08 => two: Reg),
}
}
// create a new `Device` at address `0xF00D_BABE
let mmio = unsafe { Device::new(0xF00D_BABE) };
// access the `one` register
let one = mmio.one();
// now `one` can be used similarly to the cpu register
one.MODE().set(Mode::B);
one.FLAGS().set(Flags::B | Flags::C);
one.modify(Mode::A | BAR::SET);
许可
许可协议为Apache License或MIT。
依赖项
~115KB