Closed
Description
Description
- Type: Bug
- Priority: Major
Target
NRF52_DK
Toolchain:
ARM, IAR
Toolchain version:
ARM 5.24 (Flex) ARM Compiler 5.06 update 5 (build 528)
,
IAR ANSI C/C++ Compiler V7.80.4.12462/W32 for ARM
mbed-cli version:
1.5.0
mbed-os sha:
42d77ec
Code
#include "mbed.h"
#define VERBOSE 0
#define NUM_TIMEOUTS 16
#define TEST_DELAY_US 10000ULL
void cnt_callback(volatile uint32_t *cnt)
{
(*cnt)++;
}
int main()
{
const ticker_data_t * const us_ticker = get_us_ticker_data();
const ticker_event_queue_t *ticker_event_q = us_ticker->queue;
uint32_t cnt1 = 0;
do {
#if VERBOSE
us_timestamp_t event_timestamps[NUM_TIMEOUTS] = { 0 };
#endif
us_timestamp_t ts0, ts1, ts2, end_ts, head_ts1, head_ts2;
volatile uint32_t callback_count = 0;
Timeout timeouts[NUM_TIMEOUTS];
for (size_t i = 0; i < NUM_TIMEOUTS; i++) {
timeouts[i].attach_us(mbed::callback(cnt_callback, &callback_count), TEST_DELAY_US);
}
ts0 = ticker_read_us(us_ticker);
#if VERBOSE
ticker_event_t *te = ticker_event_q->head;
int i = 0;
while (te != NULL) {
event_timestamps[i] = te->timestamp;
i++;
te = te->next;
}
#endif
end_ts = ts0 + TEST_DELAY_US;
while (ticker_read_us(us_ticker) < end_ts) {
};
// At this point all callbacks should have been called,
// so expected values are:
// cnt1 == NUM_TIMEOUTS
// ticker_event_q-> head == NULL
cnt1 = callback_count;
ts1 = ticker_read_us(us_ticker);
head_ts1 = (ticker_event_q->head == NULL) ? 0 : ticker_event_q->head->timestamp;
// Wait more to check if any callback was late.
end_ts += 2 * TEST_DELAY_US;
while (callback_count < NUM_TIMEOUTS && ticker_read_us(us_ticker) < end_ts) {
};
uint32_t cnt2 = callback_count;
ts2 = ticker_read_us(us_ticker);
head_ts2 = (ticker_event_q->head == NULL) ? 0 : ticker_event_q->head->timestamp;
#if VERBOSE
us_timestamp_t prev_ts = event_timestamps[0];
for (size_t i = 0; i < NUM_TIMEOUTS; i++) {
printf("ts[%02i]=%llu, delta=%03llu\r\n", i, event_timestamps[i], event_timestamps[i] - prev_ts);
prev_ts = event_timestamps[i];
}
#endif
printf("ts0=%llu, ts1=%llu, ts2=%llu, ts2-ts0=%llu, "
"cnt1=%lu, cnt2=%lu, head_ts1=%llu, head_ts2=%llu\r\n", ts0, ts1, ts2, ts2 - ts0, cnt1, cnt2, head_ts1,
head_ts2);
} while (cnt1 == NUM_TIMEOUTS);
printf("gotcha!\r\n");
return 0;
}
Expected behavior
When multiple Timeout
objects are scheduled one by one, all callbacks are called after given delay.
Actual behavior
With multiple repetitions it is possible to catch a case where not all the callbacks are called. The ticker event queue is not empty and still contains outdated events.
Steps to reproduce
mbed compile -t ARM -m NRF52_DK -f
ts0=732, ts1=10803, ts2=10833, ts2-ts0=10101, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=103119, ts1=113128, ts2=113128, ts2-ts0=10009, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=210632, ts1=220642, ts2=220642, ts2-ts0=10010, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=318176, ts1=328186, ts2=348205, ts2-ts0=30029, cnt1=15, cnt2=15, head_ts1=328145, head_ts2=328145
gotcha!
# RESET button pressed
ts0=732, ts1=10742, ts2=10742, ts2-ts0=10010, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=103180, ts1=113189, ts2=113189, ts2-ts0=10009, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=210663, ts1=220703, ts2=220703, ts2-ts0=10040, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=318298, ts1=328308, ts2=328308, ts2-ts0=10010, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=425872, ts1=435882, ts2=455902, ts2-ts0=30030, cnt1=3, cnt2=3, head_ts1=435323, head_ts2=435323
gotcha!
# RESET button pressed
ts0=732, ts1=10742, ts2=10742, ts2-ts0=10010, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=103210, ts1=113220, ts2=113220, ts2-ts0=10010, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=210754, ts1=220825, ts2=220825, ts2-ts0=10071, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=318451, ts1=328460, ts2=328460, ts2-ts0=10009, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=426025, ts1=436035, ts2=436035, ts2-ts0=10010, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=533600, ts1=543640, ts2=543640, ts2-ts0=10040, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=641143, ts1=651153, ts2=671173, ts2-ts0=30030, cnt1=12, cnt2=12, head_ts1=650991, head_ts2=650991
gotcha!
# RESET button pressed
ts0=732, ts1=10742, ts2=10742, ts2-ts0=10010, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=103180, ts1=113189, ts2=113189, ts2-ts0=10009, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=210724, ts1=220733, ts2=220733, ts2-ts0=10009, cnt1=16, cnt2=16, head_ts1=0, head_ts2=0
ts0=318329, ts1=328338, ts2=348358, ts2-ts0=30029, cnt1=13, cnt2=13, head_ts1=328237, head_ts2=328237
gotcha!