Skip to content

Commit

Permalink
RISCV: remove the direct-vectoring & interrupt-preemption feature…
Browse files Browse the repository at this point in the history
…s and enable them by default (#1310)

* Remove the `direct-vectoring` feature

* Enables the feature by default
* renames the old direct_vectoring enable function `enable_direct`

* Make enable_direct safe, move it out of vectored module

* enable interrupt preemption by default for riscv

* remove pub from cpu intr handlers

* add enable_direct for Xtensa too

* Fix flip-link feature

* Fix up interrupt docs

* changelog

* fix clippy suggestions

* Disable P4 workflow
  • Loading branch information
MabezDev authored Mar 20, 2024
1 parent 1f155cf commit a61ffef
Show file tree
Hide file tree
Showing 15 changed files with 351 additions and 501 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
"esp32c3",
"esp32c6",
"esp32h2",
"esp32p4",
# "esp32p4",
# Xtensa devices:
"esp32",
"esp32s2",
Expand Down Expand Up @@ -179,7 +179,7 @@ jobs:
cargo xtask build-package --features=esp32c3 --target=riscv32imc-unknown-none-elf esp-hal
cargo xtask build-package --features=esp32c6 --target=riscv32imac-unknown-none-elf esp-hal
cargo xtask build-package --features=esp32h2 --target=riscv32imac-unknown-none-elf esp-hal
cargo xtask build-package --features=esp32p4 --target=riscv32imafc-unknown-none-elf esp-hal
# cargo xtask build-package --features=esp32p4 --target=riscv32imafc-unknown-none-elf esp-hal
- name: msrv (esp-lp-hal)
run: |
cargo xtask build-package --features=esp32c6 --target=riscv32imac-unknown-none-elf esp-lp-hal
Expand Down
2 changes: 2 additions & 0 deletions esp-hal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- ESP32-C6 / ESP32-H2: Implement `ETM` for general purpose timers (#1274)
- `interrupt::enable` now has a direct CPU enable counter part, `interrupt::enable_direct` (#1310)

### Fixed

Expand All @@ -27,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Removed

- Remove package-level type exports (#1275)
- Removed `direct-vectoring` & `interrupt-preemption` features, as they are now enabled by default (#1310)

## [0.16.1] - 2024-03-12

Expand Down
4 changes: 0 additions & 4 deletions esp-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,9 @@ esp32s2 = ["dep:esp32s2", "xtensa", "portable-atomic/critical-section", "procmac
esp32s3 = ["dep:esp32s3", "xtensa", "procmacros/has-ulp-core", "xtensa-lx/spin", "xtensa-lx-rt?/esp32s3", "usb-otg"]

#! ### RISC-V Exclusive Feature Flags
## Enable direct interrupt vectoring.
direct-vectoring = ["esp-riscv-rt/direct-vectoring"]
## Move the stack to start of RAM to get zero-cost stack overflow protection
## (ESP32-C6 and ESPS32-H2 only!).
flip-link = ["esp-riscv-rt/fix-sp"]
## Enable interrupt preemption.
interrupt-preemption = ["esp-riscv-rt/interrupt-preemption"]
## Configuration for placing device drivers in the IRAM for faster access.
place-spi-driver-in-ram = []
## Initialize the `.data` section of memory.
Expand Down
12 changes: 2 additions & 10 deletions esp-hal/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{
str::FromStr,
};

use esp_metadata::{Arch, Chip, Config};
use esp_metadata::{Chip, Config};

// Macros taken from:
// https://github.com/TheDan64/inkwell/blob/36c3b10/src/lib.rs#L81-L110
Expand Down Expand Up @@ -113,21 +113,13 @@ fn main() -> Result<(), Box<dyn Error>> {
panic!("The target does not support PSRAM");
}

// Don't support "interrupt-preemption" and "direct-vectoring" on Xtensa and
// RISC-V with CLIC:
if (config.contains(&String::from("clic")) || config.arch() == Arch::Xtensa)
&& (cfg!(feature = "direct-vectoring") || cfg!(feature = "interrupt-preemption"))
{
panic!("The target does not support interrupt-preemption and direct-vectoring");
}

// Define all necessary configuration symbols for the configured device:
config.define_symbols();

#[allow(unused_mut)]
let mut config_symbols = config.all();
#[cfg(feature = "flip-link")]
config_symbols.push("flip-link");
config_symbols.push("flip-link".to_owned());

// Place all linker scripts in `OUT_DIR`, and instruct Cargo how to find these
// files:
Expand Down
6 changes: 1 addition & 5 deletions esp-hal/src/embassy/executor/interrupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,7 @@ macro_rules! from_cpu {
panic!("FROM_CPU_{} is already used by a different executor.", $irq);
}

// unsafe block because of direct-vectoring on riscv
#[allow(unused_unsafe)]
unsafe {
unwrap!(interrupt::enable(peripherals::Interrupt::[<FROM_CPU_INTR $irq>], priority));
}
unwrap!(interrupt::enable(peripherals::Interrupt::[<FROM_CPU_INTR $irq>], priority));
}

fn number() -> usize {
Expand Down
41 changes: 20 additions & 21 deletions esp-hal/src/interrupt/mod.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,18 @@
//! # Interrupt support
//!
//! ## Overview
//! The `interrupt` driver is a crucial module for ESP chips. Its primary
//! purpose is to manage and handle interrupts, which are asynchronous events
//! requiring immediate attention from the CPU. Interrupts are essential in
//! various applications, such as real-time tasks, I/O communications, and
//! handling external events like hardware signals.
//!
//! The core functionality of the `interrupt` driver revolves around the
//! management of interrupts. When an interrupt occurs, it temporarily stops the
//! ongoing CPU operations, saves its current state, and starts executing the
//! corresponding interrupt service routine (ISR). The interrupt service routine
//! is a user-defined function that performs the necessary actions to handle the
//! specific interrupt. Once the ISR is executed, the driver restores the saved
//! CPU state and resumes normal program execution.
//!
//! In scenarios where multiple interrupts may occur simultaneously, the
//! interrupt driver determines the `priority` of each interrupt. This
//! prioritization ensures that critical or high-priority tasks are handled
//! first. It helps prevent delays in time-sensitive applications and allows the
//! system to allocate resources efficiently. This functionality is provided and
//! implemented by the `priority` enum.
//! Interrupt support functionality depends heavily on the features enabled.
//!
//! When the `vectored` feature is enabled, the
//! [`enable`] method will map interrupt to a CPU
//! interrupt, and handle the `vector`ing to the peripheral interrupt, for
//! example `UART0`.
//!
//! It is also possible, but not recommended, to bind an interrupt directly to a
//! CPU interrupt. This can offer lower latency, at the cost of more complexity
//! in the interrupt handler.
//!
//! The `vectored` reserves a number of CPU interrupts, which cannot be used see
//! [`RESERVED_INTERRUPTS`].
//!
//! ## Example
//! ```no_run
Expand All @@ -30,12 +21,20 @@
//! ...
//! critical_section::with(|cs| SWINT.borrow_ref_mut(cs).replace(sw_int));
//!
//! // enable the interrupt
//! interrupt::enable(
//! peripherals::Interrupt::FROM_CPU_INTR0,
//! interrupt::Priority::Priority1,
//! )
//! .unwrap();
//!
//! // trigger the interrupt
//! SWINT
//! .borrow_ref_mut(cs)
//! .as_mut()
//! .unwrap()
//! .raise(SoftwareInterrupt::SoftwareInterrupt0);
//!
//! loop {}
//! }
//!
Expand Down
Loading

0 comments on commit a61ffef

Please sign in to comment.