Skip to content

Commit 10ea63b

Browse files
committed
Ticker: add fire interrupt now function
fire_interrupt function should be used for events in the past. As we have now 64bit timestamp, we can figure out what is in the past, and ask a target to invoke an interrupt immediately. The previous attemps in the target HAL tickers were not ideal, as it can wrap around easily (16 or 32 bit counters). This new functionality should solve this problem. set_interrupt for tickers in HAL code should not handle anything but the next match interrupt. If it was in the past is handled by the upper layer. It is possible that we are setting next event to the close future, so once it is set it is already in the past. Therefore we add a check after set interrupt to verify it is in future. If it is not, we fire interrupt immediately. This results in two events - first one immediate, correct one. The second one might be scheduled in far future (almost entire ticker range), that should be discarded. The specification for the fire_interrupts are: - should set pending bit for the ticker interrupt (as soon as possible), the event we are scheduling is already in the past, and we do not want to skip any events - no arguments are provided, neither return value, not needed - ticker should be initialized prior calling this function (no need to check if it is already initialized) All our targets provide this new functionality, removing old misleading if (timestamp is in the past) checks.
1 parent aae62bd commit 10ea63b

File tree

68 files changed

+499
-357
lines changed

Some content is hidden

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

68 files changed

+499
-357
lines changed

hal/lp_ticker_api.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ void lp_ticker_disable_interrupt(void);
7474
*/
7575
void lp_ticker_clear_interrupt(void);
7676

77+
/** Set pending interrupt that should be fired right away.
78+
*
79+
* The ticker should be initialized prior calling this function.
80+
*/
81+
void lp_ticker_fire_interrupt(void);
82+
7783
/**@}*/
7884

7985
#ifdef __cplusplus

hal/mbed_lp_ticker_api.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ static const ticker_interface_t lp_interface = {
2525
.disable_interrupt = lp_ticker_disable_interrupt,
2626
.clear_interrupt = lp_ticker_clear_interrupt,
2727
.set_interrupt = lp_ticker_set_interrupt,
28+
.fire_interrupt = lp_ticker_fire_interrupt,
2829
};
2930

3031
static const ticker_data_t lp_data = {

hal/mbed_ticker_api.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,23 @@ static void schedule_interrupt(const ticker_data_t *const ticker)
117117

118118
// if the event at the head of the queue is in the past then schedule
119119
// it immediately.
120-
if (next_event_timestamp < present) {
121-
relative_timeout = 0;
120+
if (next_event_timestamp <= present) {
121+
ticker->interface->fire_interrupt();
122+
return;
122123
} else if ((next_event_timestamp - present) < MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA) {
123124
relative_timeout = next_event_timestamp - present;
124125
}
125126
}
126127

127-
ticker->interface->set_interrupt(ticker->queue->present_time + relative_timeout);
128+
us_timestamp_t new_match_time = ticker->queue->present_time + relative_timeout;
129+
ticker->interface->set_interrupt(new_match_time);
130+
// there could be a delay, reread the time, check if it was set in the past
131+
// As result, if it is already in the past, we fire it immediately
132+
update_present_time(ticker);
133+
us_timestamp_t present = ticker->queue->present_time;
134+
if (present >= new_match_time) {
135+
ticker->interface->fire_interrupt();
136+
}
128137
}
129138

130139
void ticker_set_handler(const ticker_data_t *const ticker, ticker_event_handler handler)

hal/mbed_us_ticker_api.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ static const ticker_interface_t us_interface = {
2323
.disable_interrupt = us_ticker_disable_interrupt,
2424
.clear_interrupt = us_ticker_clear_interrupt,
2525
.set_interrupt = us_ticker_set_interrupt,
26+
.fire_interrupt = us_ticker_fire_interrupt,
2627
};
2728

2829
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
@@ -60,6 +60,7 @@ typedef struct {
6060
void (*disable_interrupt)(void); /**< Disable interrupt function */
6161
void (*clear_interrupt)(void); /**< Clear interrupt function */
6262
void (*set_interrupt)(timestamp_t timestamp); /**< Set interrupt function */
63+
void (*fire_interrupt)(void); /**< Fire interrupt right-away */
6364
} ticker_interface_t;
6465

6566
/** Ticker's event queue structure

hal/us_ticker_api.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ void us_ticker_disable_interrupt(void);
7272
*/
7373
void us_ticker_clear_interrupt(void);
7474

75+
/** Set pending interrupt that should be fired right away.
76+
*
77+
* The ticker should be initialized prior calling this function.
78+
*/
79+
void us_ticker_fire_interrupt(void);
80+
7581
/**@}*/
7682

