|
embOS is designed to perform fast context switches.
This section describes two different methods to calculate the execution
time of a context switch from a task with lower priority to a task with
a higher priority.
The first method uses port pins and requires an oscilloscope. The second
method uses the high-resolution measurement functions. Example programs
for both methods are supplied in the \Sample directory of your
embOS shipment.
Segger uses these programs to benchmark the embOS performance. You can
use these examples to evaluate the benchmark results. Note, that the actual
performance depends on many factors (CPU, clock speed, toolchain, memory
model, optimization, configuration, etc.).
The following table gives an overview about the variations of the context
switch time depending on the memory type and the CPU mode:
| ATMEL AT91SAM7S256 |
3.50b |
Flash |
Thumb |
7.562us |
| ATMEL AT91SAM7S256 |
3.50b |
Flash |
ARM |
7.875us |
| ATMEL AT91SAM7S256 |
3.50b |
RAM |
ARM |
5.896us |
| ATMEL AT91SAM7S256 |
3.50b |
RAM |
Thumb |
6.187us |
All named example performance values in the following
section are determined with the following system configuration: ATMEL
AT91SAM7S256 running with 48 MHz clock speed. All sources are compiled
with IAR Embedded Workbench version 4.40A using thumb or arm mode with
high optimization level.
Measurement with port pins and oscilloscope
The context switching time is the time between switching
the LED on and off. If the LED is switched on with an active high signal,
the context switching time is the time between rising and falling edge
of the signal. If the LED is switched on with an active low signal, the
signal polarity is reversed.
The real context switching time is shorter, because the signal also contains
the overhead of switching the LED on and off. The time of this overhead
is also displayed on the oscilloscope as a small peak right before the
task switching time display and has to be subtracted from the displayed
context switching time. The picture below shows a simplified oscilloscope
signal with an active-low LED signal (low means LED is illuminated). There
are switching points to determine:
- A = LED is switched on for overhead measurement
- B = LED is switched off for overhead measurement
- C = LED is switched on right before context switch in low-prio task
- D = LED is switched off right after context switch in high-prio task
The time needed to switch the LED on and off in subroutines
is marked as time tAB. The time needed for a complete context
switch including the time needed to switch the LED on and off in subroutines
is marked as time tCD.
The context switching time tCS is calculated as follows:
tCS = tCD - tAB

Example measurements AT91SAM7S, ARM code in RAM
Task switching time has been measured with the pararmeters listed below:
embOS Version V3.50b
Application program: MeasureCST_Scope.c
Hardware: AT91SAM7S256 processor with 48MHz
Program is executing in RAM
ARM mode is used
Compiler used: IAR V4.40A
CPU frequency (fCPU): 47.9232MHz
CPU clock cycle (tCycle): tCycle = 1 / fCPU = 1 / 47.9232MHz = 20,866ns
Measuring tAB and tCD
tAB is measured as 312ns.
The number of cycles calculates
as follows:
CyclesAB = tAB / tCycle
=312ns / 20.866ns
= 14.952Cycles
=> 15Cycles
|
 |
tCD is measured as 6217.6ns.
The number of cycles calculates
as follows:
CyclesCD = tCD / tCycle
= 6217.6ns / 20.866ns
= 297.977Cycles
=> 298Cycles
|
 |
Resulting context switching time and number of cycles
The time which is required for the pure context switch is:
tContextSwitch = tCD - tAB = 298Cycles
- 15Cycles => 283Cycles (5.9us @48MHz).
Example measurements AT91SAM7S, Thumb code in FLASH
Task switching time has been measured with the pararmeters listed below:
embOS Version V3.50b
Application program: MeasureCST_Scope.c
Hardware: AT91SAM7S256 processor with 48MHz
Program is executing in FLASH
Thumb mode is used
Compiler used: IAR V4.40A
CPU frequency (fCPU): 47.9232MHz
CPU clock cycle (tCycle): tCycle = 1 / fCPU = 1 / 47.9232MHz = 20,866ns
Measuring tAB and tCD
tAB is measured as 436.8ns.
The number of cycles calculates
as follows:
CyclesAB = tAB / tCycle
=436.8ns / 20.866ns
= 20.933Cycles
=> 21Cycles
|
 |
