mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-27 14:04:56 +01:00
peripherals as scoped singletons
This commit is contained in:
parent
e620b1e57a
commit
e97afa71ce
7 changed files with 68 additions and 30 deletions
|
@ -10,13 +10,13 @@ keywords = ["arm", "cortex-m"]
|
|||
license = "MIT OR Apache-2.0"
|
||||
name = "cortex-m-rtfm"
|
||||
repository = "https://github.com/japaric/cortex-m-rtfm"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
|
||||
[dependencies]
|
||||
cortex-m = "0.3.1"
|
||||
cortex-m = { git = "https://github.com/japaric/cortex-m" }
|
||||
untagged-option = "0.1.1"
|
||||
rtfm-core = "0.1.0"
|
||||
cortex-m-rtfm-macros = "0.2.1"
|
||||
cortex-m-rtfm-macros = { path = "macros" }
|
||||
|
||||
[target.'cfg(target_arch = "x86_64")'.dev-dependencies]
|
||||
compiletest_rs = "0.3.3"
|
||||
|
@ -27,7 +27,8 @@ version = "0.3.3"
|
|||
|
||||
[dev-dependencies.stm32f103xx]
|
||||
features = ["rt"]
|
||||
version = "0.7.5"
|
||||
git = "https://github.com/japaric/stm32f103xx"
|
||||
# version = "0.8.0"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
|
|
@ -12,6 +12,11 @@ use stm32f103xx::{SPI1, GPIOA};
|
|||
app! {
|
||||
device: stm32f103xx,
|
||||
|
||||
resources: {
|
||||
static GPIOA: GPIOA;
|
||||
static SPI1: SPI1;
|
||||
},
|
||||
|
||||
tasks: {
|
||||
EXTI0: {
|
||||
path: exti0,
|
||||
|
@ -27,7 +32,12 @@ app! {
|
|||
},
|
||||
}
|
||||
|
||||
fn init(_p: init::Peripherals) {}
|
||||
fn init(p: init::Peripherals) -> init::LateResourceValues {
|
||||
init::LateResourceValues {
|
||||
GPIOA: p.device.GPIOA,
|
||||
SPI1: p.device.SPI1,
|
||||
}
|
||||
}
|
||||
|
||||
fn idle() -> ! {
|
||||
loop {
|
||||
|
|
|
@ -7,8 +7,9 @@ extern crate cortex_m;
|
|||
extern crate cortex_m_rtfm as rtfm;
|
||||
extern crate stm32f103xx;
|
||||
|
||||
use cortex_m::peripheral::SystClkSource;
|
||||
use cortex_m::peripheral::syst::SystClkSource;
|
||||
use rtfm::{app, Threshold};
|
||||
use stm32f103xx::GPIOC;
|
||||
|
||||
app! {
|
||||
device: stm32f103xx,
|
||||
|
@ -35,9 +36,8 @@ app! {
|
|||
|
||||
// These are the resources this task has access to.
|
||||
//
|
||||
// A resource can be a peripheral like `GPIOC` or a static variable
|
||||
// like `ON`
|
||||
resources: [GPIOC, ON],
|
||||
// The resources listed here must also appear in `app.resources`
|
||||
resources: [ON],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -47,19 +47,20 @@ fn init(p: init::Peripherals, r: init::Resources) {
|
|||
r.ON;
|
||||
|
||||
// power on GPIOC
|
||||
p.RCC.apb2enr.modify(|_, w| w.iopcen().enabled());
|
||||
p.device.RCC.apb2enr.modify(|_, w| w.iopcen().enabled());
|
||||
|
||||
// configure PC13 as output
|
||||
p.GPIOC.bsrr.write(|w| w.bs13().set());
|
||||
p.GPIOC
|
||||
p.device.GPIOC.bsrr.write(|w| w.bs13().set());
|
||||
p.device
|
||||
.GPIOC
|
||||
.crh
|
||||
.modify(|_, w| w.mode13().output().cnf13().push());
|
||||
|
||||
// configure the system timer to generate one interrupt every second
|
||||
p.SYST.set_clock_source(SystClkSource::Core);
|
||||
p.SYST.set_reload(8_000_000); // 1s
|
||||
p.SYST.enable_interrupt();
|
||||
p.SYST.enable_counter();
|
||||
p.core.SYST.set_clock_source(SystClkSource::Core);
|
||||
p.core.SYST.set_reload(8_000_000); // 1s
|
||||
p.core.SYST.enable_interrupt();
|
||||
p.core.SYST.enable_counter();
|
||||
}
|
||||
|
||||
fn idle() -> ! {
|
||||
|
@ -74,15 +75,22 @@ fn idle() -> ! {
|
|||
//
|
||||
// `r` is the set of resources this task has access to. `SYS_TICK::Resources`
|
||||
// has one field per resource declared in `app!`.
|
||||
#[allow(unsafe_code)]
|
||||
fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
|
||||
// toggle state
|
||||
**r.ON = !**r.ON;
|
||||
|
||||
if **r.ON {
|
||||
// set the pin PC13 high
|
||||
r.GPIOC.bsrr.write(|w| w.bs13().set());
|
||||
// NOTE(unsafe) atomic write to a stateless register
|
||||
unsafe {
|
||||
(*GPIOC::ptr()).bsrr.write(|w| w.bs13().set());
|
||||
}
|
||||
} else {
|
||||
// set the pin PC13 low
|
||||
r.GPIOC.bsrr.write(|w| w.br13().reset());
|
||||
// NOTE(unsafe) atomic write to a stateless register
|
||||
unsafe {
|
||||
(*GPIOC::ptr()).bsrr.write(|w| w.br13().reset());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,9 @@ app! {
|
|||
// this function.
|
||||
fn init(p: init::Peripherals) {
|
||||
// This function has access to all the peripherals of the device
|
||||
p.GPIOA;
|
||||
p.RCC;
|
||||
p.core.SYST;
|
||||
p.device.GPIOA;
|
||||
p.device.RCC;
|
||||
// ..
|
||||
}
|
||||
|
||||
|
|
|
@ -63,16 +63,15 @@ pub fn app(app: check::App) -> Result<App> {
|
|||
tasks: app.tasks
|
||||
.into_iter()
|
||||
.map(|(k, v)| {
|
||||
let v = ::check::task(k.as_ref(), v)
|
||||
.chain_err(|| format!("checking task `{}`", k))?;
|
||||
let v =
|
||||
::check::task(k.as_ref(), v).chain_err(|| format!("checking task `{}`", k))?;
|
||||
|
||||
Ok((k, v))
|
||||
})
|
||||
.collect::<Result<_>>()?,
|
||||
};
|
||||
|
||||
::check::resources(&app)
|
||||
.chain_err(|| "checking `resources`")?;
|
||||
::check::resources(&app).chain_err(|| "checking `resources`")?;
|
||||
|
||||
Ok(app)
|
||||
}
|
||||
|
@ -93,6 +92,17 @@ fn resources(app: &App) -> Result<()> {
|
|||
bail!("resource `{}` is unused", resource);
|
||||
}
|
||||
|
||||
for (name, task) in &app.tasks {
|
||||
for resource in &task.resources {
|
||||
ensure!(
|
||||
app.resources.contains_key(&resource),
|
||||
"task {} contains an undeclared resource with name {}",
|
||||
name,
|
||||
resource
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -161,8 +161,13 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
|
|||
let device = &app.device;
|
||||
let krate = krate();
|
||||
|
||||
let mut tys = vec![quote!(#device::Peripherals)];
|
||||
let mut exprs = vec![quote!(#device::Peripherals::all())];
|
||||
let mut tys = vec![quote!(init::Peripherals)];
|
||||
let mut exprs = vec![quote!{
|
||||
init::Peripherals {
|
||||
core: ::#device::CorePeripherals::steal(),
|
||||
device: ::#device::Peripherals::steal(),
|
||||
}
|
||||
}];
|
||||
let mut ret = None;
|
||||
let mut mod_items = vec![];
|
||||
|
||||
|
@ -255,7 +260,10 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
|
|||
root.push(quote! {
|
||||
#[allow(unsafe_code)]
|
||||
mod init {
|
||||
pub use ::#device::Peripherals;
|
||||
pub struct Peripherals {
|
||||
pub core: ::#device::CorePeripherals,
|
||||
pub device: ::#device::Peripherals,
|
||||
}
|
||||
|
||||
#(#mod_items)*
|
||||
}
|
||||
|
@ -268,7 +276,7 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
|
|||
Kind::Exception(ref e) => {
|
||||
if exceptions.is_empty() {
|
||||
exceptions.push(quote! {
|
||||
let scb = &*#device::SCB.get();
|
||||
let scb = &*#device::SCB::ptr();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -284,7 +292,7 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
|
|||
// Interrupt. These can be enabled / disabled through the NVIC
|
||||
if interrupts.is_empty() {
|
||||
interrupts.push(quote! {
|
||||
let nvic = &*#device::NVIC.get();
|
||||
let nvic = &*#device::NVIC::ptr();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -160,6 +160,6 @@ where
|
|||
I: Nr,
|
||||
{
|
||||
// NOTE(safe) atomic write
|
||||
let nvic = unsafe { &*cortex_m::peripheral::NVIC.get() };
|
||||
let nvic = unsafe { &*cortex_m::peripheral::NVIC::ptr() };
|
||||
nvic.set_pending(interrupt);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue