Skip to main content
  • Products
  • Evaluate our Software
  • Downloads
  • Free Utilities
  • Purchase
  • Silicon Vendors
  • Support
  • About Us
  • Blog
  • Forum
  • Search
  • Jobs
  • Newsletter
  • Blog
  • Contact
  • Shop
  • embOS
  • Performance

    Performance

    embOS is designed for extreme fast performance.

    Contact us
    Downloads
    Documentation
    SEGGER embOS
    1. 1.Measurements
    2. 2.Port pins and oscilloscope
      1. 2.1.Example application
    3. 3.High-resolution timer
    ItemValue
    Boot time85 cycles (213 nsec @400 MHz)
    Context switching time192 Cycles (480 nsec @400 MHz).
    Interrupt latencyZero

    The task switching time has been measured with the parameters listed below:

    ItemValue
    embOS VersionV5.14.0.0
    Application programOS_MeasureCST_Scope.c
    HardwareRenesas RSKRZ/A1
    Program is executing inRAM
    CPU ModeThumb2
    Compiler usedSEGGER Embedded Studio V5.50d (SEGGER Compiler)
    CPU frequency (fCPU)400.0 MHz
    CPU clock cycle (tCycle):tCycle = 1 / fCPU = 1 / 400.0 MHz = 2.5 nsec

    Measurements

    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 Application directory of your embOS shipment.

    SEGGER uses these programs to benchmark the embOS performance. You can use these examples to evaluate the benchmark results. Please note that the actual performance depends on many factors (CPU, clock speed, toolchain, memory model, optimization, configuration, etc.).

    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 RZ/A1 example below use active low LEDs.

    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 on the right 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

    embOS CST Oscilloscope

    tAB is measured as 540 nsec.
    The number of cycles calculates as follows:
    CyclesAB = tAB / tCycle
    = 540 nsec / 2.5 nsec
    = 216 Cycles

    embOS CST Measure 1

    tCD is measured as 1020 nsec.
    The number of cycles calculates as follows:
    CyclesCD = tCD / tCycle
    = 1020 nsec / 2.5 nsec
    = 408 Cycles
     

    embOS CST Measure 2

    Resulting context switching time and number of cycles

    The time which is required for the pure context switch is:

    tContextSwitch = CyclesCD - CyclesAB = 408 Cycles - 216 Cycles => 192 Cycles (0.48 usec @400 MHz).

    Example application

    #include "RTOS.h"
    #include "BSP.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_TASK_Suspend(NULL);  // Suspend high priority task
        BSP_ClrLED(0);          // Stop measurement
      }
    }
    
    /*********************************************************************
    *
    *       LPTask()
    */
    static void LPTask(void) {
      while (1) {
        OS_TASK_Delay(100);      // Synchronize to tick to avoid jitter
        //
        // Display measurement overhead
        //
        BSP_SetLED(0);
        BSP_ClrLED(0);
        //
        // Perform measurement
        //
        BSP_SetLED(0);           // Start measurement
        OS_TASK_Resume(&TCBHP);  // Resume high priority task to force task switch
      }
    }
    
    /*********************************************************************
    *
    *       main()
    */
    int main(void) {
      OS_Init();    // Initialize embOS
      OS_InitHW();  // Initialize required hardware
      BSP_Init();   // Initialize LED ports
      OS_TASK_CREATE(&TCBHP, "HP Task", 100, HPTask, StackHP);
      OS_TASK_CREATE(&TCBLP, "LP Task",  50, LPTask, StackLP);
      OS_Start();   // Start embOS
      return 0;
    }

    High-resolution timer

    The context switch time may be measured with the high-resolution timer. The example OS_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.

    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 OS_MeasureCST_HRTimer_Printf.c is equal to the example program OS_MeasureCST_HRTimer_embOSView.c but displays the results with the printf() function for those debuggers which support terminal output emulation.

    #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_TASK_Suspend(NULL);           // Suspend high priority task
        OS_TIME_StopMeasurement(&Time);  // Stop measurement
      }
    }
    
    /*********************************************************************
    *
    *       LPTask()
    */
    static void LPTask(void) {
      char   acBuffer[100];    // Output buffer
      OS_U32 MeasureOverhead;  // Time for Measure Overhead
      OS_U32 v;                // Real context switching time
    
      //
      // Measure overhead for time measurement so we can take this into account by subtracting it
      //
      OS_TIME_StartMeasurement(&MeasureOverhead);
      OS_TIME_StopMeasurement(&MeasureOverhead);
      //
      // Perform measurements in endless loop
      //
      while (1) {
        OS_TASK_Delay(100);                        // Synchronize to tick to avoid jitter
        OS_TIME_StartMeasurement(&Time);           // Start measurement
        OS_TASK_Resume(&TCBHP);                    // Resume high priority task to force task switch
        v  = OS_TIME_GetResult(&Time);
        v -= OS_TIME_GetResult(&MeasureOverhead);  // Calculate real context switching time (w/o measurement overhead)
        v  = OS_ConvertCycles2us(1000 * v);        // Convert cycles to nano-seconds, increase time resolution
        sprintf(acBuffer, "Context switch time: %lu. %.3lu usec\r", (v / 1000uL), (v % 1000uL));  // Create result text
        OS_COM_SendString(acBuffer);               // Print out result
      }
    }
    
    /*********************************************************************
    *
    *       main()
    */
    int main(void) {
      OS_Init();    // Initialize embOS
      OS_InitHW();  // Initialize required hardware
      OS_TASK_CREATE(&TCBHP, "HP Task", 100, HPTask, StackHP);
      OS_TASK_CREATE(&TCBLP, "LP Task",  50, LPTask, StackLP);
      OS_Start();   // Start embOS
      return 0;
    }
    • User manual
    • Online documentation
    • Knowledge Base
    • List of downloads
    • Release notes
    • Update notification
    • Pricing
    • Support
    • Silicon vendor resources

    Headquarters

    SEGGER Microcontroller GmbH

    Ecolab-Allee 5
    40789 Monheim am Rhein, Germany
    info@segger.com
    Tel.: +49-2173-99312-0
    Fax: +49-2173-99312-28

    Locations

    USA: SEGGER Microcontroller Systems LLC

    Boston area
    101 Suffolk Lane
    Gardner, MA 01440, USA
    us-east@segger.com
    Tel.: +1-978-874-0299
    Fax: +1-978-874-0599

    Silicon Valley
    Milpitas, CA 95035, USA
    us-west@segger.com
    Tel.: +1-408-767-4068

    China: SEGGER Microcontroller China Co., Ltd.

    Room 218, Block A, Dahongqiaoguoji
    No. 133 Xiulian Road
    Minhang District, Shanghai 201199, China
    china@segger.com
    Tel.: +86-133-619-907-60

    ISO 9001 certified

    ISO 9001

    30+ years of experience

    First-class embedded software tools since 1992
    • Imprint
    • Disclaimer
    • Code of Conduct
    • Privacy Policy
    © 2025 SEGGER - All rights reserved.