Skip to content

Commit 44be049

Browse files
committed
Merge branch 'AL-145-add-recurrent-periodic-tasks-in-timer' into 'master'
AL-145: Merge AL-145-add-recurrent-periodic-tasks-in-timer to master See merge request aloxy/oss-7!99
2 parents 46a40fe + 0ed82c4 commit 44be049

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

stack/framework/components/timer/timer.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ static volatile bool NGDEF(hw_event_scheduled);
5252
static volatile timer_tick_t NGDEF(timer_offset);
5353
static const hwtimer_info_t* timer_info;
5454
static bool timer_busy_programming = false;
55+
static bool fired_by_interrupt = true;
5556
enum
5657
{
5758
NO_EVENT = FRAMEWORK_TIMER_STACK_SIZE,
@@ -80,11 +81,12 @@ error_t timer_init_event(timer_event* event, task_t callback)
8081
event->f = callback;
8182
event->arg = NULL;
8283
event->priority = MAX_PRIORITY;
84+
event->period = 0;
8385
return (sched_register_task(callback)); // register the function callback to be called at the end of the timeout
8486
}
8587

8688
static void configure_next_event();
87-
__LINK_C error_t timer_post_task_prio(task_t task, timer_tick_t fire_time, uint8_t priority, void *arg)
89+
__LINK_C error_t timer_post_task_prio(task_t task, timer_tick_t fire_time, uint8_t priority, timer_tick_t period, void *arg)
8890
{
8991
error_t status = ENOMEM;
9092
if (priority > MIN_PRIORITY)
@@ -111,6 +113,7 @@ __LINK_C error_t timer_post_task_prio(task_t task, timer_tick_t fire_time, uint8
111113
// it is allowed to update only the fire time
112114
if (NG(timers)[i].priority == priority)
113115
{
116+
NG(timers)[i].period = period;
114117
NG(timers)[i].next_event = fire_time;
115118
goto config;
116119
}
@@ -129,6 +132,7 @@ __LINK_C error_t timer_post_task_prio(task_t task, timer_tick_t fire_time, uint8
129132
NG(timers)[empty_index].next_event = fire_time;
130133
NG(timers)[empty_index].priority = priority;
131134
NG(timers)[empty_index].arg = arg;
135+
NG(timers)[empty_index].period = period;
132136
}
133137
else
134138
goto end;
@@ -153,7 +157,7 @@ __LINK_C error_t timer_post_task_prio(task_t task, timer_tick_t fire_time, uint8
153157
DPRINT("next_fire_delay <%lu>" , next_fire_delay);
154158

155159
int32_t old_fire_delay = ((int32_t)NG(timers)[NG(next_event)].next_event) - ((int32_t)counter);
156-
do_config = next_fire_delay < old_fire_delay;
160+
do_config = (next_fire_delay < old_fire_delay) || NG(next_event) == empty_index; //when same index is overwritten, also update
157161
}
158162

159163
if (do_config)
@@ -193,7 +197,7 @@ __LINK_C error_t timer_cancel_task(task_t task)
193197

194198
error_t timer_add_event(timer_event* event)
195199
{
196-
return timer_post_task_prio(event->f, timer_get_counter_value() + event->next_event, event->priority, event->arg);
200+
return timer_post_task_prio(event->f, timer_get_counter_value() + event->next_event, event->priority, event->period, event->arg);
197201
}
198202

199203
void timer_cancel_event(timer_event* event)
@@ -279,14 +283,22 @@ static void configure_next_event()
279283
next_fire_time = NG(timers)[NG(next_event)].next_event;
280284
if ( (((int32_t)next_fire_time) - ((int32_t)current_time) - timer_info->min_delay_ticks) <= 0 )
281285
{
282-
DPRINT("will be late, sched immediately");
283-
sched_post_task_prio(NG(timers)[NG(next_event)].f, NG(timers)[NG(next_event)].priority, NG(timers)[NG(next_event)].arg);
284-
NG(timers)[NG(next_event)].f = 0x0;
286+
DPRINT("will be late, sched immediately\n\n");
287+
if(NG(timers)[NG(next_event)].f == 0)
288+
DPRINT("function was empty, skipping");
289+
else {
290+
fired_by_interrupt = false;
291+
timer_fired();
292+
}
285293
}
286294
}
287295
}
288296
while(NG(next_event) != NO_EVENT && ( (((int32_t)next_fire_time) - ((int32_t)current_time) - timer_info->min_delay_ticks) <= 0 ) );
289297

