refactor: build system auto-discovery, updated docs
- build.rs discovers boards by content (implements LoRaBoard), not exclusion lists - build.rs auto-discovers helper modules by scanning board files for use super::<helper> - Jinja template dynamically generates cfg gates for helpers - Updated PORTING.md for new architecture (hal/, driver/, BoardParts, associated types) - Zero manual template editing needed when adding boards to existing MCU families
This commit is contained in:
1 parent
ecc451affe
commit
18b509344c
3 files changed
+94
-46
No files matched your search
+25
-21
@@ -5,14 +5,14 @@
|
||||
### 1. Create the board file
|
||||
|
||||
Create `src/board/your_board.rs`. Use an existing board as a template:
|
||||
- ESP32-S3 boards: copy `heltec_v4.rs` (uses shared helpers from `esp32s3.rs`)
|
||||
- nRF52840 boards: copy `rak_wisblock_4631.rs`
|
||||
- ESP32-S3 boards: copy `heltec_v4.rs` (uses shared helpers from `board/esp32s3.rs` and `hal/esp32s3.rs`)
|
||||
- nRF52840 boards: copy `rak_wisblock_4631.rs` (uses shared helpers from `hal/nrf52840.rs`)
|
||||
- New MCU family: create a new `hal/<mcu>.rs` with MCU primitives first
|
||||
|
||||
ESP32-S3 boards share common type aliases, peripheral bundles, and init helpers
|
||||
via `src/board/esp32s3.rs`. Your board file only needs the trait impl and
|
||||
board-specific init (Vext GPIO, display reset). If you add a new ESP32-S3 board,
|
||||
add its feature to the `#[cfg(any(...))]` gate on `mod esp32s3` in
|
||||
`src/board/mod.rs.j2`.
|
||||
`build.rs` auto-discovers your board file — any `.rs` file in `src/board/` that
|
||||
implements `LoRaBoard for Board` is automatically detected as a board. Helper
|
||||
modules (like `esp32s3.rs`) are auto-discovered via `use super::<helper>` imports
|
||||
in board files. No template editing or exclusion lists needed.
|
||||
|
||||
### 2. Define concrete types
|
||||
|
||||
@@ -21,7 +21,9 @@ Your board must export these type aliases:
|
||||
```rust
|
||||
pub type RadioDriver = ...; // Must work with lora_phy::LoRa<RadioDriver, Delay>
|
||||
pub type UsbDriver = ...; // Must implement embassy_usb_driver::Driver<'static>
|
||||
// (or UartDriver for UART boards)
|
||||
pub type DisplayI2c = ...; // Must implement embedded_hal_async::i2c::I2c
|
||||
pub type DisplayDriver = ...; // Must implement DrawTarget<Color = BinaryColor>
|
||||
```
|
||||
|
||||
### 3. Define peripheral bundles
|
||||
@@ -32,39 +34,43 @@ pub struct RadioParts {
|
||||
pub delay: embassy_time::Delay,
|
||||
}
|
||||
|
||||
pub struct UsbParts {
|
||||
pub struct UsbParts { // or UartParts for UART boards
|
||||
pub driver: UsbDriver,
|
||||
}
|
||||
|
||||
pub struct DisplayParts {
|
||||
pub i2c: DisplayI2c,
|
||||
pub mac: [u8; 6],
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Implement the LoRaBoard trait
|
||||
|
||||
```rust
|
||||
use super::traits::LoRaBoard;
|
||||
use super::traits::{BoardParts, LoRaBoard};
|
||||
|
||||
impl LoRaBoard for Board {
|
||||
const NAME: &'static str = "Your Board Name";
|
||||
const TX_POWER_RANGE: (i8, i8) = (-9, 22); // check your radio + PA
|
||||
|
||||
type RadioParts = RadioParts;
|
||||
type CommParts = UsbParts; // or UartParts
|
||||
type DisplayParts = DisplayParts;
|
||||
type DisplayDriver = DisplayDriver;
|
||||
|
||||
fn init() -> Self { ... }
|
||||
fn mac_address() -> [u8; 6] { ... } // read from efuse, FICR, etc.
|
||||
fn into_parts(self) -> BoardParts<RadioParts, UsbParts, DisplayParts> {
|
||||
// Initialize buses via hal::, construct drivers, return BoardParts
|
||||
BoardParts { radio, host, display: Some(display_parts), mac: Self::mac_address() }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The compiler will refuse to build if any of these are missing.
|
||||
|
||||
### 5. Implement `Board::into_parts()`
|
||||
### 5. Add display init
|
||||
|
||||
```rust
|
||||
impl Board {
|
||||
pub fn into_parts(self) -> (RadioParts, UsbParts, Option<DisplayParts>) {
|
||||
// Initialize SPI, DMA, radio, USB, I2C
|
||||
// Return peripheral bundles
|
||||
}
|
||||
pub async fn create_display(i2c: DisplayI2c) -> Option<DisplayDriver> {
|
||||
// Construct and initialize your display driver (SSD1306, SH1106, etc.)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -79,7 +85,7 @@ your_board = ["dep:your-hal", ...]
|
||||
|
||||
### 7. Add to justfile
|
||||
|
||||
Add your board's feature/target/chip to the `boards` list at the top of `justfile`.
|
||||
Add your board's feature/target/chip to the board definitions at the top of `justfile`.
|
||||
|
||||
### 8. Build and test
|
||||
|
||||
@@ -88,5 +94,3 @@ just check your_board # Must compile
|
||||
just clippy your_board # Must be clean
|
||||
just build your_board # Produces firmware
|
||||
```
|
||||
|
||||
`build.rs` auto-discovers your `.rs` file — no template editing needed.
|
||||
+4
-3
@@ -2,9 +2,10 @@
|
||||
pub mod traits;
|
||||
pub use traits::*;
|
||||
|
||||
#[cfg(any(feature = "heltec_v3", feature = "heltec_v4"))]
|
||||
mod esp32s3;
|
||||
|
||||
{% for helper, helper_features in helpers|items -%}
|
||||
#[cfg(any({% for f in helper_features %}feature = "{{ f }}"{% if not loop.last %}, {% endif %}{% endfor %}))]
|
||||
mod {{ helper }};
|
||||
{% endfor %}
|
||||
cfg_if::cfg_if! {
|
||||
{%- for board in boards %}
|
||||
{% if loop.first %}if{% else %}else if{% endif %} #[cfg(feature = "{{ board }}")] {
|
||||
|
||||
Reference in new issue
Block a user