summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--ports/cc3200/hal/cc3200_hal.h7
-rw-r--r--ports/cc3200/mods/pybrtc.c2
-rw-r--r--ports/cc3200/mpconfigport.h6
-rw-r--r--ports/esp32/mpconfigport.h7
-rw-r--r--ports/esp32/mphalport.h7
-rw-r--r--ports/esp8266/esp_mphal.h6
-rw-r--r--ports/esp8266/mpconfigport.h6
-rw-r--r--ports/mimxrt/mpconfigport.h22
-rw-r--r--ports/mimxrt/mphalport.h22
-rw-r--r--ports/renesas-ra/irq.h17
-rw-r--r--ports/renesas-ra/mpconfigport.h21
-rw-r--r--ports/renesas-ra/mphalport.h3
-rw-r--r--ports/rp2/modrp2.c1
-rw-r--r--ports/rp2/mpconfigport.h6
-rw-r--r--ports/rp2/mphalport.h7
-rw-r--r--ports/rp2/mpthreadport.c1
-rw-r--r--ports/rp2/rp2_flash.c1
-rw-r--r--ports/samd/mpconfigport.h12
-rw-r--r--ports/samd/mphalport.h13
-rw-r--r--ports/stm32/irq.h17
-rw-r--r--ports/stm32/mpconfigport.h27
-rw-r--r--ports/stm32/mphalport.h13
-rw-r--r--ports/stm32/mpu.h2
-rw-r--r--ports/unix/mpconfigport.h6
-rw-r--r--ports/unix/mphalport.h6
-rw-r--r--ports/zephyr/mpconfigport.h3
-rw-r--r--ports/zephyr/mphalport.h3
27 files changed, 124 insertions, 120 deletions
diff --git a/ports/cc3200/hal/cc3200_hal.h b/ports/cc3200/hal/cc3200_hal.h
index 9e57d39e2e..d07a9a1703 100644
--- a/ports/cc3200/hal/cc3200_hal.h
+++ b/ports/cc3200/hal/cc3200_hal.h
@@ -30,6 +30,10 @@
#include "hal/utils.h"
#include "hal/systick.h"
+// assembly functions to handle critical sections, interrupt
+// disabling/enabling and sleep mode enter/exit
+#include "cc3200_asm.h"
+
/******************************************************************************
DEFINE CONSTANTS
******************************************************************************/
@@ -55,6 +59,9 @@
" isb \n"); \
}
+#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
+#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
+
/******************************************************************************
DECLARE PUBLIC FUNCTIONS
******************************************************************************/
diff --git a/ports/cc3200/mods/pybrtc.c b/ports/cc3200/mods/pybrtc.c
index e79fb29d00..340e86e158 100644
--- a/ports/cc3200/mods/pybrtc.c
+++ b/ports/cc3200/mods/pybrtc.c
@@ -25,7 +25,7 @@
* THE SOFTWARE.
*/
-#include "py/mpconfig.h"
+#include "py/mphal.h"
#include "py/obj.h"
#include "py/runtime.h"
#include "py/mperrno.h"
diff --git a/ports/cc3200/mpconfigport.h b/ports/cc3200/mpconfigport.h
index d9087efdd5..fe579c0874 100644
--- a/ports/cc3200/mpconfigport.h
+++ b/ports/cc3200/mpconfigport.h
@@ -161,14 +161,8 @@ typedef int32_t mp_int_t; // must be pointer size
typedef unsigned int mp_uint_t; // must be pointer size
typedef long mp_off_t;
-#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
-#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
#define MICROPY_EVENT_POLL_HOOK __WFI();
-// assembly functions to handle critical sections, interrupt
-// disabling/enabling and sleep mode enter/exit
-#include "cc3200_asm.h"
-
// We need to provide a declaration/definition of alloca()
#include <alloca.h>
diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h
index 35943c47b6..ff6f6ab8d0 100644
--- a/ports/esp32/mpconfigport.h
+++ b/ports/esp32/mpconfigport.h
@@ -187,13 +187,6 @@ void *esp_native_code_commit(void *, size_t, void *);
#define MP_PLAT_COMMIT_EXEC(buf, len, reloc) esp_native_code_commit(buf, len, reloc)
#define MP_SSIZE_MAX (0x7fffffff)
-// Note: these "critical nested" macros do not ensure cross-CPU exclusion,
-// the only disable interrupts on the current CPU. To full manage exclusion
-// one should use portENTER_CRITICAL/portEXIT_CRITICAL instead.
-#include "freertos/FreeRTOS.h"
-#define MICROPY_BEGIN_ATOMIC_SECTION() portSET_INTERRUPT_MASK_FROM_ISR()
-#define MICROPY_END_ATOMIC_SECTION(state) portCLEAR_INTERRUPT_MASK_FROM_ISR(state)
-
#if MICROPY_PY_SOCKET_EVENTS
#define MICROPY_PY_SOCKET_EVENTS_HANDLER extern void socket_events_handler(void); socket_events_handler();
#else
diff --git a/ports/esp32/mphalport.h b/ports/esp32/mphalport.h
index d77e2dd0df..9a7c39487d 100644
--- a/ports/esp32/mphalport.h
+++ b/ports/esp32/mphalport.h
@@ -63,6 +63,13 @@ void check_esp_err_(esp_err_t code);
void check_esp_err_(esp_err_t code, const char *func, const int line, const char *file);
#endif
+// Note: these "critical nested" macros do not ensure cross-CPU exclusion,
+// the only disable interrupts on the current CPU. To full manage exclusion
+// one should use portENTER_CRITICAL/portEXIT_CRITICAL instead.
+#include "freertos/FreeRTOS.h"
+#define MICROPY_BEGIN_ATOMIC_SECTION() portSET_INTERRUPT_MASK_FROM_ISR()
+#define MICROPY_END_ATOMIC_SECTION(state) portCLEAR_INTERRUPT_MASK_FROM_ISR(state)
+
uint32_t mp_hal_ticks_us(void);
__attribute__((always_inline)) static inline uint32_t mp_hal_ticks_cpu(void) {
uint32_t ccount;
diff --git a/ports/esp8266/esp_mphal.h b/ports/esp8266/esp_mphal.h
index b0351877e8..73a36a4b65 100644
--- a/ports/esp8266/esp_mphal.h
+++ b/ports/esp8266/esp_mphal.h
@@ -29,6 +29,9 @@
#include "shared/runtime/interrupt_char.h"
#include "xtirq.h"
+#define MICROPY_BEGIN_ATOMIC_SECTION() esp_disable_irq()
+#define MICROPY_END_ATOMIC_SECTION(state) esp_enable_irq(state)
+
void mp_sched_keyboard_interrupt(void);
struct _mp_print_t;
@@ -66,6 +69,9 @@ uint32_t mp_hal_get_cpu_freq(void);
void uart_task_init();
void dupterm_task_init();
+uint32_t esp_disable_irq(void);
+void esp_enable_irq(uint32_t state);
+
void ets_event_poll(void);
#define ETS_POLL_WHILE(cond) { while (cond) ets_event_poll(); }
diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h
index ad9fefe0cd..07586a0ea5 100644
--- a/ports/esp8266/mpconfigport.h
+++ b/ports/esp8266/mpconfigport.h
@@ -127,9 +127,6 @@
#define MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_POLL
#define MICROPY_VM_HOOK_RETURN MICROPY_VM_HOOK_POLL
-#define MICROPY_BEGIN_ATOMIC_SECTION() esp_disable_irq()
-#define MICROPY_END_ATOMIC_SECTION(state) esp_enable_irq(state)
-
// type definitions for the specific machine
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p)))
@@ -173,6 +170,3 @@ extern const struct _mp_print_t mp_debug_print;
#define WDEV_HWRNG ((volatile uint32_t *)0x3ff20e44)
#define _assert(expr) ((expr) ? (void)0 : __assert_func(__FILE__, __LINE__, __func__, #expr))
-
-uint32_t esp_disable_irq(void);
-void esp_enable_irq(uint32_t state);
diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h
index 51f057ca82..5feb5b62b8 100644
--- a/ports/mimxrt/mpconfigport.h
+++ b/ports/mimxrt/mpconfigport.h
@@ -151,30 +151,8 @@ uint32_t trng_random_u32(void);
#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "mpy-mimxrt"
#endif
-// For regular code that wants to prevent "background tasks" from running.
-// These background tasks (LWIP, Bluetooth) run in PENDSV context.
-// TODO: Check for the settings of the STM32 port in irq.h
-#define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003)
-#define IRQ_PRI_PENDSV NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 15, 0)
-#define MICROPY_PY_PENDSV_ENTER uint32_t atomic_state = raise_irq_pri(IRQ_PRI_PENDSV);
-#define MICROPY_PY_PENDSV_REENTER atomic_state = raise_irq_pri(IRQ_PRI_PENDSV);
-#define MICROPY_PY_PENDSV_EXIT restore_irq_pri(atomic_state);
-
// Hooks to add builtins
-__attribute__((always_inline)) static inline void enable_irq(uint32_t state) {
- __set_PRIMASK(state);
-}
-
-__attribute__((always_inline)) static inline uint32_t disable_irq(void) {
- uint32_t state = __get_PRIMASK();
- __disable_irq();
- return state;
-}
-
-#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
-#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
-
#if defined(IOMUX_TABLE_ENET)
extern const struct _mp_obj_type_t network_lan_type;
#define MICROPY_HW_NIC_ETH { MP_ROM_QSTR(MP_QSTR_LAN), MP_ROM_PTR(&network_lan_type) },
diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h
index 36eb387798..c4e5b052c9 100644
--- a/ports/mimxrt/mphalport.h
+++ b/ports/mimxrt/mphalport.h
@@ -36,6 +36,18 @@
#define MICROPY_HAL_VERSION "2.8.0"
+#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
+#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
+
+// For regular code that wants to prevent "background tasks" from running.
+// These background tasks (LWIP, Bluetooth) run in PENDSV context.
+// TODO: Check for the settings of the STM32 port in irq.h
+#define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003)
+#define IRQ_PRI_PENDSV NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 15, 0)
+#define MICROPY_PY_PENDSV_ENTER uint32_t atomic_state = raise_irq_pri(IRQ_PRI_PENDSV);
+#define MICROPY_PY_PENDSV_REENTER atomic_state = raise_irq_pri(IRQ_PRI_PENDSV);
+#define MICROPY_PY_PENDSV_EXIT restore_irq_pri(atomic_state);
+
#define MICROPY_HW_USB_CDC_TX_TIMEOUT (500)
#define MP_HAL_PIN_FMT "%q"
@@ -82,6 +94,16 @@ extern ringbuf_t stdin_ringbuf;
#define mp_hal_quiet_timing_enter() raise_irq_pri(1)
#define mp_hal_quiet_timing_exit(irq_state) restore_irq_pri(irq_state)
+__attribute__((always_inline)) static inline void enable_irq(uint32_t state) {
+ __set_PRIMASK(state);
+}
+
+__attribute__((always_inline)) static inline uint32_t disable_irq(void) {
+ uint32_t state = __get_PRIMASK();
+ __disable_irq();
+ return state;
+}
+
void mp_hal_set_interrupt_char(int c);
static inline mp_uint_t mp_hal_ticks_ms(void) {
diff --git a/ports/renesas-ra/irq.h b/ports/renesas-ra/irq.h
index 076247953e..0c46caea0c 100644
--- a/ports/renesas-ra/irq.h
+++ b/ports/renesas-ra/irq.h
@@ -54,11 +54,26 @@ extern uint32_t irq_stats[IRQ_STATS_MAX];
#define IRQ_EXIT(irq)
#endif
+// We have inlined IRQ functions for efficiency (they are generally
+// 1 machine instruction).
+//
+// Note on IRQ state: you should not need to know the specific
+// value of the state variable, but rather just pass the return
+// value from disable_irq back to enable_irq.
+
static inline uint32_t query_irq(void) {
return __get_PRIMASK();
}
-// enable_irq and disable_irq are defined inline in mpconfigport.h
+static inline void enable_irq(mp_uint_t state) {
+ __set_PRIMASK(state);
+}
+
+static inline mp_uint_t disable_irq(void) {
+ mp_uint_t state = __get_PRIMASK();
+ __disable_irq();
+ return state;
+}
#if __CORTEX_M >= 0x03
diff --git a/ports/renesas-ra/mpconfigport.h b/ports/renesas-ra/mpconfigport.h
index 99286fa530..63537fa5ab 100644
--- a/ports/renesas-ra/mpconfigport.h
+++ b/ports/renesas-ra/mpconfigport.h
@@ -250,27 +250,6 @@ typedef unsigned int mp_uint_t; // must be pointer size
typedef long mp_off_t;
-// We have inlined IRQ functions for efficiency (they are generally
-// 1 machine instruction).
-//
-// Note on IRQ state: you should not need to know the specific
-// value of the state variable, but rather just pass the return
-// value from disable_irq back to enable_irq. If you really need
-// to know the machine-specific values, see irq.h.
-
-static inline void enable_irq(mp_uint_t state) {
- __set_PRIMASK(state);
-}
-
-static inline mp_uint_t disable_irq(void) {
- mp_uint_t state = __get_PRIMASK();
- __disable_irq();
- return state;
-}
-
-#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
-#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
-
#if MICROPY_HW_ENABLE_USBDEV
#define MICROPY_HW_USBDEV_TASK_HOOK extern void mp_usbd_task(void); mp_usbd_task();
#define MICROPY_VM_HOOK_COUNT (10)
diff --git a/ports/renesas-ra/mphalport.h b/ports/renesas-ra/mphalport.h
index e29a7fec7b..b8441e3767 100644
--- a/ports/renesas-ra/mphalport.h
+++ b/ports/renesas-ra/mphalport.h
@@ -29,6 +29,9 @@
#include "pin.h"
#include "py/ringbuf.h"
+#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
+#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
+
#define MICROPY_PY_PENDSV_ENTER uint32_t atomic_state = raise_irq_pri(IRQ_PRI_PENDSV)
#define MICROPY_PY_PENDSV_EXIT restore_irq_pri(atomic_state)
diff --git a/ports/rp2/modrp2.c b/ports/rp2/modrp2.c
index 94d49489c0..7ccbcb40cb 100644
--- a/ports/rp2/modrp2.c
+++ b/ports/rp2/modrp2.c
@@ -24,6 +24,7 @@
* THE SOFTWARE.
*/
+#include "py/mphal.h"
#include "py/runtime.h"
#include "drivers/dht/dht.h"
#include "modrp2.h"
diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h
index 6942d26714..5ff384c923 100644
--- a/ports/rp2/mpconfigport.h
+++ b/ports/rp2/mpconfigport.h
@@ -244,12 +244,6 @@ extern const struct _mp_obj_type_t mod_network_nic_type_wiznet5k;
#define MICROPY_HW_BOOTSEL_DELAY_US 8
#endif
-// Entering a critical section.
-extern uint32_t mp_thread_begin_atomic_section(void);
-extern void mp_thread_end_atomic_section(uint32_t);
-#define MICROPY_BEGIN_ATOMIC_SECTION() mp_thread_begin_atomic_section()
-#define MICROPY_END_ATOMIC_SECTION(state) mp_thread_end_atomic_section(state)
-
// Prevent the "lwIP task" from running when unsafe to do so.
#define MICROPY_PY_LWIP_ENTER lwip_lock_acquire();
#define MICROPY_PY_LWIP_REENTER lwip_lock_acquire();
diff --git a/ports/rp2/mphalport.h b/ports/rp2/mphalport.h
index b8133c783e..9feace2f43 100644
--- a/ports/rp2/mphalport.h
+++ b/ports/rp2/mphalport.h
@@ -36,12 +36,19 @@
#define SYSTICK_MAX (0xffffff)
#define MICROPY_HW_USB_CDC_TX_TIMEOUT (500)
+// Entering a critical section.
+#define MICROPY_BEGIN_ATOMIC_SECTION() mp_thread_begin_atomic_section()
+#define MICROPY_END_ATOMIC_SECTION(state) mp_thread_end_atomic_section(state)
+
#define MICROPY_PY_PENDSV_ENTER pendsv_suspend()
#define MICROPY_PY_PENDSV_EXIT pendsv_resume()
extern int mp_interrupt_char;
extern ringbuf_t stdin_ringbuf;
+uint32_t mp_thread_begin_atomic_section(void);
+void mp_thread_end_atomic_section(uint32_t);
+
void mp_hal_set_interrupt_char(int c);
void mp_hal_time_ns_set_from_rtc(void);
diff --git a/ports/rp2/mpthreadport.c b/ports/rp2/mpthreadport.c
index ed9e338da7..968de1f782 100644
--- a/ports/rp2/mpthreadport.c
+++ b/ports/rp2/mpthreadport.c
@@ -26,6 +26,7 @@
#include "py/runtime.h"
#include "py/gc.h"
+#include "py/mphal.h"
#include "py/mpthread.h"
#include "pico/stdlib.h"
#include "pico/multicore.h"
diff --git a/ports/rp2/rp2_flash.c b/ports/rp2/rp2_flash.c
index 26ec41949e..bc284cd976 100644
--- a/ports/rp2/rp2_flash.c
+++ b/ports/rp2/rp2_flash.c
@@ -26,6 +26,7 @@
#include <string.h>
+#include "py/mphal.h"
#include "py/runtime.h"
#include "extmod/vfs.h"
#include "modrp2.h"
diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h
index 72cbb7d208..21c29be24e 100644
--- a/ports/samd/mpconfigport.h
+++ b/ports/samd/mpconfigport.h
@@ -177,18 +177,6 @@
#endif // !defined(MICROPY_HW_MCUFLASH) ....
// Miscellaneous settings
-__attribute__((always_inline)) static inline void enable_irq(uint32_t state) {
- __set_PRIMASK(state);
-}
-
-__attribute__((always_inline)) static inline uint32_t disable_irq(void) {
- uint32_t state = __get_PRIMASK();
- __disable_irq();
- return state;
-}
-
-#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
-#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
#define MICROPY_EVENT_POLL_HOOK \
do { \
diff --git a/ports/samd/mphalport.h b/ports/samd/mphalport.h
index ee33e74462..48f047066d 100644
--- a/ports/samd/mphalport.h
+++ b/ports/samd/mphalport.h
@@ -35,6 +35,9 @@
#include "hpl_time_measure.h"
#include "sam.h"
+#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
+#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
+
#define MICROPY_PY_PENDSV_ENTER uint32_t atomic_state = raise_irq_pri(IRQ_PRI_PENDSV)
#define MICROPY_PY_PENDSV_EXIT restore_irq_pri(atomic_state)
@@ -46,6 +49,16 @@ uint64_t mp_hal_ticks_us_64(void);
void mp_hal_set_interrupt_char(int c);
+__attribute__((always_inline)) static inline void enable_irq(uint32_t state) {
+ __set_PRIMASK(state);
+}
+
+__attribute__((always_inline)) static inline uint32_t disable_irq(void) {
+ uint32_t state = __get_PRIMASK();
+ __disable_irq();
+ return state;
+}
+
#define mp_hal_delay_us_fast mp_hal_delay_us
static inline uint64_t mp_hal_ticks_ms_64(void) {
diff --git a/ports/stm32/irq.h b/ports/stm32/irq.h
index 7f10d0d004..e3a204ec96 100644
--- a/ports/stm32/irq.h
+++ b/ports/stm32/irq.h
@@ -52,11 +52,26 @@ extern uint32_t irq_stats[IRQ_STATS_MAX];
#define IRQ_EXIT(irq)
#endif
+// We have inlined IRQ functions for efficiency (they are generally
+// 1 machine instruction).
+//
+// Note on IRQ state: you should not need to know the specific
+// value of the state variable, but rather just pass the return
+// value from disable_irq back to enable_irq.
+
static inline uint32_t query_irq(void) {
return __get_PRIMASK();
}
-// enable_irq and disable_irq are defined inline in mpconfigport.h
+static inline void enable_irq(mp_uint_t state) {
+ __set_PRIMASK(state);
+}
+
+static inline mp_uint_t disable_irq(void) {
+ mp_uint_t state = __get_PRIMASK();
+ __disable_irq();
+ return state;
+}
#if __CORTEX_M >= 0x03
diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h
index e11e721030..21fab6ffd6 100644
--- a/ports/stm32/mpconfigport.h
+++ b/ports/stm32/mpconfigport.h
@@ -239,27 +239,6 @@ typedef unsigned int mp_uint_t; // must be pointer size
typedef long mp_off_t;
-// We have inlined IRQ functions for efficiency (they are generally
-// 1 machine instruction).
-//
-// Note on IRQ state: you should not need to know the specific
-// value of the state variable, but rather just pass the return
-// value from disable_irq back to enable_irq. If you really need
-// to know the machine-specific values, see irq.h.
-
-static inline void enable_irq(mp_uint_t state) {
- __set_PRIMASK(state);
-}
-
-static inline mp_uint_t disable_irq(void) {
- mp_uint_t state = __get_PRIMASK();
- __disable_irq();
- return state;
-}
-
-#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
-#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
-
#if MICROPY_PY_THREAD
#define MICROPY_EVENT_POLL_HOOK \
do { \
@@ -289,12 +268,6 @@ static inline mp_uint_t disable_irq(void) {
// Configuration for shared/runtime/softtimer.c.
#define MICROPY_SOFT_TIMER_TICKS_MS uwTick
-// For regular code that wants to prevent "background tasks" from running.
-// These background tasks (LWIP, Bluetooth) run in PENDSV context.
-#define MICROPY_PY_PENDSV_ENTER uint32_t atomic_state = raise_irq_pri(IRQ_PRI_PENDSV);
-#define MICROPY_PY_PENDSV_REENTER atomic_state = raise_irq_pri(IRQ_PRI_PENDSV);
-#define MICROPY_PY_PENDSV_EXIT restore_irq_pri(atomic_state);
-
// Prevent the "LWIP task" from running.
#define MICROPY_PY_LWIP_ENTER MICROPY_PY_PENDSV_ENTER
#define MICROPY_PY_LWIP_REENTER MICROPY_PY_PENDSV_REENTER
diff --git a/ports/stm32/mphalport.h b/ports/stm32/mphalport.h
index 410aa5a8de..4983970876 100644
--- a/ports/stm32/mphalport.h
+++ b/ports/stm32/mphalport.h
@@ -40,10 +40,21 @@ static inline int mp_hal_status_to_neg_errno(HAL_StatusTypeDef status) {
NORETURN void mp_hal_raise(HAL_StatusTypeDef status);
void mp_hal_set_interrupt_char(int c); // -1 to disable
-// timing functions
+// Atomic section helpers.
#include "irq.h"
+#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
+#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
+
+// For regular code that wants to prevent "background tasks" from running.
+// These background tasks (LWIP, Bluetooth) run in PENDSV context.
+#define MICROPY_PY_PENDSV_ENTER uint32_t atomic_state = raise_irq_pri(IRQ_PRI_PENDSV);
+#define MICROPY_PY_PENDSV_REENTER atomic_state = raise_irq_pri(IRQ_PRI_PENDSV);
+#define MICROPY_PY_PENDSV_EXIT restore_irq_pri(atomic_state);
+
+// Timing functions.
+
#if __CORTEX_M == 0
// Don't have raise_irq_pri on Cortex-M0 so keep IRQs enabled to have SysTick timing
#define mp_hal_quiet_timing_enter() (1)
diff --git a/ports/stm32/mpu.h b/ports/stm32/mpu.h
index b3e2aec2d8..e260b50219 100644
--- a/ports/stm32/mpu.h
+++ b/ports/stm32/mpu.h
@@ -26,6 +26,8 @@
#ifndef MICROPY_INCLUDED_STM32_MPU_H
#define MICROPY_INCLUDED_STM32_MPU_H
+#include "irq.h"
+
#if (defined(STM32F4) && defined(MICROPY_HW_ETH_MDC)) || defined(STM32F7) || defined(STM32H7) || defined(STM32WB)
#define MPU_REGION_ETH (MPU_REGION_NUMBER0)
diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h
index dfb99d51b1..e7ce534a71 100644
--- a/ports/unix/mpconfigport.h
+++ b/ports/unix/mpconfigport.h
@@ -221,12 +221,6 @@ static inline unsigned long mp_random_seed_init(void) {
#include <stdio.h>
#endif
-// If threading is enabled, configure the atomic section.
-#if MICROPY_PY_THREAD
-#define MICROPY_BEGIN_ATOMIC_SECTION() (mp_thread_unix_begin_atomic_section(), 0xffffffff)
-#define MICROPY_END_ATOMIC_SECTION(x) (void)x; mp_thread_unix_end_atomic_section()
-#endif
-
// In lieu of a WFI(), slow down polling from being a tight loop.
#ifndef MICROPY_EVENT_POLL_HOOK
#define MICROPY_EVENT_POLL_HOOK \
diff --git a/ports/unix/mphalport.h b/ports/unix/mphalport.h
index 724fc8af5f..ca951e5001 100644
--- a/ports/unix/mphalport.h
+++ b/ports/unix/mphalport.h
@@ -30,6 +30,12 @@
#define CHAR_CTRL_C (3)
#endif
+// If threading is enabled, configure the atomic section.
+#if MICROPY_PY_THREAD
+#define MICROPY_BEGIN_ATOMIC_SECTION() (mp_thread_unix_begin_atomic_section(), 0xffffffff)
+#define MICROPY_END_ATOMIC_SECTION(x) (void)x; mp_thread_unix_end_atomic_section()
+#endif
+
void mp_hal_set_interrupt_char(char c);
#define mp_hal_stdio_poll unused // this is not implemented, nor needed
diff --git a/ports/zephyr/mpconfigport.h b/ports/zephyr/mpconfigport.h
index 918f0fb15a..94f4cc33d6 100644
--- a/ports/zephyr/mpconfigport.h
+++ b/ports/zephyr/mpconfigport.h
@@ -139,6 +139,3 @@ typedef long mp_off_t;
// extra built in names to add to the global namespace
#define MICROPY_PORT_BUILTINS \
{ MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mp_builtin_open_obj) },
-
-#define MICROPY_BEGIN_ATOMIC_SECTION irq_lock
-#define MICROPY_END_ATOMIC_SECTION irq_unlock
diff --git a/ports/zephyr/mphalport.h b/ports/zephyr/mphalport.h
index 6158593911..0d086ac299 100644
--- a/ports/zephyr/mphalport.h
+++ b/ports/zephyr/mphalport.h
@@ -1,6 +1,9 @@
#include <zephyr/zephyr.h>
#include "shared/runtime/interrupt_char.h"
+#define MICROPY_BEGIN_ATOMIC_SECTION irq_lock
+#define MICROPY_END_ATOMIC_SECTION irq_unlock
+
void mp_hal_init(void);
void mp_hal_wait_sem(struct k_sem *sem, uint32_t timeout_ms);