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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//! `hilt` — hardware-in-the-loop test fixtures for embedded Rust.
//!
//! Runs compiled firmware inside a [Renode](https://renode.io) simulation in a
//! Podman/Docker container, captures its output, and lets host tests assert on
//! it. It supports three firmware-verification styles, and mixes them freely:
//!
//! * **Self-reporting firmware** — a generic Cortex-M board ([`CpuInit::VectorTable`]).
//! `hilt` reads the ELF's vector table, sets `SP`/`PC`, and hooks a marker
//! symbol to log `HIL OK` (and a fail symbol / the panic handler to log
//! `HIL FAIL`). Fail ends the run at once, as does pass for a lone
//! machine with no host bridge. Assert with
//! [`HilOutput::passed`] / [`HilOutput::failed`] / [`assert_hil_ok!`];
//! console UART text is in [`HilOutput::uart`]. Great for one firmware
//! image per test.
//! * **Live CAN interaction** — board-described platforms ([`CpuInit::Board`])
//! wired into a CAN hub, with any machine optionally bridged to a host
//! SocketCAN interface ([`MachineSpec::with_socketcan_bridge`]). Host code
//! then exchanges frames with the firmware over `vcan` and asserts on
//! protocol behavior. Multiple machines are supported; Linux hosts only.
//! * **Live UART interaction** — any machine's UART exposed to the host as a
//! raw TCP socket ([`MachineSpec::with_uart_bridge`]). Start the run with
//! [`RenodeRunner::spawn`], connect with [`RunningHil::connect_uart`], and
//! exchange bytes with the firmware's serial line; works on macOS/Windows
//! hosts too.
//!
//! # Quick start (single self-reporting firmware)
//!
//! ```no_run
//! use hilt::{HilConfig, Platform, RenodeRunner, assert_hil_ok};
//!
//! let output = RenodeRunner::new(HilConfig::single(
//! Platform::rp2040(),
//! "target/thumbv6m-none-eabi/release/examples/hil_keyboard",
//! ))
//! .run();
//! assert_hil_ok!(output);
//! ```
//!
//! # Quick start (multi-machine CAN with a host bridge)
//!
//! ```no_run
//! use hilt::{HilConfig, MachineSpec, Platform, RenodeRunner};
//!
//! let machines = vec![
//! MachineSpec::new("controller", "controller.elf", Platform::stm32h7())
//! .with_socketcan_bridge(),
//! MachineSpec::new("sensor", "sensor.elf", Platform::stm32h7()),
//! ];
//! // hilt::setup_vcan("vcan0"); // once, with privileges
//! let run = RenodeRunner::new(HilConfig::multi(machines)).spawn();
//! // ... open vcan0 and exercise the firmware ...
//! let output = run.wait();
//! ```
//!
//! External requirements: `podman` or `docker` (or a native `renode`). The
//! firmware ELF's vector table and symbols are read in pure Rust.
//!
//! [`CpuInit::VectorTable`]: crate::CpuInit::VectorTable
//! [`CpuInit::Board`]: crate::CpuInit::Board
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
// `assert_hil_ok!` is exported at the crate root by `#[macro_export]`.
/// Serializes tests that read or mutate process-global env vars (which are
/// shared across cargo's parallel test threads).
pub