CMSIS-RTOS: RTX Specific Functions

| CMSIS-RTOS Version 1.03 Real-Time Operating System: API and RTX Reference Implementation.

- Main Page
- Usage and Description
- Reference

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Functions
RTX Specific Functions

This section describes the functions that are specific to CMSIS-RTOS RTX. More...

## Functions
__NO_RETURN void | os_idle_demon (void)
| OS idle demon (running when no other thread is ready to run). More...
int | os_tick_init (void)
| Initializes an alternative hardware timer as RTX kernel timer. More...
uint32_t | os_tick_val (void)
| Get alternative hardware timer's current value (0 .. OS_TRV) More...
uint32_t | os_tick_ovf (void)
| Get alternative hardware timer's overflow flag. More...
void | os_tick_irqack (void)
| Acknowledge alternative hardware timer interrupt. More...
__NO_RETURN void | os_error (uint32_t error_code)
| OS error callback (called when a runtime error is detected). More...
uint32_t | os_suspend (void)
| Suspend the RTX task scheduler. More...
void | os_resume (uint32_t sleep_time)
| Resume the RTX task scheduler. More...

## Description

The RTX kernel can be customized for different application requirements:

- If you are depending on the lowest power consumption possible, you need to adapt the function os_idle_demon to send the system to sleep mode as often as possible. In addition, use the low power RTX extensions os_suspend and os_resume to suspend the RTX scheduler and to stop the SysTick timer.
- If you need to specify an alternate hardware timer as the system tick timer, you need to
  1. implement the functions os_tick_init, os_tick_ovf, os_tick_val, and optionally the function os_tick_irqack.
  2. replace the alternate timer interrupt vector with the OS_Tick_Handler in the Interrupt Vector Table in startup file.
- If you try to find a runtime error, use the function os_error to debug the error.

## Function Documentation

void os_error | ( | uint32_t | error_code | ) |

Parameters

  [in] | error_code | actual error code that has been detected.

Some system error conditions can be detected during runtime. If the RTX kernel detects a runtime error, it calls the runtime error function os_error.

The argument error_code passes the actual error code to this function:

Error Code | Description
--- | ---
OS_ERROR_STACK_OVF | The stack checking has detected a stack overflow for the currently running thread.
OS_ERROR_FIFO_OVF | The ISR FIFO Queue buffer overflow is detected.
OS_ERROR_MBX_OVF | A mailbox overflow is detected for the function osMessagePut or osMailPut.
OS_ERROR_TIMER_OVF | The User Timer Callback Queue overflow is detected.

The function os_error must contain an infinite loop to prevent further program execution. You can use an emulator to step over infinite loop and trace into the code introducing a runtime error. For the overflow errors this means you need to increase the size of the object causing an overflow.

Note
  Cannot be called from Interrupt Service Routines.

Code Example

void os_error (uint32_t error_code) {
// HERE: include optional code to be executed on runtime error.
switch (error_code) {
case OS_ERROR_STACK_OVF:
// Stack overflow detected for the currently running task.
// Thread can be identified by calling svcThreadGetId().
break;
case OS_ERROR_FIFO_OVF:
// ISR FIFO Queue buffer overflow detected.
break;
case OS_ERROR_MBX_OVF:
// Mailbox overflow detected.
break;
case OS_ERROR_TIMER_OVF:
// User Timer Callback Queue overflow detected.
break;
}
for (;;);
}

OS error callback (called when a runtime error is detected).

Parameters

  [in] | error_code | actual error code that has been detected

void os_idle_demon | ( | void |  | ) |

The function os_idle_demon is executed by the RTX kernel, when no other threads are ready to run. By default, this task is an empty end-less loop that does nothing. It only waits until another task becomes ready to run. You may change the code of the os_idle_demon function to put the CPU into a power-saving or idle mode.

The default stack size for this task is defined in the file #RTX_Conf_CM.c. Refer to Thread Configuration entry Default Thread stack size [bytes].

Note
  Cannot be called from Interrupt Service Routines.

Code Example

void os_idle_demon (void) {
for (;;) {
__WFI(); // wait for interrupt
}
}

OS idle demon (running when no other thread is ready to run).

void os_resume | ( | uint32_t | sleep_time | ) |

Parameters

  [in] | sleep_time | specifies how long the system was in sleep or power-down mode.

The function os_resume resumes the RTX task scheduler. You must call this function after you have called os_suspend to re-enable the task scheduler.

The argument sleep_time specifies how long the system was in sleep or power-down mode. It is measured in number of system intervals.