7783
#ifdef __cplusplus

targets/TARGET_ARM_SSG/TARGET_BEETLE/lp_ticker.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -115,27 +115,24 @@ uint32_t lp_ticker_read(void)
115115
*/
116116
void lp_ticker_set_interrupt(timestamp_t timestamp)
117117
{
118-
int32_t delta = 0;
119-
120118
/* Verify if lp_ticker has been not Initialized */
121119
if (lp_ticker_initialized == 0)
122120
lp_ticker_init();
123121

124122
/* Calculate the delta */
125-
delta = (int32_t)(timestamp - lp_ticker_read());
126-
/* Check if the event was in the past */
127-
if (delta <= 0) {
128-
/* This event was in the past */
129-
DualTimer_SetInterrupt_1(DUALTIMER0, 0,
130-
DUALTIMER_COUNT_32 | DUALTIMER_ONESHOT);
131-
return;
132-
}
123+
uint32_t delta = timestamp - lp_ticker_read();
133124

134125
/* Enable interrupt on SingleTimer1 */
135126
DualTimer_SetInterrupt_1(DUALTIMER0, delta,
136127
DUALTIMER_COUNT_32 | DUALTIMER_ONESHOT);
137128
}
138129

130+
void lp_ticker_fire_interrupt(void)
131+
{
132+
uint32_t lp_ticker_irqn = DualTimer_GetIRQn(DUALTIMER0);
133+
NVIC_SetPendingIRQ((IRQn_Type)lp_ticker_irqn);
134+
}
135+
139136
/**
140137
* Disable low power ticker interrupt
141138
*/

targets/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,22 +91,19 @@ uint32_t us_ticker_read() {
9191
}
9292

9393
void us_ticker_set_interrupt(timestamp_t timestamp) {
94-
int32_t delta = 0;
95-
9694
if (!us_ticker_inited)
9795
us_ticker_init();
98-
delta = (int32_t)(timestamp - us_ticker_read());
99-
/* Check if the event was in the past */
100-
if (delta <= 0) {
101-
/* This event was in the past */
102-
Timer_SetInterrupt(TIMER0, 0);
103-
return;
104-
}
10596

106-
/* If the event was not in the past enable interrupt */
97+
uint32_t delta = timestamp - us_ticker_read();
10798
Timer_SetInterrupt(TIMER0, delta);
10899
}
109100

101+
void us_ticker_fire_interrupt(void)
102+
{
103+
uint32_t us_ticker_irqn1 = Timer_GetIRQn(TIMER1);
104+
NVIC_SetPendingIRQ((IRQn_Type)us_ticker_irqn1);
105+
}
106+
110107
void us_ticker_disable_interrupt(void) {
111108
Timer_DisableInterrupt(TIMER0);
112109
}

targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/us_ticker.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,22 +108,23 @@ uint32_t us_ticker_read()
108108

109109
void us_ticker_set_interrupt(timestamp_t timestamp)
110110
{
111-
int32_t delta = 0;
111+
uint32_t delta = 0;
112112

113113
if (!us_ticker_drv_data.inited) {
114114
us_ticker_init();
115115
}
116116

117-
delta = (int32_t)(timestamp - us_ticker_read());
117+
delta = timestamp - us_ticker_read();
118118

119-
/* Check if the event was in the past */
120-
if (delta <= 0) {
121-
/* This event was in the past */
122-
Timer_SetInterrupt(TIMER0, 0);
123-
} else {
124-
/* If the event was not in the past enable interrupt */
125-
Timer_SetInterrupt(TIMER0, delta);
126-
}
119+
/* If the event was not in the past enable interrupt */
120+
Timer_SetInterrupt(TIMER0, delta);
121+
122+
}
123+
124+
void us_ticker_fire_interrupt(void)
125+
{
126+
uint32_t us_ticker_irqn1 = Timer_GetIRQn(TIMER1);
127+
NVIC_SetPendingIRQ((IRQn_Type)us_ticker_irqn1);
127128
}
128129

129130
void us_ticker_disable_interrupt(void)

targets/TARGET_ARM_SSG/TARGET_IOTSS/us_ticker.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ void us_ticker_set_interrupt(timestamp_t timestamp) {
6969
US_TICKER_TIMER1->TimerControl |= 0x80; //enable timer
7070
}
7171

72+
void us_ticker_fire_interrupt(void)
73+
{
74+
NVIC_SetPendingIRQ(US_TICKER_TIMER_IRQn);
75+
}
76+
7277
void us_ticker_disable_interrupt(void) {
7378

7479
US_TICKER_TIMER1->TimerControl &= 0xDF;

targets/TARGET_ARM_SSG/TARGET_MPS2/us_ticker.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,23 @@ uint32_t return_value = 0;
5151
}
5252

