Prevent use of deleted ticker in Ticker test

In test_case_2x_callbacks two tickers are setup to repeatedly
reschedule each other. When these tickers are deleted this
rescheduling is still occurring and can lead to a deleted ticker
being scheduled.

When this happens the following error message is displayed:
Thread 0x0 error -6: Not allowed in ISR context

Note - this problem was not detected by CI since the test reported
the correct results back to the host test and only experienced this
error on tear down.

This problem can be reproduced on an nrf51 by first building the ticker
test with:
"mbed test -t GCC_ARM -m NRF51_DK -n tests-mbed_drivers-ticker
--compile -DMBED_TRAP_ERRORS_ENABLED=1
-DMBED_HEAP_STATS_ENABLED=1 -DMBED_STACK_STATS_ENABLED=1"

And then running testing with:
"mbed test -t GCC_ARM -m NRF51_DK -n tests-mbed_drivers-ticker --run"
pull/5355/head
Russ Butler 2017-10-04 16:07:41 -05:00 committed by adbridge
parent 634bde35a1
commit 06fa1dbbef
1 changed files with 21 additions and 9 deletions

View File

@ -44,8 +44,8 @@ static const int total_ticks = 10;
DigitalOut led1(LED1);
DigitalOut led2(LED2);
Ticker *ticker1;
Ticker *ticker2;
Ticker *volatile ticker1;
Ticker *volatile ticker2;
volatile int ticker_count = 0;
volatile bool print_tick = false;
@ -67,15 +67,21 @@ void ticker_callback_2_led(void) {
void ticker_callback_1_switch_to_2(void) {
++callback_trigger_count;
ticker1->detach();
ticker1->attach_us(ticker_callback_2_switch_to_1, ONE_MILLI_SEC);
// If ticker is NULL then it is being or has been deleted
if (ticker1) {
ticker1->detach();
ticker1->attach_us(ticker_callback_2_switch_to_1, ONE_MILLI_SEC);
}
ticker_callback_1_led();
}
void ticker_callback_2_switch_to_1(void) {
++callback_trigger_count;
ticker2->detach();
ticker2->attach_us(ticker_callback_1_switch_to_2, ONE_MILLI_SEC);
// If ticker is NULL then it is being or has been deleted
if (ticker2) {
ticker2->detach();
ticker2->attach_us(ticker_callback_1_switch_to_2, ONE_MILLI_SEC);
}
ticker_callback_2_led();
}
@ -159,13 +165,19 @@ utest::v1::status_t two_ticker_case_setup_handler_t(const Case *const source, co
}
utest::v1::status_t one_ticker_case_teardown_handler_t(const Case *const source, const size_t passed, const size_t failed, const failure_t reason) {
delete ticker1;
Ticker *temp1 = ticker1;
ticker1 = NULL;
delete temp1;
return greentea_case_teardown_handler(source, passed, failed, reason);
}
utest::v1::status_t two_ticker_case_teardown_handler_t(const Case *const source, const size_t passed, const size_t failed, const failure_t reason) {
delete ticker1;
delete ticker2;
Ticker *temp1 = ticker1;
Ticker *temp2 = ticker2;
ticker1 = NULL;
ticker2 = NULL;
delete temp1;
delete temp2;
return greentea_case_teardown_handler(source, passed, failed, reason);
}