Skip to content

Commit b710f08

Browse files
committed
nanostack-hal: timer: conditionalize the use of high pri event thread
nanostack-hal.critical-section-usable-from-interrupt -tunable was previously added to optionally make critical section code interrupt safe. The IRQ safe critical section is a prequisite for interrupt safe timer callbacks. The same flag can be used to enable calling of the timer callbacks directly from the timer interrupt context, without bouncing them via event thread. This removes the code and RAM consumed by EventQueue and the thread serving the high priority events. If the system does not have any dependencies on mbed_shared_queues, by setting this flag the static RAM usage is now further reduced by ~1600 bytes and code size by 4KB. Note: the default behavior is not changed, one needs to override the "nanostack-hal.critical-section-usable-from-interrupt" to have "true".
1 parent a463b07 commit b710f08

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_timer.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,26 @@
1212

1313
static Timer timer;
1414
static Timeout timeout;
15+
16+
// If critical sections are implemented using mutexes, timers must be called in thread context, and
17+
// we use the high-priority event queue for this.
18+
// If critical sections disable interrupts, we can call timers directly from interrupt. Avoiding the
19+
// event queue can save ~1600B of RAM if the rest of the system is not using the event queue either.
20+
// Caveats of this tunable are listed on arm_hal_interrupt.c.
21+
#if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
1522
static EventQueue *equeue;
23+
#endif
24+
1625
static uint32_t due;
1726
static void (*arm_hal_callback)(void);
1827

1928
// Called once at boot
2029
void platform_timer_enable(void)
2130
{
31+
#if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
2232
equeue = mbed_highprio_event_queue();
2333
MBED_ASSERT(equeue != NULL);
34+
#endif
2435
}
2536

2637
// Actually cancels a timer, not the opposite of enable
@@ -38,7 +49,14 @@ void platform_timer_set_cb(void (*new_fp)(void))
3849
static void timer_callback(void)
3950
{
4051
due = 0;
52+
53+
#if MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
54+
// Callback is interrupt safe so it can be called directly without
55+
// bouncing via event queue thread.
56+
arm_hal_callback();
57+
#else
4158
equeue->call(arm_hal_callback);
59+
#endif
4260
}
4361

4462
// This is called from inside platform_enter_critical - IRQs can't happen

0 commit comments

Comments
 (0)