AVR library
cmt.c File Reference

Simple cooperative "on-delay" multitasking. More...

#include <avr/interrupt.h>
#include <avr/wdt.h>
#include "cmt.h"


void cmt_delay_ticks (uint16_t d)
 Delay d ticks. More...
uint8_t cmt_setup_task (void(*task_proc)(void), uint16_t task_sp)
 Add task to switching logic. More...
void cmt_tick (uint8_t ms)
 Call within a timer interrupt. More...

Detailed Description

Simple cooperative "on-delay" multitasking.

Simple cooperative "on-delay" multitasking is achieved with 3 simple steps:

  1. Add tasks to the switching system with cmt_setup_task.
  2. Use a timer interrupt to call cmt_tick periodically.
  3. Within a running task, call cmt_delay_ticks to switch to another task and return after specified ticks.

The logic of this system is to use the CPU cycles you would normally waste in a delay loop to perform other tasks. The prerequisite for expected behaviour ofcourse is that tasks spend little time processing and more time delaying. If a tasks requests a 5 tick delay and other tasks spend 10 ticks processing, the first task will obviously not be returned to in 5 ticks, but 10 ticks. In general, this means a requested delay of X ticks will result in an actual delay of X or more ticks. A task that does not wish to wait (but must still cooperate in task switching) can invoke task switching without delay by calling cmt_delay_ticks(0).

Any single task project that uses delay loops can be converted to cooperative multi tasking by simply replacing non critical delays with cmt_delay_ticks.

There is no mechanism for ending a task once started, so every task is basically one big while(1) loop.

Although mutexes are rarely needed in a cooperative multitasking scenario (since task switching in under current task's control), mutex functions are implemented for convenience (and because it was fun to do).

Matej Kogovsek (matej.nosp@m.@ham.nosp@m.radio.nosp@m..si)
This file is part of mat-avr-lib

Function Documentation

void cmt_delay_ticks ( uint16_t  d)

Delay d ticks.

Task switching is done here. This should not be called with interrupts disabled!

[in]dNumber of ticks (usually ms) to delay.
uint8_t cmt_setup_task ( void(*)(void)  task_proc,
uint16_t  task_sp 

Add task to switching logic.

[in]task_procPointer to task procedure
[in]task_spTask stack pointer
Number of defined tasks. If CMT_MAX_TASKS are already running, returns 0.
void cmt_tick ( uint8_t  ms)

Call within a timer interrupt.

If you want cmt_delay_ticks to mean cmt_delay_ms, simply call this function every ms.