1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//! The lowered IR: one node per thing the manifest asks the system to have, each
//! owning the code or device-tree it generates.
//!
//! [`bridge`](crate::bridge) builds these from a validated
//! [`Session`](crate::Session); this module is where "the manifest declares two IPC
//! channels" becomes actual `Channel::new(..)` expressions, `reserved-memory`
//! carveouts, and NVIC enables.
//!
//! Codegen is deliberately *not* centralised. Each IR type emits its own output —
//! [`ShuHan::initialize`](ipc_shm::ShuHan::initialize),
//! [`BellA::nvic_enable`](bella::BellA::nvic_enable),
//! [`ToUio::to_uio`](uio::ToUio::to_uio) — so a new component adds a module rather
//! than a branch in a shared emitter.
//!
//! | Module | Emits |
//! | ----------------- | --------------------------------------------------------- |
//! | [`ipc_shm`] | Channel instances and unsplit transport installation. |
//! | [`bella`] | Type-A doorbell interrupt enablement. |
//! | [`peripheral`] | HAL driver handles, interrupt handlers, NVIC enablement. |
//! | [`time`] | The sealed Embassy time-driver vector and `defmt::timestamp!`. |
//! | `dbg` | Nothing — resolves debug ring layout for the builder's env vars. |
//! | [`uio`] | `generic-uio` DTS nodes and their `reserved-memory` carveouts. |
//! | [`memory_to_uio`] | Groups shared-memory regions onto one UIO device. |
//! | [`dts_render`] | The Linux device tree, merged onto a vendor base or as an overlay. |
//! | [`irq`] | How a line is named: the PAC's `Interrupt` variant, or a raw number. |
//! | [`address`] | Shared address resolution: AP `uioN`/`mmap_id` vs a controller's physical base. |
//! | [`region`] | One shared-memory window's construction expression. |
//!
//! Two conventions worth knowing before adding a component:
//!
//! - **Emitted `unsafe` blocks carry their justification as a `///` doc comment,**
//! not a `//` comment. `proc_macro2` discards `//` comments because they are not
//! tokens, so [`render()`](crate::render()) rewrites the doc lines back into ordinary
//! comments after formatting. That is what satisfies
//! `clippy::undocumented_unsafe_blocks` in the generated crate.
//! - **Items referencing a chip HAL are gated to `target_arch = "arm"`,** because the
//! host trybuild harness never links one.
//! - **Interrupt vectors are emitted as bare `#[interrupt] fn <LINE>()` items** and
//! collected by [`bridge`](crate::bridge) into one `__consortium_vectors` module.
//! cortex-m-rt's attribute expands to an `interrupt::<LINE>;` existence check, so
//! that module supplies the `use <hal>::interrupt;` the check resolves against —
//! keeping the generated file independent of the firmware crate's own imports. It
//! does mean generated firmware must enable the chip HAL's `rt` feature.