STM32F10x library
Functions | Variables
cmt.c File Reference

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

#include "stm32f10x.h"
#include "cmt.h"


void cmt_delay_ticks (uint32_t d)
 Delay d ticks. More...
uint8_t cmt_setup_task (void(*task_proc)(void), uint32_t task_sp)
 Add task to switching logic. More...
void cmt_tick (void)
 Call within a timer interrupt. More...
uint32_t cmt_minsp (uint8_t task_num)
 Returns the task's minimal detected stack pointer. More...
uint8_t cmt_try_acquire (struct cmt_mutex *m)
 Tries to acquire mutex. More...
void cmt_acquire (struct cmt_mutex *m)
 Waits until mutex acquired. More...
void cmt_release (struct cmt_mutex *m)
 Releases mutex. More...


volatile uint8_t cmt_curtask = 0
volatile struct cmt_task cmt_tasks [CMT_MAXTASKS]
volatile uint8_t cmt_numtasks = 1

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 (
This file is part of mat-stm32f1-lib

Function Documentation

void cmt_acquire ( struct cmt_mutex m)

Waits until mutex acquired.

[in]mPointer to caller allocated cmt_mutex.
void cmt_delay_ticks ( uint32_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.
uint32_t cmt_minsp ( uint8_t  task_num)

Returns the task's minimal detected stack pointer.

Used for determining the task's required stack size. Note that the returned value is an approximation.

[in]task_numTask number (zero based).
Task's minimal detected stack pointer. If task_num is out of bounds, returns 0.
void cmt_release ( struct cmt_mutex m)

Releases mutex.

[in]mPointer to caller allocated cmt_mutex.
uint8_t cmt_setup_task ( void(*)(void)  task_proc,
uint32_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 ( void  )

Call within a timer interrupt.

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

uint8_t cmt_try_acquire ( struct cmt_mutex m)

Tries to acquire mutex.

[in]mPointer to caller allocated cmt_mutex.
True on success (acquired), false otherwise.

Variable Documentation

volatile uint8_t cmt_curtask = 0

Currently running task

volatile uint8_t cmt_numtasks = 1

Number of defined tasks

volatile struct cmt_task cmt_tasks[CMT_MAXTASKS]

Array of task state structs.