Skip to content

Commit

Permalink
nrf: common-hal: support nesting enable/disable interrupts
Browse files Browse the repository at this point in the history
Support calling common_hal_mcu_disable_interrupts() and
common_hal_mcu_enable_interrupts() multiple times, and only let it take
effect when the counter reaches 0.

This is necessary because several routines in RUN_BACKGROUND_TASKS call
these functions to disable interrupts, however we also need the ability
to do this while interrupts are already disabled.

Signed-off-by: Sean Cross <sean@xobs.io>
  • Loading branch information
xobs committed May 8, 2020
1 parent a9d4b14 commit 1788da2
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions ports/nrf/common-hal/microcontroller/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,35 +48,46 @@ void common_hal_mcu_delay_us(uint32_t delay) {
NRFX_DELAY_US(delay);
}

static volatile uint32_t nesting_count = 0;
static volatile uint32_t nesting_count = 1; // Start at 1, because interrupts start disabled.
static uint8_t is_nested_critical_region;
static uint8_t sd_is_enabled = false;
void common_hal_mcu_disable_interrupts() {
if (nesting_count++ > 0)
return;

// If interrupts are already disabled, crash
if (__get_PRIMASK())
reset_into_safe_mode(HARD_CRASH);

sd_softdevice_is_enabled(&sd_is_enabled);
if (sd_is_enabled) {
sd_nvic_critical_region_enter(&is_nested_critical_region);
} else {
__disable_irq();
__DMB();
nesting_count++;
}
}

void common_hal_mcu_enable_interrupts() {
if (nesting_count == 0) {
// This is very very bad because it means there was mismatched disable/enables so we
// crash.
reset_into_safe_mode(HARD_CRASH);
}
nesting_count--;
if (nesting_count > 0) {
return;
}

// If interrupts are already enabled, crash
if (__get_PRIMASK())
reset_into_safe_mode(HARD_CRASH);

// Don't check here if SD is enabled, because we'll crash if interrupts
// were turned off and sd_softdevice_is_enabled is called.
if (sd_is_enabled) {
sd_nvic_critical_region_exit(is_nested_critical_region);
} else {
if (nesting_count == 0) {
// This is very very bad because it means there was mismatched disable/enables so we
// crash.
reset_into_safe_mode(HARD_CRASH);
}
nesting_count--;
if (nesting_count > 0) {
return;
}
__DMB();
__enable_irq();
}
Expand Down

0 comments on commit 1788da2

Please sign in to comment.