Description
Description
- Type: Bug/Question
- Priority: Major
Bug
Target
ALL
Toolchain:
ALL
Description:
While working with PR #6052 I debug the ticker interrupt scheduling process on K64F board and found that interrupt is not fired when interrupt has been scheduled in the past. Please see the following part of code:
static void schedule_interrupt(const ticker_data_t *const ticker)
{
ticker_event_queue_t *queue = ticker->queue;
update_present_time(ticker);
if (ticker->queue->head) {
us_timestamp_t present = ticker->queue->present_time;
us_timestamp_t match_time = ticker->queue->head->timestamp;
// if the event at the head of the queue is in the past then schedule
// it immediately.
if (match_time <= present) {
ticker->interface->fire_interrupt();
return;
}
timestamp_t match_tick = compute_tick(ticker, match_time);
ticker->interface->set_interrupt(match_tick);
timestamp_t cur_tick = ticker->interface->read();
if (_ticker_match_interval_passed(queue->tick_last_read, cur_tick, match_tick)) { <----- ISSUE
ticker->interface->fire_interrupt();
}
} else {
uint32_t match_tick =
(queue->tick_last_read + queue->max_delta) & queue->bitmask;
ticker->interface->set_interrupt(match_tick);
}
}
Expected behavior
In case when interrupt has been scheduled in the past _ticker_match_interval_passed()
function should return true
and interrupt should be fired by means of ticker->interface->fire_interrupt();
.
I found in my debug log the following case:
- timestamp in ticks passed to
set_interrupt()
function:020394758
. - current time in ticks reported by
set_interrupt()
function:020394759
. - last tick read (
queue->tick_last_read
):020394758
.
It looks like this is the case when interrupt has been set in the past (one tick), so _ticker_match_interval_passed()
routine should return true
and interrupt should be fired by means of ticker->interface->fire_interrupt();
.
Actual behavior
Interrupt is not fired by means of ticker->interface->fire_interrupt();
.
Analysis
Please see the _ticker_match_interval_passed()
function:
int _ticker_match_interval_passed(timestamp_t prev_tick, timestamp_t cur_tick, timestamp_t match_tick)
{
if (match_tick > prev_tick) {
return (cur_tick >= match_tick) || (cur_tick < prev_tick);
} else {
return (cur_tick < prev_tick) && (cur_tick >= match_tick);
}
}
In our case:
cur_tick
>match_tick
match_tick
==prev_tick
Result: false
Question
@c1728p9
The logic of this function is quite complicated and I'm not sure if I correctly understand entire flow, but it looks like in mentioned case _ticker_match_interval_passed()
function should return true
.
Is logic of this function valid?
In our case (cur_tick >= match_tick)
condition is fulfilled, so maybe (match_tick > prev_tick)
should be changed to (match_tick >= prev_tick)
?