diff options
Diffstat (limited to 'book/en/src/internals/ceilings.md')
| -rw-r--r-- | book/en/src/internals/ceilings.md | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/book/en/src/internals/ceilings.md b/book/en/src/internals/ceilings.md index c13df53..6b0530c 100644 --- a/book/en/src/internals/ceilings.md +++ b/book/en/src/internals/ceilings.md @@ -16,61 +16,65 @@ that has a logical priority of `0` whereas `init` is completely omitted from the analysis -- the reason for that is that `init` never uses (or needs) critical sections to access static variables. -In the previous section we showed that a shared resource may appear as a mutable -reference or behind a proxy depending on the task that has access to it. Which -version is presented to the task depends on the task priority and the resource -ceiling. If the task priority is the same as the resource ceiling then the task -gets a mutable reference to the resource memory, otherwise the task gets a -proxy -- this also applies to `idle`. `init` is special: it always gets a -mutable reference to resources. +In the previous section we showed that a shared resource may appear as a unique +reference (`&mut-`) or behind a proxy depending on the task that has access to +it. Which version is presented to the task depends on the task priority and the +resource ceiling. If the task priority is the same as the resource ceiling then +the task gets a unique reference (`&mut-`) to the resource memory, otherwise the +task gets a proxy -- this also applies to `idle`. `init` is special: it always +gets a unique reference (`&mut-`) to resources. An example to illustrate the ceiling analysis: ``` rust #[rtfm::app(device = ..)] const APP: () = { - // accessed by `foo` (prio = 1) and `bar` (prio = 2) - // CEILING = 2 - static mut X: u64 = 0; - - // accessed by `idle` (prio = 0) - // CEILING = 0 - static mut Y: u64 = 0; + struct Resources { + // accessed by `foo` (prio = 1) and `bar` (prio = 2) + // -> CEILING = 2 + #[init(0)] + x: u64, + + // accessed by `idle` (prio = 0) + // -> CEILING = 0 + #[init(0)] + y: u64, + } - #[init(resources = [X])] + #[init(resources = [x])] fn init(c: init::Context) { - // mutable reference because this is `init` - let x: &mut u64 = c.resources.X; + // unique reference because this is `init` + let x: &mut u64 = c.resources.x; - // mutable reference because this is `init` - let y: &mut u64 = c.resources.Y; + // unique reference because this is `init` + let y: &mut u64 = c.resources.y; // .. } // PRIORITY = 0 - #[idle(resources = [Y])] + #[idle(resources = [y])] fn idle(c: idle::Context) -> ! { - // mutable reference because priority (0) == resource ceiling (0) - let y: &'static mut u64 = c.resources.Y; + // unique reference because priority (0) == resource ceiling (0) + let y: &'static mut u64 = c.resources.y; loop { // .. } } - #[interrupt(binds = UART0, priority = 1, resources = [X])] + #[interrupt(binds = UART0, priority = 1, resources = [x])] fn foo(c: foo::Context) { // resource proxy because task priority (1) < resource ceiling (2) - let x: resources::X = c.resources.X; + let x: resources::x = c.resources.x; // .. } - #[interrupt(binds = UART1, priority = 2, resources = [X])] + #[interrupt(binds = UART1, priority = 2, resources = [x])] fn bar(c: foo::Context) { - // mutable reference because task priority (2) == resource ceiling (2) - let x: &mut u64 = c.resources.X; + // unique reference because task priority (2) == resource ceiling (2) + let x: &mut u64 = c.resources.x; // .. } |