298+
// if recursive event was scheduled immediately, don't set hw timer delay until last time in configure next event
299+
if(!fired_by_interrupt)
300+
return;
301+
290302
//at this point NG(next_event) is eiter equal to NO_EVENT (no tasks left)
291303
//or we have the next event we can schedule
292304
if(NG(next_event) == NO_EVENT)
@@ -355,11 +367,21 @@ static void timer_overflow()
355367

356368
static void timer_fired()
357369
{
358-
if(timer_busy_programming)
370+
if(timer_busy_programming && fired_by_interrupt)
359371
return;
360372
assert(NG(next_event) != NO_EVENT);
361373
assert(NG(timers)[NG(next_event)].f != 0x0);
362374
sched_post_task_prio(NG(timers)[NG(next_event)].f, NG(timers)[NG(next_event)].priority, NG(timers)[NG(next_event)].arg);
375+
if(NG(timers)[NG(next_event)].period > 0) {
376+
task_t recursive_task = NG(timers)[NG(next_event)].f;
377+
NG(timers)[NG(next_event)].f = 0x0;
378+
timer_post_task_prio(recursive_task, timer_get_counter_value() + NG(timers)[NG(next_event)].period, NG(timers)[NG(next_event)].priority, NG(timers)[NG(next_event)].period, NG(timers)[NG(next_event)].arg);
379+
fired_by_interrupt = true;
380+
return;
381+
}
363382
NG(timers)[NG(next_event)].f = 0x0;
364-
configure_next_event();
383+
if(fired_by_interrupt)
384+
configure_next_event();
385+
else
386+
fired_by_interrupt = true;
365387
}

stack/framework/inc/timer.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ typedef struct
6363
timer_tick_t next_event;
6464
uint8_t priority;
6565
void *arg;
66+
timer_tick_t period;
6667
} timer_event;
6768

6869
//a bit of dirty macro evaluation to prepend HWTIMER_FREQ_ to the value of 'FRAMEWORK_TIMER_RESOLUTION'
@@ -121,6 +122,7 @@ __LINK_C timer_tick_t timer_get_counter_value();
121122
* \param task The task to be scheduled at the given time.
122123
* \param time The time at which to schedule the task for execution.
123124
* \param priority The priority with which the task should be executed
125+
* \param period The period on which the task should be repeated (0 is not repeated)
124126
*
125127
* \returns error_t SUCCESS if the task was posted successfully
126128
* ENOMEM if the task could not be posted there are already too
@@ -129,7 +131,7 @@ __LINK_C timer_tick_t timer_get_counter_value();
129131
* EINVAL if an invalid priority was specified.
130132
*
131133
*/
132-
__LINK_C error_t timer_post_task_prio(task_t task, timer_tick_t time, uint8_t priority, void *arg);
134+
__LINK_C error_t timer_post_task_prio(task_t task, timer_tick_t time, uint8_t priority, timer_tick_t period, void *arg);
133135

134136
/*! \brief Post a task \<task\> to be scheduled at a given \<time\> with the default priority.
135137
*
@@ -149,7 +151,7 @@ __LINK_C error_t timer_post_task_prio(task_t task, timer_tick_t time, uint8_t pr
149151
* many tasks waiting for execution.
150152
* EALREADY if the task was already scheduled.
151153
*/
152-
inline error_t timer_post_task(task_t task, timer_tick_t time) { return timer_post_task_prio(task,time,DEFAULT_PRIORITY,NULL);}
154+
inline error_t timer_post_task(task_t task, timer_tick_t time) { return timer_post_task_prio(task,time,DEFAULT_PRIORITY,0,NULL);}
153155

154156

155157
/*! \brief Post a task \<task\> to be scheduled with a certain \<delay\> with a given \<priority\>
@@ -175,7 +177,7 @@ inline error_t timer_post_task(task_t task, timer_tick_t time) { return timer_po
175177
*/
176178
inline error_t timer_post_task_prio_delay(task_t task, timer_tick_t delay, uint8_t priority)
177179
{
178-
return timer_post_task_prio(task, timer_get_counter_value() + delay, priority, NULL);
180+
return timer_post_task_prio(task, timer_get_counter_value() + delay, priority, 0, NULL);
179181
}
180182
/*! \brief Post a task to be scheduled with a certain \<delay\> with the default priority.
181183
*

0 commit comments

Comments
 (0)