diff options
Diffstat (limited to 'book/en/src/by-example/tips')
| -rw-r--r-- | book/en/src/by-example/tips/destructureing.md | 15 | ||||
| -rw-r--r-- | book/en/src/by-example/tips/index.md | 3 | ||||
| -rw-r--r-- | book/en/src/by-example/tips/indirection.md | 26 | ||||
| -rw-r--r-- | book/en/src/by-example/tips/static_lifetimes.md | 23 | ||||
| -rw-r--r-- | book/en/src/by-example/tips/view_code.md | 47 |
5 files changed, 114 insertions, 0 deletions
diff --git a/book/en/src/by-example/tips/destructureing.md b/book/en/src/by-example/tips/destructureing.md new file mode 100644 index 0000000..752311d --- /dev/null +++ b/book/en/src/by-example/tips/destructureing.md @@ -0,0 +1,15 @@ +# Resource de-structure-ing + +Destructuring task resources might help readability if a task takes multiple +resources. Here are two examples on how to split up the resource struct: + +``` rust,noplayground +{{#include ../../../../../rtic/examples/destructure.rs}} +``` + +``` console +$ cargo run --target thumbv7m-none-eabi --example destructure +``` +``` console +{{#include ../../../../../rtic/ci/expected/destructure.run}} +``` diff --git a/book/en/src/by-example/tips/index.md b/book/en/src/by-example/tips/index.md new file mode 100644 index 0000000..18d5991 --- /dev/null +++ b/book/en/src/by-example/tips/index.md @@ -0,0 +1,3 @@ +# Tips & tricks + +In this section we will explore common tips & tricks related to using RTIC. diff --git a/book/en/src/by-example/tips/indirection.md b/book/en/src/by-example/tips/indirection.md new file mode 100644 index 0000000..aa68190 --- /dev/null +++ b/book/en/src/by-example/tips/indirection.md @@ -0,0 +1,26 @@ +# Using 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. + +Indirection can minimize message passing overhead: instead of sending the buffer by value, one can send an owning pointer into the buffer. + +One can use a global memory 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/latest/heapless/pool/index.html + +As this example of approach goes completely outside of RTIC resource model with shared and local the program would rely on the correctness of the memory allocator, in this case `heapless::pool`. + +Here's an example where `heapless::Pool` is used to "box" buffers of 128 bytes. + +``` rust,noplayground +{{#include ../../../../../rtic/examples/pool.rs}} +``` + +``` console +$ cargo run --target thumbv7m-none-eabi --example pool +``` + +``` console +{{#include ../../../../../rtic/ci/expected/pool.run}} +``` diff --git a/book/en/src/by-example/tips/static_lifetimes.md b/book/en/src/by-example/tips/static_lifetimes.md new file mode 100644 index 0000000..f4e4829 --- /dev/null +++ b/book/en/src/by-example/tips/static_lifetimes.md @@ -0,0 +1,23 @@ +# 'static super-powers + +In `#[init]` and `#[idle]` `local` resources have `'static` lifetime. + +Useful when pre-allocating and/or splitting resources between tasks, drivers or some other object. This comes in handy when drivers, such as USB drivers, need to allocate memory and when using splittable data structures such as [`heapless::spsc::Queue`]. + +In the following example two different tasks share a [`heapless::spsc::Queue`] for lock-free access to the shared queue. + +[`heapless::spsc::Queue`]: https://docs.rs/heapless/0.7.5/heapless/spsc/struct.Queue.html + +``` rust,noplayground +{{#include ../../../../../rtic/examples/static.rs}} +``` + +Running this program produces the expected output. + +``` console +$ cargo run --target thumbv7m-none-eabi --example static +``` + +``` console +{{#include ../../../../../rtic/ci/expected/static.run}} +``` diff --git a/book/en/src/by-example/tips/view_code.md b/book/en/src/by-example/tips/view_code.md new file mode 100644 index 0000000..64af7ad --- /dev/null +++ b/book/en/src/by-example/tips/view_code.md @@ -0,0 +1,47 @@ +# Inspecting generated 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 smallest --target thumbv7m-none-eabi +``` + +``` console +$ rustfmt target/rtic-expansion.rs +``` + +``` console +$ tail target/rtic-expansion.rs +``` + +``` rust,noplayground +#[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 +``` + +``` console +cargo expand --example smallest | tail +``` |