tCD is measured as 8012ns.
The number of cycles calculates
as follows:
CyclesCD = tCD / tCycle
= 8012ns / 20.866ns
= 383.973Cycles
=> 384Cycles
|
 |
Resulting context switching time and number of cycles
The time which is required for the pure context switch is:
tContextSwitch = tCD - tAB = 384Cycles
- 21Cycles => 363Cycles (7.56us @48MHz).
Download the sample project below to test, compare and
verify our context switching time measurements:
| embOS Measurement for the AT91SAM7S-EK |
IAR Embedded Workbench 4.41A |
embOS_Measurement |
Measurement with port pins and oscilloscope
The example file MeasureCST_Scope.c uses the
LED.c module to set and clear a port pin. This allows measuring
the context switch time with an oscilloscope. The following source code
is excerpt from MeasureCST_Scope.c:
#include "RTOS.h"
#include "LED.h"
static OS_STACKPTR int StackHP[128], StackLP[128]; // Task stacks
static OS_TASK TCBHP, TCBLP; // Task-control-blocks
/*********************************************************************
*
* HPTask
*/
static void HPTask(void) {
while (1) {
OS_Suspend(NULL); // Suspend high priority task
LED_ClrLED0(); // Stop measurement
}
}
/*********************************************************************
*
* LPTask
*/
static void LPTask(void) {
while (1) {
OS_Delay(100); // Syncronize to tick to avoid jitter
//
// Display measurement overhead
//
LED_SetLED0();
LED_ClrLED0();
//
// Perform measurement
//
LED_SetLED0(); // Start measurement
OS_Resume(&TCBHP); // Resume high priority task to force task switch
}
}
/*********************************************************************
*
* main
*/
int main(void) {
OS_IncDI(); // Initially disable interrupts
OS_InitKern(); // Initialize OS
OS_InitHW(); // Initialize Hardware for OS
LED_Init(); // Initialize LED ports
OS_CREATETASK(&TCBHP, "HP Task", HPTask, 100, StackHP);
OS_CREATETASK(&TCBLP, "LP Task", LPTask, 99, StackLP);
OS_Start(); // Start multitasking
return 0;
}
|
Oscilloscope analysis
Measurement with high-resolution timer
The context switch time may be measured with the high-resolution
timer.
The example MeasureCST_HRTimer_embOSView.c uses a high-resolution
timer to measure the context switch time from a low priority task to a
high priority task and displays the results on embOSView.
#include "RTOS.h"
#include "stdio.h"
static OS_STACKPTR int StackHP[128], StackLP[128]; // Task stacks
static OS_TASK TCBHP, TCBLP; // Task-control-blocks
static OS_U32 _Time; // Timer values
/*********************************************************************
*
* HPTask
*/
static void HPTask(void) {
while (1) {
OS_Suspend(NULL); // Suspend high priority task
OS_Timing_End(&_Time); // Stop measurement
}
}
/*********************************************************************
*
* LPTask
*/
static void LPTask(void) {
char acBuffer[100]; // Output buffer
OS_U32 MeasureOverhead; // Time for Measure Overhead
OS_U32 v;
//
// Measure Overhead for time measurement so we can take
// this into account by subtracting it
//
OS_Timing_Start(&MeasureOverhead);
OS_Timing_End(&MeasureOverhead);
//
// Perform measurements in endless loop
//
while (1) {
OS_Delay(100); // Sync. to tick to avoid jitter
OS_Timing_Start(&_Time); // Start measurement
OS_Resume(&TCBHP); // Resume high priority task
to force task switch
v = OS_Timing_GetCycles(&_Time) - OS_Timing_GetCycles(&MeasureOverhead);
v = OS_ConvertCycles2us(1000 * v); // Convert
cycles to nano-seconds
sprintf(acBuffer, "Context switch time: %u.%.3u
usec\r", v / 1000, v % 1000);
OS_SendString(acBuffer);
}
}
|
The example program calculates and subtracts the measurement
overhead itself, so there is no need to do this. The results will be transmitted
to embOSView, so the example runs on every target that supports UART communication
to embOSView. The example program MeasureCST_HRTimer_Printf.c
is equal to the example program MeasureCST_HRTimer_embOSView.c
but displays the results with the printf() function for those
debuggers which support terminal output emulation.

|