Note
  - You can call this function from the idle task only.
  - When the system is in power-down, the system tick timer is not running.
  - Cannot be called from Interrupt Service Routines.

See os_suspend for a Code Example.

uint32_t os_suspend | ( | void |  | ) |

Returns
  number of ticks, for how long the system can sleep or power-down.

The function os_suspend suspends the RTX task scheduler. The function calculates the time, for how long the system is allowed to power-down, and locks the task scheduler. When the function returns, the task switches are disabled. For normal RTX operation, after calling os_suspend, you must call the os_resume function to re-enable the OS task scheduler.

Note
  - You can call this function from the idle task only.
  - When the system is in power-down, the system tick timer is not running.
  - Cannot be called from Interrupt Service Routines.

Code Example

The low power RTX is controlled from the os_idle_demon. The peripheral wake-up timer must be initialized before the system enters an endless loop. os_suspend calculates the timeout until the first suspended task becomes ready, and returns the timeout to the user:

for (;;) {
sleep = os_suspend();

The user sets-up a peripheral timer to sleep timeout and starts the timer. The timeout is measured in system ticks.

if (sleep) {
// Setup the wake-up timer ...

When the wake-up timer is set-up and running, the user puts the system in power-down mode. The wake-up timer must run also in power-down mode. All other peripherals and the CPU may power-down to reduce power.

// Power-down the system ...
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFE();

The wake-up timer, when expired, generates the interrupt and wakes-up the system. Hence, it must run also in power-down mode. The system resumes operation and needs to call the function os_resume. This function restores the RTX and re-enables the scheduler.

// After Wake-up
sleep = (tc - LPC_WWDT->TV) / 250;
}
os_resume(sleep);

If, for any reason, the system does not wake up immediately after the wake-up interrupt, the actual sleep time is checked and adjusted.

int os_tick_init | ( | void |  | ) |

Returns
  IRQ number of the alternative hardware timer

The function os_tick_init initializes an alternate hardware timer as the system tick timer and starts it. If you setup OS_SYSTICK to 0, this function will be available for adding the alternate timer. It returns the interrupt number of the alternative hardware timer.

Note
  - When using an alternate timer, you must enter the OS_Tick_Handler in the interrupt vector table in the startup file.
  - Cannot be called from Interrupt Service Routines.

Code Example

#include "LPC43xx.h" // Device header
int os_tick_init (void) {
// Initialize hardware timer as system tick timer.
LPC_CCU1->CLK_M4_RITIMER_CFG = (1UL << 0);
LPC_RITIMER->COMPVAL = OS_TRV; // Set match value
LPC_RITIMER->COUNTER = 0; // Set count value to 0
LPC_RITIMER->CTRL = (1UL << 3) | // Timer enable
(1UL << 2) | // Timer enable for debug
(1UL << 1) | // Timer enable clear on match
(1UL << 0); // Clear interrupt flag
return (M0_RITIMER_OR_WWDT_IRQn); // Return IRQ number of timer (0..239)
}

void os_tick_irqack | ( | void |  | ) |

The function os_tick_irqack acknowledges the peripheral timer interrupt.

Note
  - When using an alternate timer, you must enter the OS_Tick_Handler in the interrupt vector table in the startup file.
  - Cannot be called from Interrupt Service Routines.

Code Example

#include "LPC43xx.h" // Device header
void os_tick_irqack (void) {
LPC_RITIMER->CTRL |= (1UL << 0); // Clear interrupt flag
}

uint32_t os_tick_ovf | ( | void |  | ) |

Returns
  Overflow flag
  - 1 : overflow
  - 0 : no overflow

The function os_tick_ovf returns the overflow flag of the alternate hardware timer specified by os_tick_init.

Note
  - When using an alternate timer, you must enter the OS_Tick_Handler in the interrupt vector table in the startup file.
  - Cannot be called from Interrupt Service Routines.

Code Example

#include "LPC43xx.h" // Device header
uint32_t os_tick_ovf (void) {
return (LPC_RITIMER->CTRL);
}

uint32_t os_tick_val | ( | void |  | ) |

Returns
  Current value of the alternative hardware timer

The function os_tick_val returns the current value of the alternate hardware timer specified by os_tick_init.

Note
  - When using an alternate timer, you must enter the OS_Tick_Handler in the interrupt vector table in the startup file.
  - Cannot be called from Interrupt Service Routines.

Code Example

#include "LPC43xx.h" // Device header
uint32_t os_tick_val (void) {
return (LPC_RITIMER->COUNTER);
}