diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-03-06 00:41:47 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-03-06 00:41:47 +0100 |
| commit | 18fe398673f55b07159d01a230910bb9689c1525 (patch) | |
| tree | 85c92ef10298ccaedec58c0582af1bf05753192e /embassy-cortex-m/src | |
| parent | 403a83e08da67ebb20d04b1675a34c12752a94fc (diff) | |
| parent | f5e09a8f4a6d7b1bd6723c60915cb9f29cf352f7 (diff) | |
Merge pull request #1224 from embassy-rs/interrupt-binding
nrf: new interrupt binding traits/macro
Diffstat (limited to 'embassy-cortex-m/src')
| -rw-r--r-- | embassy-cortex-m/src/interrupt.rs | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/embassy-cortex-m/src/interrupt.rs b/embassy-cortex-m/src/interrupt.rs index 1df8671b9..3a82726df 100644 --- a/embassy-cortex-m/src/interrupt.rs +++ b/embassy-cortex-m/src/interrupt.rs | |||
| @@ -13,14 +13,44 @@ pub mod _export { | |||
| 13 | pub use embassy_macros::{cortex_m_interrupt as interrupt, cortex_m_interrupt_declare as declare}; | 13 | pub use embassy_macros::{cortex_m_interrupt as interrupt, cortex_m_interrupt_declare as declare}; |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | /// Interrupt handler trait. | ||
| 17 | /// | ||
| 18 | /// Drivers that need to handle interrupts implement this trait. | ||
| 19 | /// The user must ensure `on_interrupt()` is called every time the interrupt fires. | ||
| 20 | /// Drivers must use use [`Binding`] to assert at compile time that the user has done so. | ||
| 21 | pub trait Handler<I: Interrupt> { | ||
| 22 | /// Interrupt handler function. | ||
| 23 | /// | ||
| 24 | /// Must be called every time the `I` interrupt fires, synchronously from | ||
| 25 | /// the interrupt handler context. | ||
| 26 | /// | ||
| 27 | /// # Safety | ||
| 28 | /// | ||
| 29 | /// This function must ONLY be called from the interrupt handler for `I`. | ||
| 30 | unsafe fn on_interrupt(); | ||
| 31 | } | ||
| 32 | |||
| 33 | /// Compile-time assertion that an interrupt has been bound to a handler. | ||
| 34 | /// | ||
| 35 | /// For the vast majority of cases, you should use the `bind_interrupts!` | ||
| 36 | /// macro instead of writing `unsafe impl`s of this trait. | ||
| 37 | /// | ||
| 38 | /// # Safety | ||
| 39 | /// | ||
| 40 | /// By implementing this trait, you are asserting that you have arranged for `H::on_interrupt()` | ||
| 41 | /// to be called every time the `I` interrupt fires. | ||
| 42 | /// | ||
| 43 | /// This allows drivers to check bindings at compile-time. | ||
| 44 | pub unsafe trait Binding<I: Interrupt, H: Handler<I>> {} | ||
| 45 | |||
| 16 | /// Implementation detail, do not use outside embassy crates. | 46 | /// Implementation detail, do not use outside embassy crates. |
| 17 | #[doc(hidden)] | 47 | #[doc(hidden)] |
| 18 | pub struct Handler { | 48 | pub struct DynHandler { |
| 19 | pub func: AtomicPtr<()>, | 49 | pub func: AtomicPtr<()>, |
| 20 | pub ctx: AtomicPtr<()>, | 50 | pub ctx: AtomicPtr<()>, |
| 21 | } | 51 | } |
| 22 | 52 | ||
| 23 | impl Handler { | 53 | impl DynHandler { |
| 24 | pub const fn new() -> Self { | 54 | pub const fn new() -> Self { |
| 25 | Self { | 55 | Self { |
| 26 | func: AtomicPtr::new(ptr::null_mut()), | 56 | func: AtomicPtr::new(ptr::null_mut()), |
| @@ -51,7 +81,7 @@ pub unsafe trait Interrupt: Peripheral<P = Self> { | |||
| 51 | 81 | ||
| 52 | /// Implementation detail, do not use outside embassy crates. | 82 | /// Implementation detail, do not use outside embassy crates. |
| 53 | #[doc(hidden)] | 83 | #[doc(hidden)] |
| 54 | unsafe fn __handler(&self) -> &'static Handler; | 84 | unsafe fn __handler(&self) -> &'static DynHandler; |
| 55 | } | 85 | } |
| 56 | 86 | ||
| 57 | /// Represents additional behavior for all interrupts. | 87 | /// Represents additional behavior for all interrupts. |
