Skip to content

Commit 79ecfbf

Browse files
committed
Add hardware initialization module
Implement bootloader/src/init.rs with: - BootHardware struct to represent initialized system state - InitError enum and Result type for robust error handling - init_hardware() entry point to configure clocks, flash, and essential peripherals - Feature-flag stubs for MCU families (e.g. stm32f4, nrf52) - Helper functions for flash interface, peripherals, and system clock frequency - Basic unit test validating default initialization Provides a clean, MCU-agnostic starting point for setting up bootloader hardware and is ready for platform-specific logic.
1 parent af42ce2 commit 79ecfbf

File tree

1 file changed

+133
-4
lines changed

1 file changed

+133
-4
lines changed

bootloader/src/init.rs

Lines changed: 133 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! M2 Bootloader RUST
1+
//! M2 Bootloader RUST
22
//! ------------------
33
//! License : Dual License
44
//! - Apache 2.0 for open-source / personal use
@@ -7,6 +7,135 @@
77
//! URL : <https://m-a-h-b-u-b.github.io>
88
//! GitHub : <https://github.com/m-a-h-b-u-b/M2-Bootloader-RUST>
99
10-
pub fn init_hardware() {
11-
// Initialize clocks, watchdog, GPIO pins
12-
}
10+
//! Hardware initialization module.
11+
//!
12+
//! This module provides a high-level abstraction for initializing the
13+
//! microcontroller hardware required by the bootloader. It prepares the
14+
//! system clock, flash interface, and any peripherals (UART/USB) used for
15+
//! firmware updates. The implementation is MCU-agnostic with hooks for
16+
//! specific hardware families via feature flags.
17+
18+
use core::fmt;
19+
20+
/// Boot error types returned during hardware initialization.
21+
#[derive(Debug)]
22+
pub enum InitError {
23+
ClockConfig,
24+
FlashConfig,
25+
PeripheralInit,
26+
Other(&'static str),
27+
}
28+
29+
impl fmt::Display for InitError {
30+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31+
match self {
32+
InitError::ClockConfig => write!(f, "Clock configuration failed"),
33+
InitError::FlashConfig => write!(f, "Flash interface configuration failed"),
34+
InitError::PeripheralInit => write!(f, "Peripheral initialization failed"),
35+
InitError::Other(msg) => write!(f, "Other init error: {}", msg),
36+
}
37+
}
38+
}
39+
40+
/// Result type for hardware initialization.
41+
pub type Result<T> = core::result::Result<T, InitError>;
42+
43+
/// Represents the bootloader hardware state.
44+
/// In a real implementation this may hold MCU-specific peripherals or handles.
45+
pub struct BootHardware {
46+
pub clock_speed_hz: u32,
47+
pub flash_ready: bool,
48+
pub peripherals_ready: bool,
49+
}
50+
51+
impl BootHardware {
52+
/// Create a new BootHardware instance with default placeholders.
53+
pub const fn new() -> Self {
54+
BootHardware {
55+
clock_speed_hz: 0,
56+
flash_ready: false,
57+
peripherals_ready: false,
58+
}
59+
}
60+
}
61+
62+
/// Initialize all hardware required for the bootloader.
63+
///
64+
/// This function should:
65+
/// - Configure the system clock.
66+
/// - Enable and configure the flash memory interface.
67+
/// - Initialize essential peripherals (UART/USB) for communication.
68+
///
69+
/// Feature flags can be used to include MCU-specific implementations.
70+
/// For example:
71+
/// ```toml
72+
/// [features]
73+
/// stm32f4 = []
74+
/// nrf52 = []
75+
/// ```
76+
///
77+
/// # Safety
78+
/// Must be called once at system start before other hardware access.
79+
pub fn init_hardware() -> Result<BootHardware> {
80+
// System clock configuration placeholder.
81+
#[cfg(feature = "stm32f4")]
82+
stm32f4_clock_setup()?;
83+
#[cfg(feature = "nrf52")]
84+
nrf52_clock_setup()?;
85+
86+
// Flash interface setup placeholder.
87+
flash_interface_setup()?;
88+
89+
// Peripheral setup placeholder (UART/USB, etc.).
90+
peripherals_setup()?;
91+
92+
Ok(BootHardware {
93+
clock_speed_hz: system_clock_hz(),
94+
flash_ready: true,
95+
peripherals_ready: true,
96+
})
97+
}
98+
99+
// Below are dummy stubs for platform-specific implementations.
100+
// Replace with actual HAL or register-level code.
101+
#[cfg(feature = "stm32f4")]
102+
fn stm32f4_clock_setup() -> Result<()> {
103+
// TODO: configure PLL, flash wait states, bus prescalers, etc.
104+
Ok(())
105+
}
106+
107+
#[cfg(feature = "nrf52")]
108+
fn nrf52_clock_setup() -> Result<()> {
109+
// TODO: enable HFCLK and set correct source.
110+
Ok(())
111+
}
112+
113+
fn flash_interface_setup() -> Result<()> {
114+
// TODO: configure flash wait states, caches, or unlock sequences.
115+
Ok(())
116+
}
117+
118+
fn peripherals_setup() -> Result<()> {
119+
// TODO: initialize UART/USB or other communication peripherals.
120+
Ok(())
121+
}
122+
123+
/// Query the configured system clock frequency (in Hz).
124+
/// Replace with MCU-specific readback.
125+
fn system_clock_hz() -> u32 {
126+
// Example placeholder: 48 MHz.
127+
48_000_000
128+
}
129+
130+
#[cfg(test)]
131+
mod tests {
132+
use super::*;
133+
134+
#[test]
135+
fn test_init_hardware_success() {
136+
let hw = init_hardware().unwrap();
137+
assert!(hw.flash_ready);
138+
assert!(hw.peripherals_ready);
139+
assert_eq!(hw.clock_speed_hz, 48_000_000);
140+
}
141+
}

0 commit comments

Comments
 (0)