-
-
Notifications
You must be signed in to change notification settings - Fork 768
Description
Observations
While working on chips from the nRF5x family, one thing that came up is that some chips support more interrupts than others. Currently, the code to service pending interrupts is in the nrf52
crate.
Lines 52 to 62 in b22a314
fn service_pending_interrupts(&self) { | |
unsafe { | |
loop { | |
if let Some(task) = deferred_call::DeferredCall::next_pending() { | |
match task { | |
DeferredCallTask::Nvmc => nvmc::NVMC.handle_interrupt(), | |
} | |
} else if let Some(interrupt) = nvic::next_pending() { | |
match interrupt { | |
peripheral_interrupts::ECB => nrf5x::aes::AESECB.handle_interrupt(), | |
peripheral_interrupts::GPIOTE => self.gpio_port.handle_interrupt(), |
There is some common code and then a match
over the interrupt number, that calls the suitable handle_interrupt
function for the suitable driver.
With this architecture, an interrupt only defined on say nrf52840
would have to be added to nrf52
, so the driver would also need to be in nrf52
instead of nrf52840
. This isn't separating well various chips of the same family.
Alternatively, nrf52840
could redefine the whole chips.rs
, which would be a lot of duplicated code for maybe a few unique drivers.
Draft Proposal
To make servicing of interrupts more flexible, an InterruptServiceTrait
could be define as follows:
trait InterruptServiceTrait {
unsafe fn service_interrupt(&self, interrupt: u32) -> bool;
}
- The function is
unsafe
, similarly to thematch
inside the currentservice_pending_interrupts
. - It returns a boolean, whether this interrupt number was serviced or not.
This allows composable interrupt services, for example nrf52
defines a set of interrupt handlers, and on top of that nrf52840
only defines its specific interrupts, returning false
otherwise to indicate that the parent nrf52
should handle the interrupt.
The chip's constructor, currently here:
Lines 22 to 23 in b22a314
impl NRF52 { | |
pub unsafe fn new(gpio_port: &'static nrf5x::gpio::Port) -> NRF52 { |
would be updated to take a interrupt_service: &'static dyn InterruptServiceTrait
as parameter to service the interrupt. Then, each "end-user" chip such as nrf52840
or nrf52833
can pass a suitable InterruptServiceTrait
to the generic NRF52
chip constructor.
It seems that such a trait wouldn't be specific to Nordic chips but could be useful for all chips, as a trait in the kernel.
Any thoughts?
Misc
Another trait that could be useful to clarify things would be an InterruptHandler
trait that defines the handle_interrupt
method. For now, drivers have this method by convention, but it isn't formalized as a trait. It could also be useful to put the "enable/disable all interrupts" pattern in this trait.