5353
void us_ticker_set_interrupt(timestamp_t timestamp) {
54-
int delta = 0;
5554
if (!us_ticker_inited)
5655
us_ticker_init();
57-
delta = (int)(timestamp - us_ticker_read());
58-
if (delta <= 0) {
59-
// This event was in the past:
60-
us_ticker_irq_handler();
61-
return;
62-
}
56+
57+
uint32_t delta = timestamp - us_ticker_read();
6358
// enable interrupt
6459
US_TICKER_TIMER1->TimerControl = 0x0; // disable timer
6560
US_TICKER_TIMER1->TimerControl = 0x62; // enable interrupt and set to 32 bit counter and set to periodic mode
6661
US_TICKER_TIMER1->TimerLoad = (delta)*25; //initialise the timer value
6762
US_TICKER_TIMER1->TimerControl |= 0x80; //enable timer
6863
}
6964

65+
void us_ticker_fire_interrupt(void)
66+
{
67+
NVIC_SetPendingIRQ(US_TICKER_TIMER_IRQn);
68+
}
69+
70+
7071
void us_ticker_disable_interrupt(void) {
7172

7273
US_TICKER_TIMER1->TimerControl &= 0xDF;

targets/TARGET_Atmel/TARGET_SAM_CortexM4/lp_ticker.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,10 @@ uint32_t lp_ticker_read()
8686
void lp_ticker_set_interrupt(timestamp_t timestamp)
8787
{
8888
uint32_t cur_time;
89-
int32_t delta;
89+
uint32_t delta;
9090

9191
cur_time = lp_ticker_read();
92-
delta = (int32_t)((uint32_t)timestamp - cur_time);
93-
if (delta < 0) {
94-
/* Event already occurred in past */
95-
lp_ticker_irq_handler();
96-
return;
97-
}
92+
delta = timestamp - cur_time;
9893

9994
uint16_t interruptat=0;
10095

@@ -120,6 +115,11 @@ void lp_ticker_set_interrupt(timestamp_t timestamp)
120115
tc_start(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2);
121116
}
122117

118+
void lp_ticker_fire_interrupt(void)
119+
{
120+
NVIC_SetPendingIRQ(TICKER_COUNTER_IRQn2);
121+
}
122+
123123
void lp_ticker_disable_interrupt(void)
124124
{
125125
tc_stop(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2);

targets/TARGET_Atmel/TARGET_SAM_CortexM4/us_ticker.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ void us_ticker_set_interrupt(timestamp_t timestamp)
170170
tc_start(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL1);
171171
}
172172

173+
void us_ticker_fire_interrupt(void)
174+
{
175+
NVIC_SetPendingIRQ(TICKER_COUNTER_IRQn1);
176+
}
177+
173178
void us_ticker_disable_interrupt(void)
174179
{
175180
tc_stop(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL1);

targets/TARGET_Freescale/TARGET_K20XX/TARGET_K20D50M/us_ticker.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,7 @@ static void ticker_isr(void) {
138138
}
139139

140140
void us_ticker_set_interrupt(timestamp_t timestamp) {
141-
int delta = (int)((uint32_t)timestamp - us_ticker_read());
142-
if (delta <= 0) {
143-
// This event was in the past:
144-
us_ticker_irq_handler();
145-
return;
146-
}
147-
141+
uint32_t delta = timestamp - us_ticker_read();
148142
//Calculate how much falls outside the 32-bit after multiplying with clk_mhz
149143
//We shift twice 16-bit to keep everything within the 32-bit variable
150144
us_ticker_int_counter = (uint32_t)(delta >> 16);
@@ -159,3 +153,8 @@ void us_ticker_set_interrupt(timestamp_t timestamp) {
159153
ticker_set(us_ticker_int_remainder);
160154
}
161155
}
156+
157+
void us_ticker_fire_interrupt(void)
158+
{
159+
NVIC_SetPendingIRQ(PIT_TICKER_IRQ);
160+
}

targets/TARGET_Freescale/TARGET_K20XX/TARGET_TEENSY3_1/us_ticker.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,14 @@ void us_ticker_clear_interrupt(void) {
7070
}
7171

7272
void us_ticker_set_interrupt(timestamp_t timestamp) {
73-
int delta = (int)((uint32_t)timestamp - us_ticker_read());
74-
if (delta <= 0) {
75-
// This event was in the past:
76-
us_ticker_irq_handler();
77-
return;
78-
}
79-
73+
uint32_t delta = timestamp - us_ticker_read();
8074
PIT->CHANNEL[3].TCTRL = 0;
8175
PIT->CHANNEL[3].LDVAL = delta;
8276
PIT->CHANNEL[3].TCTRL = PIT_TCTRL_TIE_MASK | PIT_TCTRL_TEN_MASK | PIT_TCTRL_CHN_MASK;
8377

8478
}
79+
80+
void us_ticker_fire_interrupt(void)
81+
{
82+
NVIC_SetPendingIRQ(PIT3_IRQn);
83+
}

targets/TARGET_Freescale/TARGET_KLXX/us_ticker.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -185,13 +185,7 @@ static void lptmr_isr(void) {
185185
}
186186

187187
void us_ticker_set_interrupt(timestamp_t timestamp) {
188-
int delta = (int)((uint32_t)timestamp - us_ticker_read());
189-
if (delta <= 0) {
190-
// This event was in the past. Force it into the very near
191-
// future instead.
192-
delta = 1;
193-
}
194-
188+
uint32_t delta = timestamp - us_ticker_read();
195189
us_ticker_int_counter = (uint32_t)(delta >> 16);
196190
us_ticker_int_remainder = (uint16_t)(0xFFFF & delta);
197191
if (us_ticker_int_counter > 0) {
@@ -202,3 +196,13 @@ void us_ticker_set_interrupt(timestamp_t timestamp) {
202196
us_ticker_int_remainder = 0;
203197
}
204198
}
199+
200+
void us_ticker_fire_interrupt(void)
201+
{
202+
#if defined(TARGET_KL43Z)
203+
NVIC_SetPendingIRQ(LPTMR0_IRQn);
204+
#else
205+
NVIC_SetPendingIRQ(LPTimer_IRQn);
206+
207+
#endif
208+
}

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/us_ticker.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,16 @@ void us_ticker_clear_interrupt(void)
7373

7474
void us_ticker_set_interrupt(timestamp_t timestamp)
7575
{
76-
int delta = (int)(timestamp - us_ticker_read());
77-
if (delta <= 0) {
78-
// This event was in the past.
79-
// Set the interrupt as pending, but don't process it here.
80-
// This prevents a recurive loop under heavy load
81-
// which can lead to a stack overflow.
82-
NVIC_SetPendingIRQ(PIT3_IRQn);
83-
return;
84-
}
85-
76+
uint32_t delta = timestamp - us_ticker_read();
8677
PIT_StopTimer(PIT, kPIT_Chnl_3);
8778
PIT_StopTimer(PIT, kPIT_Chnl_2);
8879
PIT_SetTimerPeriod(PIT, kPIT_Chnl_3, (uint32_t)delta);
8980
PIT_EnableInterrupts(PIT, kPIT_Chnl_3, kPIT_TimerInterruptEnable);
9081
PIT_StartTimer(PIT, kPIT_Chnl_3);
9182
PIT_StartTimer(PIT, kPIT_Chnl_2);
9283
}
84+
85+
void us_ticker_fire_interrupt(void)
86+
{
87+
NVIC_SetPendingIRQ(PIT3_IRQn);
88+
}

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/us_ticker.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,16 @@ void us_ticker_clear_interrupt(void)
7373

7474
void us_ticker_set_interrupt(timestamp_t timestamp)
7575
{
76-
int delta = (int)(timestamp - us_ticker_read());
77-
if (delta <= 0) {
78-
// This event was in the past.
79-
// Set the interrupt as pending, but don't process it here.
80-
// This prevents a recurive loop under heavy load
81-
// which can lead to a stack overflow.
82-
NVIC_SetPendingIRQ(PIT3_IRQn);
83-
return;
84-
}
85-
76+
uint32_t delta = timestamp - us_ticker_read();
8677
PIT_StopTimer(PIT, kPIT_Chnl_3);
8778
PIT_StopTimer(PIT, kPIT_Chnl_2);
8879
PIT_SetTimerPeriod(PIT, kPIT_Chnl_3, (uint32_t)delta);
8980
PIT_EnableInterrupts(PIT, kPIT_Chnl_3, kPIT_TimerInterruptEnable);
9081
PIT_StartTimer(PIT, kPIT_Chnl_3);
9182
PIT_StartTimer(PIT, kPIT_Chnl_2);
9283
}
84+
85+
void us_ticker_fire_interrupt(void)
86+
{
87+
NVIC_SetPendingIRQ(PIT3_IRQn);
88+
}

0 commit comments

Comments
 (0)