diff --git a/book/en/src/by-example/starting_a_project.md b/book/en/src/by-example/starting_a_project.md index c916479aa8..c4f49b6ba1 100644 --- a/book/en/src/by-example/starting_a_project.md +++ b/book/en/src/by-example/starting_a_project.md @@ -1,6 +1,9 @@ # Starting a new project -A recommendation when starting a RTIC project from scratch is to follow RTIC's [`defmt-app-template`]. +A recommendation when starting a RTIC project from scratch on an ARMv7-M or ARMv8-M-main MCU is to +follow RTIC's [`defmt-app-template`]. For ARMv6-M or ARMv8-M-base, check out Section 4.? of +this book for more information on hardware and implementation differences to be aware of before +starting with RTIC. [`defmt-app-template`]: https://github.com/rtic-rs/defmt-app-template diff --git a/book/en/src/internals/targets.md b/book/en/src/internals/targets.md new file mode 100644 index 0000000000..0104cdba8c --- /dev/null +++ b/book/en/src/internals/targets.md @@ -0,0 +1,59 @@ +# Target Architecture + +While RTIC can currently target all Cortex-m devices there are some key architecure differences that +users should be aware. Namely the absence of hardware priority ceiling (BASEPRI) support in the +ARMv6-M and ARMv8-M-base architectures requires a few tweaks from RTIC to deliver the same +features. These differences result in two flavors of critical sections: priority ceiling, and source +masking. Table 1 below shows a list of Cortex-m processors and which type of critical section they +employ. + +#### *Table 1: Critical Section Implementation by Processor Architecture* + +| Processor | Architecture | Priority Ceiling | Source Masking | +| :--------- | :----------: | :--------------: | :------------: | +| Cortex-M0 | ARMv6-M | | ઙ | +| Cortex-M0+ | ARMv6-M | | ઙ | +| Cortex-M3 | ARMv7-M | ઙ | | +| Cortex-M4 | ARMv7-M | ઙ | | +| Cortex-M23 | ARMv8-M-base | | ઙ | +| Cortex-M33 | ARMv8-M-main | ઙ | | +| Cortex-M7 | ARMv7-M | ઙ | | + +## Priority Ceiling + +This implementation is covered in depth by Chapter 4.5 of this book. + +## Source Masking + +Since there is no hardware support for a priority ceiling, RTIC must instead rely on the Nested +Vectored Interrupt Controller (NVIC) present in the core architecture. Consider Figure 1 below, +showing two tasks A and B where A has higher priority but shares a resource with B. + +#### *Figure 1: Shared Resources and Source Masking* + +```text + ┌────────────────────────────────────────────────────────────────┐ + │ │ + │ │ +3 │ Pending Preempts │ +2 │ ↑- - -A- - - - -↓A─────────► │ +1 │ B───────────────────► - - - - B────────► │ +0 │Idle┌─────► Resumes ┌────────► │ + ├────┴────────────────────────────────────────────┴──────────────┤ + │ │ + └────────────────────────────────────────────────────────────────┴──► Time + t1 t2 t3 t4 +``` + +At time *t1*, task B locks the shared resource by selectively disabling all other tasks which share +the resource using the NVIC. In effect this raisis the virtual priority ceiling. Task A is one such +task that shares resources with task B. At time *t2*, task A is either spawned by task B or becomes +pending through an interrupt condition, but does not yet preempt task B even though it's priority is +greater. This is because the NVIC is preventing it from starting due to task A's source mask being +disabled. At time *t3*, task B releases the lock by re-enabling the tasks in the NVIC. Because +task A was pending and has a higher priority than task B, it immediately preempts task B and is +free to use the shared resource without risk of data race conditions. At time *t4*, task A completes +and returns the execution context to B. + +Since source masking relies on use of the NVIC, core exception sources such as HardFault, SVCall, +PendSV, and SysTick cannot share data with other tasks.