diff options
| author | Emil Fresk <emil.fresk@gmail.com> | 2020-11-12 18:19:00 +0100 |
|---|---|---|
| committer | Emil Fresk <emil.fresk@gmail.com> | 2020-11-12 18:19:00 +0100 |
| commit | 5e3bbada638d1751d7c48b4ec0979c0468080e4d (patch) | |
| tree | 3ae2ede9423963bb6fc4ef346ffdb931e8216179 /book | |
| parent | ad50b54530b7068dde3227dfb72f2a641171af61 (diff) | |
Updated migration guide with symmetric locks and new spawn
Diffstat (limited to 'book')
| -rw-r--r-- | book/en/src/migration/migration_v5.md | 122 |
1 files changed, 96 insertions, 26 deletions
diff --git a/book/en/src/migration/migration_v5.md b/book/en/src/migration/migration_v5.md index 44af15e..8edefd2 100644 --- a/book/en/src/migration/migration_v5.md +++ b/book/en/src/migration/migration_v5.md @@ -6,61 +6,62 @@ This section describes how to upgrade from v0.5.x to v0.6.0 of the RTIC framewor Change the version of `cortex-m-rtic` to `"0.6.0"`. -## Move Dispatchers from `extern "C"` to app arguments. +## `mod` instead of `const` + +With the support of attributes on modules the `const APP` workaround is not needed. Change ``` rust #[rtic::app(/* .. */)] const APP: () = { - [code here] - - // RTIC requires that unused interrupts are declared in an extern block when - // using software tasks; these free interrupts will be used to dispatch the - // software tasks. - extern "C" { - fn SSI0(); - fn QEI0(); - } + [code here] }; ``` into ``` rust -#[rtic::app(/* .. */, dispatchers = [SSI0, QEI0])] +#[rtic::app(/* .. */)] mod app { [code here] } ``` -This works also for ram functions, see examples/ramfunc.rs - -## Module instead of Const +Now that a regular Rust module is used it means it is possible to have custom +user code within that module. +Additionally, it means that `use`-statements for resources etc may be required. -With the support of attributes on modules the `const APP` workaround is not needed. +## Move Dispatchers from `extern "C"` to app arguments. Change ``` rust #[rtic::app(/* .. */)] const APP: () = { - [code here] + [code here] + + // RTIC requires that unused interrupts are declared in an extern block when + // using software tasks; these free interrupts will be used to dispatch the + // software tasks. + extern "C" { + fn SSI0(); + fn QEI0(); + } }; ``` into ``` rust -#[rtic::app(/* .. */)] +#[rtic::app(/* .. */, dispatchers = [SSI0, QEI0])] mod app { [code here] } ``` -Now that a regular Rust module is used it means it is possible to have custom -user code within that module. -Additionally, it means that `use`-statements for resources etc may be required. +This works also for ram functions, see examples/ramfunc.rs + ## Init always returns late resources @@ -75,7 +76,8 @@ mod app { fn init(_: init::Context) { rtic::pend(Interrupt::UART0); } - [more code] + + // [more code] } ``` @@ -90,11 +92,12 @@ mod app { init::LateResources {} } - [more code] + + // [more code] } ``` -## Resources struct - #[resources] +## Resources struct - `#[resources]` Previously the RTIC resources had to be in in a struct named exactly "Resources": @@ -118,19 +121,86 @@ In fact, the name of the struct is now up to the developer: ``` rust #[resources] -struct whateveryouwant { +struct Whateveryouwant { // Resources defined in here } ``` would work equally well. +## Spawn/schedule from anywhere + +With the new "spawn/schedule from anywhere", old code such as: + + + +``` rust +#[task(spawn = [bar])] +fn foo(cx: foo::Context) { + cx.spawn.bar().unwrap(); +} + +#[task(schedule = [bar])] +fn bar(cx: bar::Context) { + cx.schedule.foo(/* ... */).unwrap(); +} +``` + +Will now be written as: + +``` rust +#[task] +fn foo(_c: foo::Context) { + bar::spawn().unwrap(); +} + +#[task] +fn bar(_c: bar::Context) { + foo::schedule(/* ... */).unwrap(); +} +``` + +Note that the attributes `spawn` and `schedule` are no longer needed. + +## Symmetric locks + +Now RTIC utilizes symmetric locks, this means that the `lock` method need to be used for all resource access. In old code one could do the following as the high priority task has exclusive access to the resource: + +``` rust +#[task(priority = 2, resources = [r])] +fn foo(cx: foo::Context) { + cx.resources.r = /* ... */; +} + +#[task(resources = [r])] +fn bar(cx: bar::Context) { + cx.resources.r.lock(|r| r = /* ... */); +} +``` + +And with symmetric locks one needs to use locks in both tasks: + +``` rust +#[task(priority = 2, resources = [r])] +fn foo(cx: foo::Context) { + cx.resources.r.lock(|r| r = /* ... */); +} + +#[task(resources = [r])] +fn bar(cx: bar::Context) { + cx.resources.r.lock(|r| r = /* ... */); +} +``` + +Note that the performance does not change thanks to LLVM's optimizations which optimizes away unnecessary locks. + --- ## Additions ### Extern tasks -Both software and hardware tasks can now be defined external to the `mod app`. Previously this was possible only by implementing a trampoline calling out the task implementation. +Both software and hardware tasks can now be defined external to the `mod app`. Previously this was possible only by implementing a trampoline calling out the task implementation. + +See examples `examples/extern_binds.rs` and `examples/extern_spawn.rs`. -See examples `examples/extern_binds.rs` and `examples/extern_spawn.rs`.
\ No newline at end of file |
