Skip to content

Commit e78ca98

Browse files
committed
Auto merge of #50 - japaric:singletons, r=japaric
Peripherals as scoped singletons See this RFC for details: rust-embedded/svd2rust#157 - The first commit adapts this crate to the changes in rust-embedded/cortex-m#65 and rust-embedded/svd2rust#158 - ~~The second commit is an alternative implementation of RFC #47 (there's another implementation in #49. This second commit is not required for RFC157 but let us experiment with safe DMA abstractions.~~ postponed ### TODO - [x] un-bless peripherals as resources. Peripherals as resources were special cased: if resource listed in e.g. `app.tasks.FOO.resources` didn't appear in `app.resources` then it was assumed to be a peripheral and special code was generated for it. This is no longer required under RFC157. ~~This depends on PR rtic-rs/rtic-syntax#2~~ postponed
2 parents e620b1e + 1830bdb commit e78ca98

File tree

7 files changed

+176
-233
lines changed

7 files changed

+176
-233
lines changed

Cargo.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ keywords = ["arm", "cortex-m"]
1010
license = "MIT OR Apache-2.0"
1111
name = "cortex-m-rtfm"
1212
repository = "https://github.com/japaric/cortex-m-rtfm"
13-
version = "0.2.2"
13+
version = "0.3.0"
1414

1515
[dependencies]
16-
cortex-m = "0.3.1"
16+
cortex-m = { git = "https://github.com/japaric/cortex-m" }
1717
untagged-option = "0.1.1"
1818
rtfm-core = "0.1.0"
19-
cortex-m-rtfm-macros = "0.2.1"
19+
cortex-m-rtfm-macros = { path = "macros" }
2020

2121
[target.'cfg(target_arch = "x86_64")'.dev-dependencies]
2222
compiletest_rs = "0.3.3"
@@ -27,7 +27,8 @@ version = "0.3.3"
2727

2828
[dev-dependencies.stm32f103xx]
2929
features = ["rt"]
30-
version = "0.7.5"
30+
git = "https://github.com/japaric/stm32f103xx"
31+
# version = "0.8.0"
3132

3233
[profile.release]
3334
lto = true

examples/generics.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ use stm32f103xx::{SPI1, GPIOA};
1212
app! {
1313
device: stm32f103xx,
1414

15+
resources: {
16+
static GPIOA: GPIOA;
17+
static SPI1: SPI1;
18+
},
19+
1520
tasks: {
1621
EXTI0: {
1722
path: exti0,
@@ -27,7 +32,12 @@ app! {
2732
},
2833
}
2934

30-
fn init(_p: init::Peripherals) {}
35+
fn init(p: init::Peripherals) -> init::LateResourceValues {
36+
init::LateResourceValues {
37+
GPIOA: p.device.GPIOA,
38+
SPI1: p.device.SPI1,
39+
}
40+
}
3141

3242
fn idle() -> ! {
3343
loop {

examples/one-task.rs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ extern crate cortex_m;
77
extern crate cortex_m_rtfm as rtfm;
88
extern crate stm32f103xx;
99

10-
use cortex_m::peripheral::SystClkSource;
10+
use cortex_m::peripheral::syst::SystClkSource;
1111
use rtfm::{app, Threshold};
12+
use stm32f103xx::GPIOC;
1213

1314
app! {
1415
device: stm32f103xx,
@@ -35,9 +36,8 @@ app! {
3536

3637
// These are the resources this task has access to.
3738
//
38-
// A resource can be a peripheral like `GPIOC` or a static variable
39-
// like `ON`
40-
resources: [GPIOC, ON],
39+
// The resources listed here must also appear in `app.resources`
40+
resources: [ON],
4141
},
4242
}
4343
}
@@ -47,19 +47,20 @@ fn init(p: init::Peripherals, r: init::Resources) {
4747
r.ON;
4848

4949
// power on GPIOC
50-
p.RCC.apb2enr.modify(|_, w| w.iopcen().enabled());
50+
p.device.RCC.apb2enr.modify(|_, w| w.iopcen().enabled());
5151

5252
// configure PC13 as output
53-
p.GPIOC.bsrr.write(|w| w.bs13().set());
54-
p.GPIOC
53+
p.device.GPIOC.bsrr.write(|w| w.bs13().set());
54+
p.device
55+
.GPIOC
5556
.crh
5657
.modify(|_, w| w.mode13().output().cnf13().push());
5758

5859
// configure the system timer to generate one interrupt every second
59-
p.SYST.set_clock_source(SystClkSource::Core);
60-
p.SYST.set_reload(8_000_000); // 1s
61-
p.SYST.enable_interrupt();
62-
p.SYST.enable_counter();
60+
p.core.SYST.set_clock_source(SystClkSource::Core);
61+
p.core.SYST.set_reload(8_000_000); // 1s
62+
p.core.SYST.enable_interrupt();
63+
p.core.SYST.enable_counter();
6364
}
6465

6566
fn idle() -> ! {
@@ -74,15 +75,22 @@ fn idle() -> ! {
7475
//
7576
// `r` is the set of resources this task has access to. `SYS_TICK::Resources`
7677
// has one field per resource declared in `app!`.
78+
#[allow(unsafe_code)]
7779
fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
7880
// toggle state
7981
**r.ON = !**r.ON;
8082

8183
if **r.ON {
8284
// set the pin PC13 high
83-
r.GPIOC.bsrr.write(|w| w.bs13().set());
85+
// NOTE(unsafe) atomic write to a stateless register
86+
unsafe {
87+
(*GPIOC::ptr()).bsrr.write(|w| w.bs13().set());
88+
}
8489
} else {
8590
// set the pin PC13 low
86-
r.GPIOC.bsrr.write(|w| w.br13().reset());
91+
// NOTE(unsafe) atomic write to a stateless register
92+
unsafe {
93+
(*GPIOC::ptr()).bsrr.write(|w| w.br13().reset());
94+
}
8795
}
8896
}

examples/zero-tasks.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ app! {
2525
// this function.
2626
fn init(p: init::Peripherals) {
2727
// This function has access to all the peripherals of the device
28-
p.GPIOA;
29-
p.RCC;
28+
p.core.SYST;
29+
p.device.GPIOA;
30+
p.device.RCC;
3031
// ..
3132
}
3233

macros/src/check.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,15 @@ pub fn app(app: check::App) -> Result<App> {
6363
tasks: app.tasks
6464
.into_iter()
6565
.map(|(k, v)| {
66-
let v = ::check::task(k.as_ref(), v)
67-
.chain_err(|| format!("checking task `{}`", k))?;
66+
let v =
67+
::check::task(k.as_ref(), v).chain_err(|| format!("checking task `{}`", k))?;
6868

6969
Ok((k, v))
7070
})
7171
.collect::<Result<_>>()?,
7272
};
7373

74-
::check::resources(&app)
75-
.chain_err(|| "checking `resources`")?;
74+
::check::resources(&app).chain_err(|| "checking `resources`")?;
7675

7776
Ok(app)
7877
}
@@ -93,6 +92,17 @@ fn resources(app: &App) -> Result<()> {
9392
bail!("resource `{}` is unused", resource);
9493
}
9594

95+
for (name, task) in &app.tasks {
96+
for resource in &task.resources {
97+
ensure!(
98+
app.resources.contains_key(&resource),
99+
"task {} contains an undeclared resource with name {}",
100+
name,
101+
resource
102+
);
103+
}
104+
}
105+
96106
Ok(())
97107
}
98108

0 commit comments

Comments
 (0)