Skip to content

Commit

Permalink
Merge pull request #47 from SteelPh0enix/system-hal-rename
Browse files Browse the repository at this point in the history
ROS#156: SystemHal -> AerugoHal and HAL refactor
  • Loading branch information
SteelPh0enix authored Aug 31, 2023
2 parents 6b7714b + ee40460 commit 2907d56
Show file tree
Hide file tree
Showing 43 changed files with 218 additions and 191 deletions.
20 changes: 11 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
members = [
"aerugo-hal",
"arch/cortex-m/aerugo-cortex-m",
"arch/cortex-m/aerugo-samv71-hal",
"arch/cortex-m/samv71-hal",
"arch/cortex-m/samv71q21-pac",
"arch/x86/aerugo-x86",
"arch/x86/x86-hal",
"arch/x86/aerugo-x86-hal",
"utils/env-parser",
"utils/env-parser-tests",
"utils/internal_cell",
Expand Down Expand Up @@ -44,26 +45,27 @@ keywords = ["rtos", "space"]
categories = ["aerospace", "embedded", "hardware-support", "no-std"]

[dependencies]
heapless = "0.7"
bare-metal = "0.2.4"
aerugo-hal = { version = "0.1.0", path = "aerugo-hal" }
aerugo-cortex-m = { version = "0.1.0", path = "arch/cortex-m/aerugo-cortex-m", optional = true }
samv71-hal = { version = "0.1.0", path = "arch/cortex-m/samv71-hal", optional = true }
aerugo-hal = { version = "0.1.0", path = "aerugo-hal" }
aerugo-samv71-hal = { version = "0.1.0", path = "arch/cortex-m/aerugo-samv71-hal", optional = true }
aerugo-x86 = { version = "0.1.0", path = "arch/x86/aerugo-x86", optional = true }
x86-hal = { version = "0.1.0", path = "arch/x86/x86-hal", optional = true }
aerugo-x86-hal = { version = "0.1.0", path = "arch/x86/aerugo-x86-hal", optional = true }
bare-metal = "0.2.4"
env-parser = { version = "1.0.0", path = "utils/env-parser" }
heapless = "0.7"
internal-cell = { version = "0.0.1", path = "utils/internal_cell" }
samv71-hal = { version = "0.1.0", path = "arch/cortex-m/samv71-hal", optional = true }

[dev-dependencies]
test-binary = "3.0"
assert_cmd = "2.0"

[features]
default = ["log"]
use-aerugo-cortex-m = ["aerugo-cortex-m", "samv71-hal"]
use-aerugo-x86 = ["aerugo-x86", "x86-hal"]
use-aerugo-cortex-m = ["aerugo-cortex-m", "aerugo-samv71-hal"]
use-aerugo-x86 = ["aerugo-x86", "aerugo-x86-hal"]
test-aerugo-cortex-m = ["use-aerugo-x86"]
rt = ["samv71-hal?/rt"]
rt = ["aerugo-samv71-hal?/rt"]
log = ["aerugo-cortex-m?/log", "aerugo-x86?/log"]

[profile.release]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
//! System HAL configuration structures.

use crate::time;

/// System hardware configuration.
pub struct SystemHardwareConfig {
/// Timeout for the watchdog.
pub watchdog_timeout: crate::Duration,
pub watchdog_timeout: time::MillisDurationU32,
/// If true, all interrupts will be disabled until `AERUGO.start()` is called.
pub disable_interrupts_during_setup: bool,
}

impl Default for SystemHardwareConfig {
fn default() -> Self {
SystemHardwareConfig {
watchdog_timeout: crate::Duration::secs(1),
watchdog_timeout: time::MillisDurationU32::secs(3),
disable_interrupts_during_setup: true,
}
}
Expand Down
46 changes: 45 additions & 1 deletion aerugo-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ HAL (Hardware Abstract Layer) for Aerugo system.
#![warn(clippy::missing_docs_in_private_items)]
#![warn(rustdoc::missing_crate_level_docs)]

pub mod system_hal;
mod config;

use bare_metal::CriticalSection;

pub use config::SystemHardwareConfig;
pub use fugit as time;

/// Constant representing system timer frequency.
Expand All @@ -20,3 +23,44 @@ pub const SYSTEM_TIMER_FREQUENCY: u32 = 1_000_000;
pub type Instant = time::TimerInstantU64<SYSTEM_TIMER_FREQUENCY>;
/// Type representing Aerugo duration.
pub type Duration = time::TimerDurationU64<SYSTEM_TIMER_FREQUENCY>;

/// System HAL trait.
pub trait AerugoHal {
/// Type for system HAL error.
type Error;

/// Configure system hardware.
///
/// Implementation should initialize and configure all core system peripherals.
///
/// # Parameters
/// * `config` - System hardware configuration.
fn configure_hardware(config: SystemHardwareConfig) -> Result<(), Self::Error>;

/// Gets current system time timestamp.
fn get_system_time() -> Instant;

/// Feeds the system watchdog.
fn feed_watchdog();

/// Enters critical section
fn enter_critical();

/// Exits critical section
fn exit_critical();

/// Executes closure `f` in an interrupt-free context.
///
/// # Generic Parameters
/// * `F` - Closure type.
/// * `R` - Closure return type.
///
/// # Parameters
/// * `f` - Closure to execute.
///
/// # Return
/// Closure result.
fn execute_critical<F, R>(f: F) -> R
where
F: FnOnce(&CriticalSection) -> R;
}
48 changes: 0 additions & 48 deletions aerugo-hal/src/system_hal.rs

This file was deleted.

18 changes: 18 additions & 0 deletions arch/cortex-m/aerugo-samv71-hal/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "aerugo-samv71-hal"
version.workspace = true
authors.workspace = true
edition.workspace = true
rust-version.workspace = true
repository.workspace = true
# homepage.workspace = true
license.workspace = true
description = "Crate with AerugoHal implementation for SAMV71"

[dependencies]
aerugo-hal = { version = "0.1.0", path = "../../../aerugo-hal" }
bare-metal = "0.2.5"
samv71-hal = { version = "0.1.0", path = "../samv71-hal" }

[features]
rt = ["samv71-hal/rt"]
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
//! System HAL implementation for Cortex-M SAMV71 target.

use aerugo_hal::system_hal::{SystemHal, SystemHardwareConfig};
use aerugo_hal::Instant;
use aerugo_hal::{AerugoHal, Instant, SystemHardwareConfig};
use bare_metal::CriticalSection;

use cortex_m::asm;

use crate::drivers::timer::channel_config::ChannelClock;
use crate::drivers::timer::timer_config::{ExternalClock, ExternalClockSource};
use crate::drivers::timer::waveform_config::{
ComparisonEffect, OutputSignalEffects, WaveformModeConfig,
};
use crate::drivers::timer::{Ch0, Ch1, Ch2, Channel, Timer, Waveform};
use crate::drivers::watchdog::watchdog_config::WatchdogConfig;
use crate::drivers::watchdog::Watchdog;
use crate::cortex_m;
use crate::error::HalError;
use crate::system_peripherals::SystemPeripherals;
use crate::user_peripherals::UserPeripherals;
use internal_cell::InternalCell;
use pac::{self, PMC, TC0};
use samv71_hal::pac::{self, PMC, TC0};
use samv71_hal::timer::channel_config::ChannelClock;
use samv71_hal::timer::timer_config::{ExternalClock, ExternalClockSource};
use samv71_hal::timer::waveform_config::{
ComparisonEffect, OutputSignalEffects, WaveformModeConfig,
};
use samv71_hal::timer::{Ch0, Ch1, Ch2, Channel, Timer, Waveform};
use samv71_hal::watchdog::{Watchdog, WatchdogConfig};

/// Global system peripherals instance, used internally by HAL.
///
/// # Safety
/// Mutex is not used here, because it would imply a critical section at every access to HAL.
/// Safety of this cell is managed by HAL instead, guaranteeing that undefined behavior will not occur.
static HAL_SYSTEM_PERIPHERALS: InternalCell<Option<SystemPeripherals>> = InternalCell::new(None);
static mut HAL_SYSTEM_PERIPHERALS: Option<SystemPeripherals> = None;

/// HAL implementation for Cortex-M based SAMV71 MCU.
pub struct Hal;
Expand All @@ -38,7 +34,7 @@ impl Hal {
///
/// Some of these peripherals are taken from SystemPeripherals structure, hence
/// this function should not be called before finishing HAL initialization (via
/// [`SystemHal::configure_hardware] function).
/// [`AerugoHal::configure_hardware] function).
///
/// This function executes in critical section, as it modifies HAL_SYSTEM_PERIPHERALS.
///
Expand All @@ -52,7 +48,7 @@ impl Hal {
/// [`None`] otherwise.
pub fn create_user_peripherals() -> Option<UserPeripherals> {
Hal::execute_critical(|_| {
if let Some(system_peripherals) = unsafe { HAL_SYSTEM_PERIPHERALS.as_mut_ref() } {
if let Some(system_peripherals) = unsafe { &mut HAL_SYSTEM_PERIPHERALS } {
let mcu_peripherals = unsafe { pac::Peripherals::steal() };
let core_peripherals = unsafe { pac::CorePeripherals::steal() };

Expand All @@ -76,7 +72,7 @@ impl Hal {
/// Initializes global HAL instance using PAC peripherals.
///
/// Calling this function begins HAL initialization process. This process must be finished
/// by calling [`SystemHal::configure_hardware`]. Until then, no other HAL functions should
/// by calling [`AerugoHal::configure_hardware`]. Until then, no other HAL functions should
/// be called, as they will most likely fail.
///
/// # Safety
Expand All @@ -95,19 +91,15 @@ impl Hal {
return Err(HalError::HalAlreadyInitialized);
}

unsafe {
HAL_SYSTEM_PERIPHERALS
.as_mut_ref()
.replace(Hal::create_system_peripherals())
};
unsafe { HAL_SYSTEM_PERIPHERALS.replace(Hal::create_system_peripherals()) };

Ok(())
}

/// Creates system peripherals of HAL.
///
/// This function steals PAC peripherals and returns a [`SystemPeripherals`] structure
/// containing peripherals used by [`SystemHal`] API implementation.
/// containing peripherals used by [`AerugoHal`] API implementation.
///
/// # Safety
/// This function should be only called once inside [`Hal::initialize`].
Expand All @@ -127,7 +119,7 @@ impl Hal {
}
}

impl SystemHal for Hal {
impl AerugoHal for Hal {
type Error = HalError;

/// This function performs SAMV71 hardware configuration required for the HAL to work correctly.
Expand All @@ -147,7 +139,7 @@ impl SystemHal for Hal {

// SAFETY: Immutable access to system peripherals is safe, as we're in critical section
// of single-core MCU and no other references to peripherals should exist at this time.
let is_hal_created = unsafe { HAL_SYSTEM_PERIPHERALS.as_ref().is_some() };
let is_hal_created = unsafe { HAL_SYSTEM_PERIPHERALS.is_some() };
if !is_hal_created {
return Err(HalError::HalNotInitialized);
}
Expand All @@ -157,7 +149,6 @@ impl SystemHal for Hal {
// We also checked that peripherals exist, so it should realistically never panic.
let peripherals = unsafe {
HAL_SYSTEM_PERIPHERALS
.as_mut_ref()
.as_mut()
.expect("HAL is not initialized")
};
Expand Down Expand Up @@ -207,7 +198,6 @@ impl SystemHal for Hal {
// system peripherals should exist during this call.
let peripherals = unsafe {
HAL_SYSTEM_PERIPHERALS
.as_ref()
.as_ref()
.expect("HAL cannot be accessed before initialization")
};
Expand Down Expand Up @@ -238,7 +228,6 @@ impl SystemHal for Hal {
// system peripherals should exist during this call.
let peripherals = unsafe {
HAL_SYSTEM_PERIPHERALS
.as_mut_ref()
.as_mut()
.expect("HAL cannot be accessed before initialization")
};
Expand All @@ -254,7 +243,7 @@ impl SystemHal for Hal {
/// Exits critical section by enabling global interrupts.
///
/// # Safety
/// <div class="warning">This function should never be called from scope-bound critical sections (like the one created with <code>SystemHal::execute_critical</code>)</div>
/// <div class="warning">This function should never be called from scope-bound critical sections (like the one created with <code>AerugoHal::execute_critical</code>)</div>
fn exit_critical() {
unsafe { cortex_m::interrupt::enable() };
}
Expand Down Expand Up @@ -357,7 +346,7 @@ fn configure_timer_pmc(pmc: &PMC) {

// Wait until PCK6 is ready
while pmc.sr.read().pckrdy6().bit_is_clear() {
asm::nop();
cortex_m::asm::nop();
}
}

Expand Down
18 changes: 18 additions & 0 deletions arch/cortex-m/aerugo-samv71-hal/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*!
SAMV71 implementation of aerugo HAL.
*/
#![no_std]
#![warn(missing_docs)]
#![warn(clippy::missing_docs_in_private_items)]
#![warn(rustdoc::missing_crate_level_docs)]

mod system_peripherals;

pub mod error;
pub mod hal;
pub mod user_peripherals;

pub use hal::Hal;
pub use samv71_hal as drivers;
pub use samv71_hal::cortex_m;
pub use user_peripherals::UserPeripherals;
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
//! Module representing peripherals internally used by Aerugo.

use pac::{PMC, TC0};

use crate::drivers::{
use samv71_hal::pac::{PMC, TC0};
use samv71_hal::{
timer::{Ch0, Ch1, Ch2, Channel, Timer, Waveform},
watchdog::Watchdog,
};

/// System peripherals structure. These peripherals are represented as HAL drivers.
/// Some of these peripherals are available only during HAL initialization
/// (between `SystemHal::initialize` and `SystemHal::configure_hardware` calls).
/// (between `AerugoHal::initialize` and `AerugoHal::configure_hardware` calls).
pub struct SystemPeripherals {
/// Watchdog instance.
pub watchdog: Watchdog,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Module representing user-accessible peripherals.

use pac;
use samv71_hal::pac;

/// Peripherals structure.
/// These peripherals can be used to create HAL drivers in user code.
Expand Down
Loading

0 comments on commit 2907d56

Please sign in to comment.