mirror of https://github.com/ARMmbed/mbed-os.git
Don't reschedule ticker while dispatching
Wait until dispatching is finished before scheduling the next ticker interrupt. This prevents unnecissary calls to set_interrupt from periodic elements being added back. This is particularly useful for the low power ticker on devices with LPTICKER_DELAY_TICKS set to a non-zero value. This is because the low power ticker cannot be reschduled immediately and needs to fall back onto the microsecond ticker which temporarily locks deep sleep.pull/7874/head
parent
39d5e2d362
commit
cb0c189135
|
@ -69,6 +69,7 @@ static void initialize(const ticker_data_t *ticker)
|
||||||
ticker->queue->max_delta = max_delta;
|
ticker->queue->max_delta = max_delta;
|
||||||
ticker->queue->max_delta_us = max_delta_us;
|
ticker->queue->max_delta_us = max_delta_us;
|
||||||
ticker->queue->present_time = 0;
|
ticker->queue->present_time = 0;
|
||||||
|
ticker->queue->dispatching = false;
|
||||||
ticker->queue->initialized = true;
|
ticker->queue->initialized = true;
|
||||||
|
|
||||||
update_present_time(ticker);
|
update_present_time(ticker);
|
||||||
|
@ -229,6 +230,12 @@ int _ticker_match_interval_passed(timestamp_t prev_tick, timestamp_t cur_tick, t
|
||||||
static void schedule_interrupt(const ticker_data_t *const ticker)
|
static void schedule_interrupt(const ticker_data_t *const ticker)
|
||||||
{
|
{
|
||||||
ticker_event_queue_t *queue = ticker->queue;
|
ticker_event_queue_t *queue = ticker->queue;
|
||||||
|
if (ticker->queue->dispatching) {
|
||||||
|
// Don't schedule the next interrupt until dispatching is
|
||||||
|
// finished. This prevents repeated calls to interface->set_interrupt
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
update_present_time(ticker);
|
update_present_time(ticker);
|
||||||
|
|
||||||
if (ticker->queue->head) {
|
if (ticker->queue->head) {
|
||||||
|
@ -280,6 +287,7 @@ void ticker_irq_handler(const ticker_data_t *const ticker)
|
||||||
ticker->interface->clear_interrupt();
|
ticker->interface->clear_interrupt();
|
||||||
|
|
||||||
/* Go through all the pending TimerEvents */
|
/* Go through all the pending TimerEvents */
|
||||||
|
ticker->queue->dispatching = true;
|
||||||
while (1) {
|
while (1) {
|
||||||
if (ticker->queue->head == NULL) {
|
if (ticker->queue->head == NULL) {
|
||||||
break;
|
break;
|
||||||
|
@ -302,6 +310,7 @@ void ticker_irq_handler(const ticker_data_t *const ticker)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ticker->queue->dispatching = false;
|
||||||
|
|
||||||
schedule_interrupt(ticker);
|
schedule_interrupt(ticker);
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,7 @@ typedef struct {
|
||||||
uint64_t tick_remainder; /**< Ticks that have not been added to base_time */
|
uint64_t tick_remainder; /**< Ticks that have not been added to base_time */
|
||||||
us_timestamp_t present_time; /**< Store the timestamp used for present time */
|
us_timestamp_t present_time; /**< Store the timestamp used for present time */
|
||||||
bool initialized; /**< Indicate if the instance is initialized */
|
bool initialized; /**< Indicate if the instance is initialized */
|
||||||
|
bool dispatching; /**< The function ticker_irq_handler is dispatching */
|
||||||
uint8_t frequency_shifts; /**< If frequency is a value of 2^n, this is n, otherwise 0 */
|
uint8_t frequency_shifts; /**< If frequency is a value of 2^n, this is n, otherwise 0 */
|
||||||
} ticker_event_queue_t;
|
} ticker_event_queue_t;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue