11 #if !defined(__AVR__) && !defined(__SAM3X8E__) 12 #error board not supported, error 22 #define TASKS_MEASURE_PIN 0 23 #if (TASKS_MEASURE_PIN) 24 #define SET_PIN (PORTB |= B00000010) 25 #define CLEAR_PIN (PORTB &= ~B00000010) 26 #define TOGGLE_PIN (PORTB ^= B00000010) 33 #define PAUSE_INTERRUPTS { oldISR = SREG; noInterrupts(); } 34 #define RESUME_INTERRUPTS { SREG = oldISR; interrupts(); } 35 #elif defined(__SAM3X8E__) 36 #define PAUSE_INTERRUPTS { oldISR = ((__get_PRIMASK() & 0x1) == 0 && (__get_FAULTMASK() & 0x1) == 0); noInterrupts(); } 37 #define RESUME_INTERRUPTS { if (oldISR != 0) { interrupts(); } } 42 typedef struct SchedulingStruct
54 bool SchedulingActive;
60 #if defined(__SAM3X8E__) 74 void startTasksTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency)
76 pmc_set_writeprotect(
false);
77 pmc_enable_periph_clk((uint32_t)irq);
78 TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);
79 uint32_t rc = (SystemCoreClock >> 1)/frequency;
81 TC_SetRC(tc, channel, rc);
82 TC_Start(tc, channel);
83 tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
84 tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
85 NVIC_SetPriority(SysTick_IRQn, 8);
86 NVIC_SetPriority(irq, 15);
92 void Scheduler_update_nexttime(
void)
98 _nexttime = _timebase + INT16_MAX;
99 for (uint8_t i = 0; i < _lasttask; i++) {
100 if ((SchedulingTable[i].active ==
true) && (SchedulingTable[i].func != NULL)) {
108 if ((int16_t)(SchedulingTable[i].time - _nexttime) < 0) {
109 _nexttime = SchedulingTable[i].time;
141 static bool flagDone =
false;
144 if (flagDone ==
false) {
161 SchedulingActive =
false;
168 SchedulingTable[i].func = NULL;
169 SchedulingTable[i].active =
false;
170 SchedulingTable[i].running =
false;
171 SchedulingTable[i].period = 0;
172 SchedulingTable[i].time = 0;
188 if ((period < 0) || (delay < 0))
193 delay = (uint16_t)(((((int32_t)delay) * 250) + 128) >> 8);
194 period = (uint16_t)(((((int32_t)period) * 250) + 128) >> 8);
198 for(uint8_t i = 0; i < _lasttask; i++)
204 if (SchedulingTable[i].func == func)
206 SchedulingTable[i].active =
true;
207 SchedulingTable[i].running =
false;
208 SchedulingTable[i].period = period;
209 SchedulingTable[i].time = _timebase + delay;
215 Scheduler_update_nexttime();
233 if (SchedulingTable[i].func == NULL)
236 SchedulingTable[i].func = func;
237 SchedulingTable[i].active =
true;
238 SchedulingTable[i].running =
false;
239 SchedulingTable[i].period = period;
240 SchedulingTable[i].time = _timebase + delay;
250 Scheduler_update_nexttime();
276 for (uint8_t i = 0; i < _lasttask; i++)
282 if (SchedulingTable[i].func == func)
285 SchedulingTable[i].func = NULL;
286 SchedulingTable[i].active =
false;
287 SchedulingTable[i].running =
false;
288 SchedulingTable[i].period = 0;
289 SchedulingTable[i].time = 0;
292 if (i == (_lasttask - 1))
295 while(_lasttask != 0)
297 if(SchedulingTable[_lasttask - 1].func != NULL)
309 Scheduler_update_nexttime();
340 delay = (uint16_t)(((((int32_t)delay) * 250) + 128) >> 8);
344 for (uint8_t i = 0; i < _lasttask; i++)
350 if (SchedulingTable[i].func == func)
353 if (SchedulingTable[i].running ==
true)
354 SchedulingTable[i].time = SchedulingTable[i].time - SchedulingTable[i].period;
357 SchedulingTable[i].time = _timebase + delay;
363 Scheduler_update_nexttime();
389 for (uint8_t i = 0; i < _lasttask; i++)
395 if(SchedulingTable[i].func == func)
398 SchedulingTable[i].active = state;
399 SchedulingTable[i].time = _timebase + SchedulingTable[i].period;
405 Scheduler_update_nexttime();
427 #if (TASKS_MEASURE_PIN) 432 SchedulingActive =
true;
435 _nexttime = _timebase;
439 TIMSK0 |= (1<<OCIE0A);
440 #elif defined(__SAM3X8E__) 441 startTasksTimer(TC1, 0, TC3_IRQn, 1000);
445 Scheduler_update_nexttime();
454 SchedulingActive =
false;
459 TIMSK0 &= ~(1<<OCIE0A);
460 #elif defined(__SAM3X8E__) 461 NVIC_DisableIRQ(TC3_IRQn);
474 ISR(TIMER0_COMPA_vect)
475 #elif defined(__SAM3X8E__) 476 void TC3_Handler(
void)
478 void Scheduler_dummy_handler(
void)
484 #if (TASKS_MEASURE_PIN) 488 #if defined(__SAM3X8E__) 489 TC_GetStatus(TC1, 0);
493 if (SchedulingActive ==
false) {
494 #if (TASKS_MEASURE_PIN) // measure speed via GPIO 504 if ((int16_t)(_nexttime - _timebase) > 0) {
505 #if (TASKS_MEASURE_PIN) // measure speed via GPIO 512 for(i = 0; i < _lasttask; i++)
518 if ((SchedulingTable[i].active ==
true) && (SchedulingTable[i].running ==
false) && (SchedulingTable[i].func != NULL))
521 if((int16_t)(SchedulingTable[i].time - _timebase) <= 0)
524 SchedulingTable[i].running =
true;
525 SchedulingTable[i].time = _timebase + SchedulingTable[i].period;
531 SchedulingTable[i].func();
537 SchedulingTable[i].running =
false;
540 if(SchedulingTable[i].period == 0)
542 SchedulingTable[i].func = NULL;
556 Scheduler_update_nexttime();
559 #if (TASKS_MEASURE_PIN) void(* Task)(void)
Example prototype for a function than can be executed as a task.
void Tasks_Pause(void)
Pause the task scheduler.
void Tasks_Start(void)
Start the task scheduler.
bool Tasks_SetState(Task func, bool state)
Enable or disable the execution of a task.
bool Tasks_Add(Task func, int16_t period, int16_t delay)
Add a task to the task scheduler.
#define MAX_TASK_CNT
Maximum number of parallel tasks.
void Tasks_Init(void)
Initialize timer and reset the tasks scheduler at first call.
bool Tasks_Delay(Task func, int16_t delay)
Delay execution of a task.
Library providing a simple task scheduler for multitasking.
void Tasks_Clear(void)
Reset the tasks schedulder.
bool Tasks_Remove(Task func)
Remove a task from the task scheduler.