diff options
Diffstat (limited to 'book/en/src/by-example/tips.md')
| -rw-r--r-- | book/en/src/by-example/tips.md | 175 |
1 files changed, 1 insertions, 174 deletions
diff --git a/book/en/src/by-example/tips.md b/book/en/src/by-example/tips.md index e292634..18d5991 100644 --- a/book/en/src/by-example/tips.md +++ b/book/en/src/by-example/tips.md @@ -1,176 +1,3 @@ # Tips & tricks -For complete RTIC examples see the [rtic-examples][rtic-examples] repository. - -[rtic-examples]: https://github.com/rtic-rs/rtic-examples - -## Generics - -All resource proxies implement the `rtic::Mutex` trait. -If a resource does not implement this, one can wrap it in the [`rtic::Exclusive`] -newtype which does implement the `Mutex` trait. With the help of this newtype -one can write a generic function that operates on generic resources and call it -from different tasks to perform some operation on the same set of resources. -Here's one such example: - -[`rtic::Exclusive`]: ../../../api/rtic/struct.Exclusive.html - -``` rust -{{#include ../../../../examples/generics.rs}} -``` - -``` console -$ cargo run --example generics -{{#include ../../../../ci/expected/generics.run}} -``` - -## Conditional compilation - -You can use conditional compilation (`#[cfg]`) on resources (the fields of -`#[resources] struct Resources`) and tasks (the `fn` items). -The effect of using `#[cfg]` attributes is that the resource / task -will *not* be available through the corresponding `Context` `struct` -if the condition doesn't hold. - -The example below logs a message whenever the `foo` task is spawned, but only if -the program has been compiled using the `dev` profile. - -``` rust -{{#include ../../../../examples/cfg.rs}} -``` - -``` console -$ cargo run --example cfg --release - -$ cargo run --example cfg -{{#include ../../../../ci/expected/cfg.run}} -``` - -## Running tasks from RAM - -The main goal of moving the specification of RTIC applications to attributes in -RTIC v0.4.0 was to allow inter-operation with other attributes. For example, the -`link_section` attribute can be applied to tasks to place them in RAM; this can -improve performance in some cases. - -> **IMPORTANT**: In general, the `link_section`, `export_name` and `no_mangle` -> attributes are very powerful but also easy to misuse. Incorrectly using any of -> these attributes can cause undefined behavior; you should always prefer to use -> safe, higher level attributes around them like `cortex-m-rt`'s `interrupt` and -> `exception` attributes. -> -> In the particular case of RAM functions there's no -> safe abstraction for it in `cortex-m-rt` v0.6.5 but there's an [RFC] for -> adding a `ramfunc` attribute in a future release. - -[RFC]: https://github.com/rust-embedded/cortex-m-rt/pull/100 - -The example below shows how to place the higher priority task, `bar`, in RAM. - -``` rust -{{#include ../../../../examples/ramfunc.rs}} -``` - -Running this program produces the expected output. - -``` console -$ cargo run --example ramfunc -{{#include ../../../../ci/expected/ramfunc.run}} -``` - -One can look at the output of `cargo-nm` to confirm that `bar` ended in RAM -(`0x2000_0000`), whereas `foo` ended in Flash (`0x0000_0000`). - -``` console -$ cargo nm --example ramfunc --release | grep ' foo::' -{{#include ../../../../ci/expected/ramfunc.grep.foo}} -``` - -``` console -$ cargo nm --example ramfunc --release | grep ' bar::' -{{#include ../../../../ci/expected/ramfunc.grep.bar}} -``` - -## Indirection for faster message passing - -Message passing always involves copying the payload from the sender into a -static variable and then from the static variable into the receiver. Thus -sending a large buffer, like a `[u8; 128]`, as a message involves two expensive -`memcpy`s. To minimize the message passing overhead one can use indirection: -instead of sending the buffer by value, one can send an owning pointer into the -buffer. - -One can use a global allocator to achieve indirection (`alloc::Box`, -`alloc::Rc`, etc.), which requires using the nightly channel as of Rust v1.37.0, -or one can use a statically allocated memory pool like [`heapless::Pool`]. - -[`heapless::Pool`]: https://docs.rs/heapless/0.5.0/heapless/pool/index.html - -Here's an example where `heapless::Pool` is used to "box" buffers of 128 bytes. - -``` rust -{{#include ../../../../examples/pool.rs}} -``` - -``` console -$ cargo run --example pool -{{#include ../../../../ci/expected/pool.run}} -``` - -## Inspecting the expanded code - -`#[rtic::app]` is a procedural macro that produces support code. If for some -reason you need to inspect the code generated by this macro you have two -options: - -You can inspect the file `rtic-expansion.rs` inside the `target` directory. This -file contains the expansion of the `#[rtic::app]` item (not your whole program!) -of the *last built* (via `cargo build` or `cargo check`) RTIC application. The -expanded code is not pretty printed by default so you'll want to run `rustfmt` -on it before you read it. - -``` console -$ cargo build --example foo - -$ rustfmt target/rtic-expansion.rs - -$ tail target/rtic-expansion.rs -``` - -``` rust -#[doc = r" Implementation details"] -mod app { - #[doc = r" Always include the device crate which contains the vector table"] - use lm3s6965 as _; - #[no_mangle] - unsafe extern "C" fn main() -> ! { - rtic::export::interrupt::disable(); - let mut core: rtic::export::Peripherals = core::mem::transmute(()); - core.SCB.scr.modify(|r| r | 1 << 1); - rtic::export::interrupt::enable(); - loop { - rtic::export::wfi() - } - } -} -``` - -Or, you can use the [`cargo-expand`] sub-command. This sub-command will expand -*all* the macros, including the `#[rtic::app]` attribute, and modules in your -crate and print the output to the console. - -[`cargo-expand`]: https://crates.io/crates/cargo-expand - -``` console -$ # produces the same output as before -$ cargo expand --example smallest | tail -``` - -## Resource de-structure-ing - -When having a task taking multiple resources it can help in readability to split -up the resource struct. Here are two examples on how this can be done: - -``` rust -{{#include ../../../../examples/destructure.rs}} -``` +In this section we will explore common tips & tricks related to using RTIC. |
