Skip to content

Commit ae40a09

Browse files
author
Cruz Monrreal
authored
Merge pull request #7508 from mprse/ticker_free
Ticker free() - requirements, pseudo code, tests, implementation
2 parents 88316e8 + 2fe6b98 commit ae40a09

File tree

66 files changed

+502
-28
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+502
-28
lines changed

TESTS/mbed_drivers/timer/main.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ static void stub_fire_interrupt(void)
103103
/* do nothing. */
104104
}
105105

106+
/* User ticker interface function. */
107+
static void stub_free(void)
108+
{
109+
/* do nothing. */
110+
}
111+
106112
ticker_info_t info =
107113
{ TICKER_FREQ_1MHZ, TICKER_BITS };
108114

@@ -122,6 +128,7 @@ static const ticker_interface_t us_interface = {
122128
.clear_interrupt = stub_clear_interrupt,
123129
.set_interrupt = stub_set_interrupt,
124130
.fire_interrupt = stub_fire_interrupt,
131+
.free = stub_free,
125132
.get_info = stub_get_info,
126133
};
127134

TESTS/mbed_hal/common_tickers/main.cpp

Lines changed: 112 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ extern "C" {
3333
#error [NOT_SUPPORTED] test not supported
3434
#endif
3535

36+
#define US_PER_S 1000000
37+
3638
#define FORCE_OVERFLOW_TEST (false)
3739
#define TICKER_INT_VAL 500
3840
#define TICKER_DELTA 10
@@ -43,10 +45,11 @@ extern "C" {
4345
#define US_TICKER_OVERFLOW_DELTA2 60
4446

4547
#define TICKER_100_TICKS 100
48+
#define TICKER_500_TICKS 500
4649

4750
#define MAX_FUNC_EXEC_TIME_US 20
4851
#define DELTA_FUNC_EXEC_TIME_US 5
49-
#define NUM_OF_CALLS 1000
52+
#define NUM_OF_CALLS 100
5053

5154
#define NUM_OF_CYCLES 100000
5255

@@ -149,6 +152,19 @@ void wait_cycles(volatile unsigned int cycles)
149152
while (cycles--);
150153
}
151154

155+
/* Auxiliary function to determine how long ticker function are executed.
156+
* This function returns number of us between <start_ticks> and <stop_ticks>
157+
* taking into account counter roll-over, counter size and frequency.
158+
*/
159+
uint32_t diff_us(uint32_t start_ticks, uint32_t stop_ticks, const ticker_info_t * info)
160+
{
161+
uint32_t counter_mask = ((1 << info->bits) - 1);
162+
163+
uint32_t diff_ticks = ((stop_ticks - start_ticks) & counter_mask);
164+
165+
return (uint32_t) ((uint64_t) diff_ticks * US_PER_S / info->frequency);
166+
}
167+
152168
/* Test that ticker_init can be called multiple times and
153169
* ticker_init allows the ticker to keep counting and disables the ticker interrupt.
154170
*/
@@ -419,64 +435,134 @@ void ticker_increment_test(void)
419435
/* Test that common ticker functions complete with the required amount of time. */
420436
void ticker_speed_test(void)
421437
{
422-
Timer timer;
423438
int counter = NUM_OF_CALLS;
439+
uint32_t start;
440+
uint32_t stop;
441+
442+
const ticker_info_t * us_ticker_info = get_us_ticker_data()->interface->get_info();
443+
444+
/* Free function will disable the ticker. For time measurement
445+
* we need to use other one if available.
446+
*/
447+
#if DEVICE_LPTICKER
448+
const ticker_info_t * lp_ticker_info = get_lp_ticker_data()->interface->get_info();
449+
bool us_ticker_test = (intf == get_us_ticker_data()->interface);
450+
#endif
424451

425452
/* ---- Test ticker_read function. ---- */
426-
timer.reset();
427-
timer.start();
453+
start = us_ticker_read();
428454
while (counter--) {
429455
intf->read();
430456
}
431-
timer.stop();
457+
stop = us_ticker_read();
432458

433-
TEST_ASSERT(timer.read_us() < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
459+
TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
434460

435461
/* ---- Test ticker_clear_interrupt function. ---- */
436462
counter = NUM_OF_CALLS;
437-
timer.reset();
438-
timer.start();
463+
start = us_ticker_read();
439464
while (counter--) {
440465
intf->clear_interrupt();
441466
}
442-
timer.stop();
467+
stop = us_ticker_read();
443468

444-
TEST_ASSERT(timer.read_us() < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
469+
TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
445470

446471
/* ---- Test ticker_set_interrupt function. ---- */
447472
counter = NUM_OF_CALLS;
448-
timer.reset();
449-
timer.start();
473+
start = us_ticker_read();
450474
while (counter--) {
451475
intf->set_interrupt(0);
452476
}
453-
timer.stop();
477+
stop = us_ticker_read();
454478

455-
TEST_ASSERT(timer.read_us() < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
479+
TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
456480

457481
/* ---- Test fire_interrupt function. ---- */
458482
counter = NUM_OF_CALLS;
459-
timer.reset();
460-
timer.start();
483+
start = us_ticker_read();
461484
while (counter--) {
462485
intf->fire_interrupt();
463486
}
464-
timer.stop();
487+
stop = us_ticker_read();
465488

466-
TEST_ASSERT(timer.read_us() < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
489+
TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
467490

468491
/* ---- Test disable_interrupt function. ---- */
469492
counter = NUM_OF_CALLS;
470-
timer.reset();
471-
timer.start();
493+
start = us_ticker_read();
472494
while (counter--) {
473495
intf->disable_interrupt();
474496
}
475-
timer.stop();
497+
stop = us_ticker_read();
498+
499+
TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
500+
501+
/* ---- Test free function. ---- */
502+
#if DEVICE_LPTICKER
503+
counter = NUM_OF_CALLS;
504+
if (us_ticker_test) {
505+
lp_ticker_init();
506+
}
507+
start = us_ticker_test ? lp_ticker_read() : us_ticker_read();
508+
while (counter--) {
509+
intf->free();
510+
}
511+
stop = us_ticker_test ? lp_ticker_read() : us_ticker_read();
512+
513+
TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
514+
#endif
515+
}
516+
517+
/* Test that ticker_free disables ticker interrupt. */
518+
void ticker_free_interrupt_test(void)
519+
{
520+
overflow_protect();
521+
522+
uint32_t cycles_500_ticks = 50;
523+
uint32_t reference_ticks_count = 0;
524+
525+
while(reference_ticks_count < TICKER_500_TICKS) {
526+
cycles_500_ticks *= 2;
527+
const uint32_t start = intf->read();
528+
wait_cycles(cycles_500_ticks);
529+
reference_ticks_count = intf->read() - start;
530+
}
531+
532+
intFlag = 0;
533+
534+
intf->set_interrupt(intf->read() + (TICKER_500_TICKS / 2));
535+
intf->free();
536+
wait_cycles(cycles_500_ticks);
537+
intf->init();
538+
TEST_ASSERT_EQUAL(0, intFlag);
539+
}
540+
541+
/* Test that ticker can be successfully re-initialized after free(). */
542+
void ticker_init_free_test(void)
543+
{
544+
intf->free();
545+
intf->init();
546+
547+
overflow_protect();
548+
549+
intFlag = 0;
550+
551+
const uint32_t tick_count = intf->read();
552+
553+
intf->set_interrupt(intf->read() + TICKER_INT_VAL);
554+
555+
while (intf->read() < (tick_count + TICKER_INT_VAL - TICKER_DELTA)) {
556+
TEST_ASSERT_EQUAL_INT_MESSAGE(0, intFlag, "Interrupt fired too early");
557+
}
558+
559+
while (intf->read() < (tick_count + TICKER_INT_VAL + TICKER_DELTA)) {
560+
}
476561

477-
TEST_ASSERT(timer.read_us() < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
562+
TEST_ASSERT_EQUAL(1, intFlag);
478563
}
479564

565+
480566
utest::v1::status_t us_ticker_setup(const Case *const source, const size_t index_of_case)
481567
{
482568
intf = get_us_ticker_data()->interface;
@@ -551,6 +637,8 @@ Case cases[] = {
551637
Case("Microsecond ticker overflow test", us_ticker_setup, ticker_overflow_test, us_ticker_teardown),
552638
Case("Microsecond ticker increment test", us_ticker_setup, ticker_increment_test, us_ticker_teardown),
553639
Case("Microsecond ticker speed test", us_ticker_setup, ticker_speed_test, us_ticker_teardown),
640+
Case("Microsecond ticker free interrupt test", us_ticker_setup, ticker_free_interrupt_test, us_ticker_teardown),
641+
Case("Microsecond re-init after free test", us_ticker_setup, ticker_init_free_test, us_ticker_teardown),
554642
#if DEVICE_LPTICKER
555643
Case("lp ticker init is safe to call repeatedly", lp_ticker_setup, ticker_init_test, lp_ticker_teardown),
556644
Case("lp ticker info test", lp_ticker_setup, ticker_info_test, lp_ticker_teardown),
@@ -561,6 +649,8 @@ Case cases[] = {
561649
Case("lp ticker overflow test", lp_ticker_setup, ticker_overflow_test, lp_ticker_teardown),
562650
Case("lp ticker increment test", lp_ticker_setup, ticker_increment_test, lp_ticker_teardown),
563651
Case("lp ticker speed test", lp_ticker_setup, ticker_speed_test, lp_ticker_teardown),
652+
Case("lp ticker free interrupt test", lp_ticker_setup, ticker_free_interrupt_test, lp_ticker_teardown),
653+
Case("lp ticker re-init after free test", lp_ticker_setup, ticker_init_free_test, lp_ticker_teardown),
564654
#endif
565655
};
566656

TESTS/mbed_hal/common_tickers/ticker_api_tests.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,21 @@ void ticker_speed_test(void);
118118
*/
119119
void ticker_overflow_test(void);
120120

121+
/** Test ticker_free disables ticker interrupt.
122+
*
123+
* Given ticker is available.
124+
* When ticker interrupt is set and then ticker_free is called.
125+
* Then ticker interrupt is not triggered.
126+
*/
127+
void ticker_free_interrupt_test(void);
128+
129+
/** Test that ticker can be successfully re-initialized after free().
130+
*
131+
* Given ticker is available.
132+
* When ticker has been re-initialized after free().
133+
* Then ticker counts and generates interrupts.
134+
*/
135+
void ticker_init_free_test(void);
121136
/**@}*/
122137

123138
#ifdef __cplusplus

TESTS/mbedmicro-rtos-mbed/systimer/main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ void mock_ticker_fire_interrupt()
9999
{
100100
}
101101

102+
void mock_ticker_free()
103+
{
104+
}
105+
102106
const ticker_info_t *mock_ticker_get_info()
103107
{
104108
static const ticker_info_t mock_ticker_info = {
@@ -115,6 +119,7 @@ ticker_interface_t mock_ticker_interface = {
115119
.clear_interrupt = mock_ticker_clear_interrupt,
116120
.set_interrupt = mock_ticker_set_interrupt,
117121
.fire_interrupt = mock_ticker_fire_interrupt,
122+
.free = mock_ticker_free,
118123
.get_info = mock_ticker_get_info,
119124
};
120125

hal/mbed_lp_ticker_api.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ static const ticker_interface_t lp_interface = {
3535
#endif
3636
.fire_interrupt = lp_ticker_fire_interrupt,
3737
.get_info = lp_ticker_get_info,
38+
.free = lp_ticker_free,
3839
};
3940

4041
static const ticker_data_t lp_data = {

hal/mbed_us_ticker_api.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ static const ticker_interface_t us_interface = {
2727
.set_interrupt = us_ticker_set_interrupt,
2828
.fire_interrupt = us_ticker_fire_interrupt,
2929
.get_info = us_ticker_get_info,
30+
.free = us_ticker_free,
3031
};
3132

3233
static const ticker_data_t us_data = {

hal/ticker_api.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ typedef struct {
6464
void (*clear_interrupt)(void); /**< Clear interrupt function */
6565
void (*set_interrupt)(timestamp_t timestamp); /**< Set interrupt function */
6666
void (*fire_interrupt)(void); /**< Fire interrupt right-away */
67+
void (*free)(void); /**< Disable function */
6768
const ticker_info_t *(*get_info)(void); /**< Return info about this ticker's implementation */
6869
} ticker_interface_t;
6970

hal/us_ticker_api.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ extern "C" {
7373
* Verified by ::ticker_fire_now_test
7474
* * The ticker operations ticker_read, ticker_clear_interrupt, ticker_set_interrupt and ticker_fire_interrupt
7575
* take less than 20us to complete - Verified by ::ticker_speed_test
76+
* * The function ticker_free disables the ticker interrupt - ::ticker_free_interrupt_test
77+
* * The function ticker_init re-initializes ticker after has been disabled by means of ticker_free - Verified by ::ticker_init_free_test
7678
*
7779
* # Undefined behavior
7880
* * Calling any function other than ticker_init before the initialization of the ticker
@@ -170,6 +172,25 @@ void us_ticker_init(void);
170172
* except us_ticker_init(), calling any function other than init is undefined.
171173
*
172174
* @note This function stops the ticker from counting.
175+
*
176+
* Pseudo Code:
177+
* @code
178+
* uint32_t us_ticker_free()
179+
* {
180+
* // Disable timer
181+
* TIMER_CTRL &= ~TIMER_CTRL_ENABLE_Msk;
182+
*
183+
* // Disable the compare interrupt
184+
* TIMER_CTRL &= ~TIMER_CTRL_COMPARE_ENABLE_Msk;
185+
*
186+
* // Disable timer interrupt
187+
* NVIC_DisableIRQ(TIMER_IRQn);
188+
*
189+
* // Disable clock gate so processor cannot read TIMER registers
190+
* POWER_CTRL &= ~POWER_CTRL_TIMER_Msk;
191+
* }
192+
* @endcode
193+
*
173194
*/
174195
void us_ticker_free(void);
175196

targets/TARGET_ARM_SSG/TARGET_BEETLE/lp_ticker.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,9 @@ void lp_ticker_clear_interrupt(void)
152152
DualTimer_ClearInterrupt(DUALTIMER0);
153153
}
154154

155+
void lp_ticker_free(void)
156+
{
157+
158+
}
159+
155160
#endif

targets/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,8 @@ void us_ticker_disable_interrupt(void) {
111111
void us_ticker_clear_interrupt(void) {
112112
Timer_ClearInterrupt(TIMER0);
113113
}
114+
115+
void us_ticker_free(void)
116+
{
117+
118+
}

targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/lp_ticker.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ void lp_ticker_fire_interrupt(void)
108108
cmsdk_ticker_fire_interrupt(&timer_data);
109109
}
110110

111+
void lp_ticker_free(void)
112+
{
113+
114+
}
115+
111116
void TIMER1_IRQHandler(void)
112117
{
113118
cmsdk_ticker_irq_handler(&timer_data);

targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/us_ticker.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ void us_ticker_fire_interrupt(void)
112112
cmsdk_ticker_fire_interrupt(&timer_data);
113113
}
114114

115+
void us_ticker_free(void)
116+
{
117+
118+
}
119+
115120
void TIMER0_IRQHandler(void)
116121
{
117122
cmsdk_ticker_irq_handler(&timer_data);

targets/TARGET_ARM_SSG/TARGET_IOTSS/us_ticker.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,8 @@ void us_ticker_clear_interrupt(void) {
8787
US_TICKER_TIMER2->TimerIntClr = 0x1;
8888

8989
}
90+
91+
void us_ticker_free(void)
92+
{
93+
94+
}

targets/TARGET_ARM_SSG/TARGET_MPS2/us_ticker.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,8 @@ void us_ticker_clear_interrupt(void) {
8181
US_TICKER_TIMER2->TimerIntClr = 0x1;
8282

8383
}
84+
85+
void us_ticker_free(void)
86+
{
87+
88+
}

0 commit comments

Comments
 (0)