aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/full-syntax.rs40
-rw-r--r--examples/generics.rs7
-rw-r--r--examples/modules.rs76
-rw-r--r--examples/nested.rs48
-rw-r--r--examples/one-task.rs30
-rw-r--r--examples/preemption.rs10
-rw-r--r--examples/two-tasks.rs15
-rw-r--r--examples/zero-tasks.rs14
8 files changed, 84 insertions, 156 deletions
diff --git a/examples/full-syntax.rs b/examples/full-syntax.rs
index 184349b..20e8dfb 100644
--- a/examples/full-syntax.rs
+++ b/examples/full-syntax.rs
@@ -1,5 +1,4 @@
//! A showcase of the `app!` macro syntax
-
#![deny(unsafe_code)]
#![feature(const_fn)]
#![feature(proc_macro)]
@@ -8,7 +7,7 @@
extern crate cortex_m_rtfm as rtfm;
extern crate stm32f103xx;
-use rtfm::{app, Resource, Threshold};
+use rtfm::{app, Threshold};
app! {
device: stm32f103xx,
@@ -21,23 +20,30 @@ app! {
},
init: {
- path: init_, // this is a path to the "init" function
+ // This is the path to the `init` function
+ //
+ // `init` doesn't necessarily has to be in the root of the crate
+ path: main::init,
},
idle: {
- path: idle_, // this is a path to the "idle" function
+ // This is a path to the `idle` function
+ //
+ // `idle` doesn't necessarily has to be in the root of the crate
+ path: main::idle,
resources: [OWNED, SHARED],
},
tasks: {
SYS_TICK: {
path: sys_tick,
- priority: 1,
+ // If omitted priority is assumed to be 1
+ // priority: 1,
resources: [CO_OWNED, ON, SHARED],
},
TIM2: {
- // tasks are enabled, between `init` and `idle`, by default but they
+ // Tasks are enabled, between `init` and `idle`, by default but they
// can start disabled if `false` is specified here
enabled: false,
path: tim2,
@@ -47,18 +53,22 @@ app! {
},
}
-fn init_(_p: init::Peripherals, _r: init::Resources) {}
+mod main {
+ use rtfm::{self, Resource, Threshold};
+
+ pub fn init(_p: ::init::Peripherals, _r: ::init::Resources) {}
-fn idle_(t: &mut Threshold, mut r: idle::Resources) -> ! {
- loop {
- *r.OWNED != *r.OWNED;
+ pub fn idle(t: &mut Threshold, mut r: ::idle::Resources) -> ! {
+ loop {
+ *r.OWNED != *r.OWNED;
- if *r.OWNED {
- if r.SHARED.claim(t, |shared, _| **shared) {
- rtfm::wfi();
+ if *r.OWNED {
+ if r.SHARED.claim(t, |shared, _| **shared) {
+ rtfm::wfi();
+ }
+ } else {
+ r.SHARED.claim_mut(t, |shared, _| **shared = !**shared);
}
- } else {
- r.SHARED.claim_mut(t, |shared, _| **shared = !**shared);
}
}
}
diff --git a/examples/generics.rs b/examples/generics.rs
index 6c6e1d6..57c9b8e 100644
--- a/examples/generics.rs
+++ b/examples/generics.rs
@@ -1,5 +1,4 @@
//! Working with resources in a generic fashion
-
#![deny(unsafe_code)]
#![feature(proc_macro)]
#![no_std]
@@ -36,7 +35,7 @@ fn idle() -> ! {
}
}
-// a generic function to use resources in any task (regardless of its priority)
+// A generic function that uses some resources
fn work<G, S>(t: &mut Threshold, gpioa: &G, spi1: &S)
where
G: Resource<Data = GPIOA>,
@@ -53,12 +52,12 @@ where
});
}
-// this task needs critical sections to access the resources
+// This task needs critical sections to access the resources
fn exti0(t: &mut Threshold, r: EXTI0::Resources) {
work(t, &r.GPIOA, &r.SPI1);
}
-// this task has direct access to the resources
+// This task has direct access to the resources
fn exti1(t: &mut Threshold, r: EXTI1::Resources) {
work(t, r.GPIOA, r.SPI1);
}
diff --git a/examples/modules.rs b/examples/modules.rs
deleted file mode 100644
index 6bdf8d9..0000000
--- a/examples/modules.rs
+++ /dev/null
@@ -1,76 +0,0 @@
-//! Using paths and modules
-#![deny(unsafe_code)]
-#![feature(const_fn)]
-#![feature(proc_macro)]
-#![no_std]
-
-extern crate cortex_m_rtfm as rtfm;
-extern crate stm32f103xx;
-
-use rtfm::app;
-
-app! {
- device: stm32f103xx,
-
- resources: {
- static CO_OWNED: u32 = 0;
- static ON: bool = false;
- static OWNED: bool = false;
- static SHARED: bool = false;
- },
-
- init: {
- path: main::init,
- },
-
- idle: {
- path: main::idle,
- resources: [OWNED, SHARED],
- },
-
- tasks: {
- SYS_TICK: {
- path: tasks::sys_tick,
- resources: [CO_OWNED, ON, SHARED],
- },
-
- TIM2: {
- path: tasks::tim2,
- resources: [CO_OWNED],
- },
- },
-}
-
-mod main {
- use rtfm::{self, Resource, Threshold};
-
- pub fn init(_p: ::init::Peripherals, _r: ::init::Resources) {}
-
- pub fn idle(t: &mut Threshold, mut r: ::idle::Resources) -> ! {
- loop {
- *r.OWNED != *r.OWNED;
-
- if *r.OWNED {
- if r.SHARED.claim(t, |shared, _| **shared) {
- rtfm::wfi();
- }
- } else {
- r.SHARED.claim_mut(t, |shared, _| **shared = !**shared);
- }
- }
- }
-}
-
-pub mod tasks {
- use rtfm::Threshold;
-
- pub fn sys_tick(_t: &mut Threshold, r: ::SYS_TICK::Resources) {
- **r.ON = !**r.ON;
-
- **r.CO_OWNED += 1;
- }
-
- pub fn tim2(_t: &mut Threshold, r: ::TIM2::Resources) {
- **r.CO_OWNED += 1;
- }
-}
diff --git a/examples/nested.rs b/examples/nested.rs
index 92f90cb..7013170 100644
--- a/examples/nested.rs
+++ b/examples/nested.rs
@@ -2,7 +2,6 @@
//!
//! If you run this program you'll hit the breakpoints as indicated by the
//! letters in the comments: A, then B, then C, etc.
-
#![deny(unsafe_code)]
#![feature(const_fn)]
#![feature(proc_macro)]
@@ -46,9 +45,12 @@ app! {
fn init(_p: init::Peripherals, _r: init::Resources) {}
fn idle() -> ! {
- // sets task `exti0` as pending
+ // A
+ rtfm::bkpt();
+
+ // Sets task `exti0` as pending
//
- // because `exti0` has higher priority than `idle` it will be executed
+ // Because `exti0` has higher priority than `idle` it will be executed
// immediately
rtfm::set_pending(Interrupt::EXTI0); // ~> exti0
@@ -58,64 +60,66 @@ fn idle() -> ! {
}
fn exti0(t: &mut Threshold, r: EXTI0::Resources) {
- // because this task has a priority of 1 the preemption threshold is also 1
+ // Because this task has a priority of 1 the preemption threshold `t` also
+ // starts at 1
let mut low = r.LOW;
let mut high = r.HIGH;
- // A
+ // B
rtfm::bkpt();
- // because `exti1` has higher priority than `exti0` it can preempt it
+ // Because `exti1` has higher priority than `exti0` it can preempt it
rtfm::set_pending(Interrupt::EXTI1); // ~> exti1
- // a claim creates a critical section
+ // A claim creates a critical section
low.claim_mut(t, |_low, t| {
- // this claim increases the preemption threshold to 2
- // just high enough to not race with task `exti1` for access to the
+ // This claim increases the preemption threshold to 2
+ //
+ // 2 is just high enough to not race with task `exti1` for access to the
// `LOW` resource
- // C
+ // D
rtfm::bkpt();
- // now `exti1` can't preempt this task because its priority is equal to
+ // Now `exti1` can't preempt this task because its priority is equal to
// the current preemption threshold
rtfm::set_pending(Interrupt::EXTI1);
- // but `exti2` can, because its priority is higher than the current
+ // But `exti2` can, because its priority is higher than the current
// preemption threshold
rtfm::set_pending(Interrupt::EXTI2); // ~> exti2
- // E
+ // F
rtfm::bkpt();
- // claims can be nested
+ // Claims can be nested
high.claim_mut(t, |_high, _| {
// This claim increases the preemption threshold to 3
- // now `exti2` can't preempt this task
+ // Now `exti2` can't preempt this task
rtfm::set_pending(Interrupt::EXTI2);
- // F
+ // G
rtfm::bkpt();
});
- // upon leaving the critical section the preemption threshold drops to 2
- // and `exti2` immediately preempts this task
+ // Upon leaving the critical section the preemption threshold drops back
+ // to 2 and `exti2` immediately preempts this task
// ~> exti2
});
- // once again the preemption threshold drops to 1
- // now the pending `exti1` can preempt this task
+ // Once again the preemption threshold drops but this time to 1. Now the
+ // pending `exti1` task can preempt this task
// ~> exti1
}
fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) {
- // B, H
+ // C, I
rtfm::bkpt();
}
fn exti2(_t: &mut Threshold, _r: EXTI2::Resources) {
- // D, G
+ // E, H
rtfm::bkpt();
}
diff --git a/examples/one-task.rs b/examples/one-task.rs
index e1d598d..556177d 100644
--- a/examples/one-task.rs
+++ b/examples/one-task.rs
@@ -14,11 +14,11 @@ use rtfm::{app, Threshold};
app! {
device: stm32f103xx,
- // Here resources are declared
+ // Here data resources are declared
//
- // Resources are static variables that are safe to share across tasks
+ // Data resources are static variables that are safe to share across tasks
resources: {
- // declaration of resources looks exactly like declaration of static
+ // Declaration of resources looks exactly like declaration of static
// variables
static ON: bool = false;
},
@@ -31,20 +31,24 @@ app! {
tasks: {
// Here we declare that we'll use the SYS_TICK exception as a task
SYS_TICK: {
- // Path to the task *handler*
+ // Path to the task handler
path: sys_tick,
// This is the priority of the task.
//
- // 1 is the lowest priority a task can have.
- // The maximum priority is determined by the number of priority bits
- // the device has. This device has 4 priority bits so 16 is the
- // maximum value.
+ // 1 is the lowest priority a task can have, and the maximum
+ // priority is determined by the number of priority bits the device
+ // has. `stm32f103xx` has 4 priority bits so 16 is the maximum valid
+ // value.
+ //
+ // You can omit this field. If you do the priority is assumed to be
+ // 1.
priority: 1,
- // These are the *resources* associated with this task
+ // These are the resources this task has access to.
//
- // The peripherals that the task needs can be listed here
+ // A resource can be a peripheral like `GPIOC` or a static variable
+ // like `ON`
resources: [GPIOC, ON],
},
}
@@ -75,8 +79,10 @@ fn idle() -> ! {
// This is the task handler of the SYS_TICK exception
//
-// `r` is the resources this task has access to. `SYS_TICK::Resources` has one
-// field per every resource declared in `app!`.
+// `_t` is the preemption threshold token. We won't use it in this program.
+//
+// `r` is the set of resources this task has access to. `TIMER0_A1::Resources`
+// has one field per resource declared in `app!`.
fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
// toggle state
**r.ON = !**r.ON;
diff --git a/examples/preemption.rs b/examples/preemption.rs
index 057e4fd..256b9bd 100644
--- a/examples/preemption.rs
+++ b/examples/preemption.rs
@@ -1,4 +1,4 @@
-//! Two tasks running at different priorities with access to the same resource
+//! Two tasks running at *different* priorities with access to the same resource
#![deny(unsafe_code)]
#![feature(const_fn)]
#![feature(proc_macro)]
@@ -17,7 +17,7 @@ app! {
},
tasks: {
- // the task `SYS_TICK` has higher priority than `TIM2`
+ // The `SYS_TICK` task has higher priority than `TIM2`
SYS_TICK: {
path: sys_tick,
priority: 2,
@@ -45,7 +45,7 @@ fn idle() -> ! {
fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
// ..
- // this task can't be preempted by `tim2` so it has direct access to the
+ // This task can't be preempted by `tim2` so it has direct access to the
// resource data
**r.COUNTER += 1;
@@ -55,10 +55,10 @@ fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
fn tim2(t: &mut Threshold, mut r: TIM2::Resources) {
// ..
- // as this task runs at lower priority it needs a critical section to
+ // As this task runs at lower priority it needs a critical section to
// prevent `sys_tick` from preempting it while it modifies this resource
// data. The critical section is required to prevent data races which can
- // lead to data corruption or data loss
+ // lead to undefined behavior
r.COUNTER.claim_mut(t, |counter, _t| { **counter += 1; });
// ..
diff --git a/examples/two-tasks.rs b/examples/two-tasks.rs
index 42b91e4..ea059a0 100644
--- a/examples/two-tasks.rs
+++ b/examples/two-tasks.rs
@@ -1,4 +1,4 @@
-//! Two tasks running at the same priority with access to the same resource
+//! Two tasks running at the *same* priority with access to the same resource
#![deny(unsafe_code)]
#![feature(const_fn)]
@@ -13,34 +13,25 @@ use rtfm::{app, Threshold};
app! {
device: stm32f103xx,
- // Resources that are plain data, not peripherals
resources: {
- // Declaration of resources looks like the declaration of `static`
- // variables
static COUNTER: u64 = 0;
},
+ // Both SYS_TICK and TIM2 have access to the `COUNTER` data
tasks: {
SYS_TICK: {
path: sys_tick,
- priority: 1,
- // Both this task and TIM2 have access to the `COUNTER` resource
resources: [COUNTER],
},
- // An interrupt as a task
TIM2: {
- // For interrupts the `enabled` field must be specified. It
- // indicates if the interrupt will be enabled or disabled once
- // `idle` starts
path: tim2,
- priority: 1,
resources: [COUNTER],
},
},
}
-// when data resources are declared in the top `resources` field, `init` will
+// When data resources are declared in the top `resources` field, `init` will
// have full access to them
fn init(_p: init::Peripherals, _r: init::Resources) {
// ..
diff --git a/examples/zero-tasks.rs b/examples/zero-tasks.rs
index 1320167..9176103 100644
--- a/examples/zero-tasks.rs
+++ b/examples/zero-tasks.rs
@@ -1,7 +1,7 @@
//! Minimal example with zero tasks
-
#![deny(unsafe_code)]
-#![feature(proc_macro)] // IMPORTANT always include this feature gate
+// IMPORTANT always include this feature gate
+#![feature(proc_macro)]
#![no_std]
extern crate cortex_m_rtfm as rtfm; // IMPORTANT always do this rename
@@ -15,7 +15,7 @@ use rtfm::app;
// This macro will expand to a `main` function so you don't need to supply
// `main` yourself.
app! {
- // this is a path to the device crate
+ // this is the path to the device crate
device: stm32f103xx,
}
@@ -28,20 +28,14 @@ fn init(p: init::Peripherals) {
p.GPIOA;
p.RCC;
// ..
-
- // You'll hit this breakpoint first
- rtfm::bkpt();
}
// The idle loop.
//
-// This runs afterwards and has a priority of 0. All tasks can preempt this
+// This runs after `init` and has a priority of 0. All tasks can preempt this
// function. This function can never return so it must contain some sort of
// endless loop.
fn idle() -> ! {
- // And then this breakpoint
- rtfm::bkpt();
-
loop {
// This puts the processor to sleep until there's a task to service
rtfm::wfi();