Skip to content

Commit 8a396c5

Browse files
committed
Auto merge of #58 - japaric:init-resources, r=japaric
safe `&'static mut` references via init.resources see RFC #59 for details
2 parents 0f5784c + a238fd5 commit 8a396c5

19 files changed

+448
-244
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
**/*.rs.bk
22
*.org
3+
.#*
34
.gdb_history
45
Cargo.lock
56
target/

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ version = "0.3.0"
1515
[dependencies]
1616
cortex-m = { git = "https://github.com/japaric/cortex-m" }
1717
untagged-option = "0.1.1"
18-
rtfm-core = "0.1.0"
18+
# rtfm-core = "0.2.0"
19+
rtfm-core = { git = "https://github.com/japaric/rtfm-core" }
1920
cortex-m-rtfm-macros = { path = "macros" }
2021

2122
[target.'cfg(target_arch = "x86_64")'.dev-dependencies]
22-
compiletest_rs = "0.3.3"
23+
# compiletest_rs = "0.3.4"
24+
compiletest_rs = { git = "https://github.com/dwrensha/compiletest-rs", branch = "rustup" }
2325

2426
[dev-dependencies.cortex-m-rt]
2527
features = ["abort-on-panic"]

examples/custom-type.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#![deny(unsafe_code)]
2+
#![deny(warnings)]
3+
#![feature(proc_macro)]
4+
#![no_std]
5+
6+
extern crate cortex_m_rtfm as rtfm;
7+
extern crate stm32f103xx;
8+
9+
use rtfm::{app, Threshold};
10+
11+
pub struct Foo;
12+
13+
app! {
14+
device: stm32f103xx,
15+
16+
resources: {
17+
static CO_OWNED: Foo = Foo;
18+
static ON: Foo = Foo;
19+
static OWNED: Foo = Foo;
20+
static SHARED: Foo = Foo;
21+
},
22+
23+
idle: {
24+
resources: [OWNED, SHARED],
25+
},
26+
27+
tasks: {
28+
SYS_TICK: {
29+
path: sys_tick,
30+
resources: [CO_OWNED, ON, SHARED],
31+
},
32+
33+
TIM2: {
34+
enabled: false,
35+
path: tim2,
36+
priority: 1,
37+
resources: [CO_OWNED],
38+
},
39+
},
40+
}
41+
42+
fn init(_p: ::init::Peripherals, _r: ::init::Resources) {}
43+
44+
fn idle(_t: &mut Threshold, _r: ::idle::Resources) -> ! {
45+
loop {}
46+
}
47+
48+
fn sys_tick(_t: &mut Threshold, _r: SYS_TICK::Resources) {}
49+
50+
fn tim2(_t: &mut Threshold, _r: TIM2::Resources) {}

examples/full-syntax.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,22 @@ mod main {
6363
*r.OWNED != *r.OWNED;
6464

6565
if *r.OWNED {
66-
if r.SHARED.claim(t, |shared, _| **shared) {
66+
if r.SHARED.claim(t, |shared, _| *shared) {
6767
rtfm::wfi();
6868
}
6969
} else {
70-
r.SHARED.claim_mut(t, |shared, _| **shared = !**shared);
70+
r.SHARED.claim_mut(t, |shared, _| *shared = !*shared);
7171
}
7272
}
7373
}
7474
}
7575

76-
fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
77-
**r.ON = !**r.ON;
76+
fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) {
77+
*r.ON = !*r.ON;
7878

79-
**r.CO_OWNED += 1;
79+
*r.CO_OWNED += 1;
8080
}
8181

82-
fn tim2(_t: &mut Threshold, r: TIM2::Resources) {
83-
**r.CO_OWNED += 1;
82+
fn tim2(_t: &mut Threshold, mut r: TIM2::Resources) {
83+
*r.CO_OWNED += 1;
8484
}

examples/generics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,5 @@ fn exti0(t: &mut Threshold, r: EXTI0::Resources) {
7070

7171
// This task has direct access to the resources
7272
fn exti1(t: &mut Threshold, r: EXTI1::Resources) {
73-
work(t, r.GPIOA, r.SPI1);
73+
work(t, &r.GPIOA, &r.SPI1);
7474
}

examples/late-resources.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//! Demonstrates initialization of resources in `init`.
2-
32
#![deny(unsafe_code)]
43
#![deny(warnings)]
54
#![feature(proc_macro)]

examples/one-task.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ fn idle() -> ! {
7777
// `r` is the set of resources this task has access to. `SYS_TICK::Resources`
7878
// has one field per resource declared in `app!`.
7979
#[allow(unsafe_code)]
80-
fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
80+
fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) {
8181
// toggle state
82-
**r.ON = !**r.ON;
82+
*r.ON = !*r.ON;
8383

84-
if **r.ON {
84+
if *r.ON {
8585
// set the pin PC13 high
8686
// NOTE(unsafe) atomic write to a stateless register
8787
unsafe {

examples/preemption.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ fn idle() -> ! {
4242
}
4343
}
4444

45-
fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
45+
fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) {
4646
// ..
4747

4848
// This task can't be preempted by `tim2` so it has direct access to the
4949
// resource data
50-
**r.COUNTER += 1;
50+
*r.COUNTER += 1;
5151

5252
// ..
5353
}
@@ -61,7 +61,7 @@ fn tim2(t: &mut Threshold, mut r: TIM2::Resources) {
6161
// lead to undefined behavior.
6262
r.COUNTER.claim_mut(t, |counter, _t| {
6363
// `claim_mut` creates a critical section
64-
**counter += 1;
64+
*counter += 1;
6565
});
6666

6767
// ..

examples/safe-static-mut-ref.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//! Safe creation of `&'static mut` references
2+
#![deny(unsafe_code)]
3+
#![deny(warnings)]
4+
#![feature(proc_macro)]
5+
#![no_std]
6+
7+
extern crate cortex_m_rtfm as rtfm;
8+
extern crate stm32f103xx;
9+
10+
use rtfm::app;
11+
12+
app! {
13+
device: stm32f103xx,
14+
15+
resources: {
16+
static BUFFER: [u8; 16] = [0; 16];
17+
},
18+
19+
init: {
20+
resources: [BUFFER],
21+
},
22+
}
23+
24+
fn init(_p: init::Peripherals, r: init::Resources) {
25+
let _buf: &'static mut [u8] = r.BUFFER;
26+
}
27+
28+
fn idle() -> ! {
29+
loop {
30+
rtfm::wfi();
31+
}
32+
}

examples/two-tasks.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,18 @@ fn idle() -> ! {
4242

4343
// As both tasks are running at the same priority one can't preempt the other.
4444
// Thus both tasks have direct access to the resource
45-
fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
45+
fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) {
4646
// ..
4747

48-
**r.COUNTER += 1;
48+
*r.COUNTER += 1;
4949

5050
// ..
5151
}
5252

53-
fn tim2(_t: &mut Threshold, r: TIM2::Resources) {
53+
fn tim2(_t: &mut Threshold, mut r: TIM2::Resources) {
5454
// ..
5555

56-
**r.COUNTER += 1;
56+
*r.COUNTER += 1;
5757

5858
// ..
5959
}

macros/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ version = "0.2.1"
1212
[dependencies]
1313
error-chain = "0.10.0"
1414
quote = "0.3.15"
15-
rtfm-syntax = "0.2.0"
15+
# rtfm-syntax = "0.2.0"
16+
rtfm-syntax = { git = "https://github.com/japaric/rtfm-syntax" }
1617
syn = "0.11.11"
1718

1819
[lib]

macros/src/analyze.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ pub enum Ownership {
1717
}
1818

1919
impl Ownership {
20+
pub fn ceiling(&self) -> u8 {
21+
match *self {
22+
Ownership::Owned { priority } => priority,
23+
Ownership::Shared { ceiling } => ceiling,
24+
}
25+
}
26+
2027
pub fn is_owned(&self) -> bool {
2128
match *self {
2229
Ownership::Owned { .. } => true,

macros/src/check.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,38 @@ pub fn app(app: check::App) -> Result<App> {
7777
}
7878

7979
fn resources(app: &App) -> Result<()> {
80+
for name in &app.init.resources {
81+
if let Some(resource) = app.resources.get(name) {
82+
ensure!(
83+
resource.expr.is_some(),
84+
"resource `{}`, allocated to `init`, must have an initial value",
85+
name
86+
);
87+
} else {
88+
bail!(
89+
"resource `{}`, allocated to `init`, must be a data resource",
90+
name
91+
);
92+
}
93+
94+
ensure!(
95+
!app.idle.resources.contains(name),
96+
"resources assigned to `init` can't be shared with `idle`"
97+
);
98+
99+
ensure!(
100+
app.tasks
101+
.iter()
102+
.all(|(_, task)| !task.resources.contains(name)),
103+
"resources assigned to `init` can't be shared with tasks"
104+
)
105+
}
106+
80107
for resource in app.resources.keys() {
108+
if app.init.resources.contains(resource) {
109+
continue;
110+
}
111+
81112
if app.idle.resources.contains(resource) {
82113
continue;
83114
}

0 commit comments

Comments
 (0)