From 96d6da4e252b06dcfdc041e7df23e86161c33007 Mon Sep 17 00:00:00 2001 From: rihab kouki Date: Tue, 28 Jul 2020 11:24:49 +0100 Subject: Official ARM version: v5.6.0 --- docs/RTOS2/html/theory_of_operation.html | 92 +++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 20 deletions(-) (limited to 'docs/RTOS2/html/theory_of_operation.html') diff --git a/docs/RTOS2/html/theory_of_operation.html b/docs/RTOS2/html/theory_of_operation.html index aaa8e5c..a285476 100644 --- a/docs/RTOS2/html/theory_of_operation.html +++ b/docs/RTOS2/html/theory_of_operation.html @@ -120,12 +120,14 @@ System Startup
  • Initialization and configuration of hardware including peripherals, memory, pins, clocks and the interrupt system.
  • Update the system core clock using the respective CMSIS-Core (Cortex-M) or CMSIS-Core (Cortex-A) function.
  • Initialize the CMSIS-RTOS kernel using osKernelInitialize.
  • -
  • Optionally, create a new thread app_main, which is used as a main thread using osThreadNew. Alternatively, threads can be created in main() directly.
  • -
  • Start the RTOS scheduler using osKernelStart which also configure system tick timer and RTOS specific interrupts. This function does not return in case of successful execution. Any application code after osKernelStart will therefore not be executed.
  • +
  • Optionally, create one thread (for example app_main), which is used as a main thread using osThreadNew. This thread should take care of creating and starting objects, once it is run by the scheduler. Alternatively, threads can be created in main() directly.
  • +
  • Start the RTOS scheduler using osKernelStart which also configures the system tick timer and initializes RTOS specific interrupts. This function does not return in case of successful execution. Therefore, any application code after osKernelStart will not be executed.
  • -
    Note
    Interrupts are initialized in osKernelStart. Modifying basic In case priorities and groupings in the NVIC are altered by the application after the above sequence it might be necessary to call osKernelInitialize again. Incorrect ossibly catched by osRtxErrorNotify or causing a hard fault.
    -
    -The tick timer is configured during osKernelStart.
    +
    Note
      +
    • Modifying priorities and groupings in the NVIC by the application after the above sequence is not recommended.
    • +
    • Before executing osKernelStart, only the functions osKernelGetInfo, osKernelGetState, and object creation functions (osXxxNew) may be called.
    • +
    +

    Scheduler

    RTX5 implements a low-latency preemptive scheduler. Major parts of RTX5 are executed in handler mode such as

    @@ -140,7 +142,7 @@ Scheduler
    Thread scheduling and interrupt execution

    The scheduler combines priority and round-robin based context switches. The example depicted in the image above contains four threads (1, 2, 3, and 4). Threads 1 and 2 share the same priority, thread 3 has a higher one and thread 4 the highest (osThreadAttr_t::priority). As long as threads 3 and 4 are blocked the scheduler switches between thread 1 and 2 on a time-slice basis (round-robin). The time-slice for round-robin scheduling can be configured, see Round-Robin Timeout in System Configuration.

    -

    Thread 2 unblocks thread 3 by an arbitrary RTOS-call (executed in SVC handler mode) at time index 2. The scheduler switches to thread 3 immediately because thread 3 has the highest priority. Thread 4 is still blocked.

    +

    Thread 2 unblocks thread 3 by an arbitrary RTOS-call (executed in SVC handler mode) at time index 2. The scheduler switches to thread 3 immediately because thread 3 has the highest priority. Thread 4 is still blocked.

    At time index 4 an interrupt (ISR) occurs and preempts the SysTick_Handler. RTX does not add any latency to the interrupt service execution. The ISR routine uses an RTOS-call that unblocks thread 4. Instead of switching to thread 4 immediately the PendSV flag is set to defer the context switching. The PendSV_Handler is executed right after the SysTick_Handler returns and the deferred context switch to thread 4 is carried out. As soon as highest priority thread 4 blocks again by using a blocking RTOS-call execution is switched back to thread 3 immediately during time index 5.

    At time index 5 thread 3 uses a blocking RTOS-call as well. Thus the scheduler switches back to thread 2 for time index 6. At time index 7 the scheduler uses the round-robin mechanism to switch to thread 1 and so on.

    @@ -219,6 +221,7 @@ Statically allocated memory for all objects Message Queue .bss.os.msgqueue.cb +

    It must be assured that these sections are placed into contiguous memory. This can fail, i.e. sections end up being split over multiple memory segments, when assigning compilation units to memory segments, manually.

    The following code example shows how to create an OS object using static memory.

    Code Example:

    /*----------------------------------------------------------------------------
    @@ -313,7 +316,7 @@ Low-Power Operation

    RTX Kernel Timer Tick

    RTX uses the generic OS Tick API to configure and control its periodic Kernel Tick.

    To use an alternative timer as the Kernel Tick Timer one simply needs to implement a custom version of the OS Tick API.

    -
    Note
    The OS Tick implementation provided must asure that the used timer interrupt uses the same (low) priority group as the service interrupts, i.e. interrupts used by RTX must not preempt each other. Refer to the Scheduler section for more details.
    +
    Note
    The OS Tick implementation provided must assure that the used timer interrupt uses the same (low) priority group as the service interrupts, i.e. interrupts used by RTX must not preempt each other. Refer to the Scheduler section for more details.

    Tick-less Low-Power Operation

    RTX5 provides extension for tick-less operation which is useful for applications that use extensively low-power modes where the SysTick timer is also disabled. To provide a time-tick in such power-saving modes, a wake-up timer is used to derive timer intervals. The CMSIS-RTOS2 functions osKernelSuspend and osKernelResume control the tick-less operation.

    @@ -383,7 +386,7 @@ RTX5 Header File

    Every implementation of the CMSIS-RTOS2 API can bring its own additional features. RTX5 adds a couple of functions for the idle more, for error notifications, and special system timer functions. It also is using macros for control block and memory sizes.

    If you require some of the RTX specific functions in your application code, #include the header file rtx_os.h:

    /*
    -
    * Copyright (c) 2013-2018 Arm Limited. All rights reserved.
    +
    * Copyright (c) 2013-2019 Arm Limited. All rights reserved.
    *
    * SPDX-License-Identifier: Apache-2.0
    *
    @@ -422,22 +425,22 @@ RTX5 Header File
    /// Kernel Information
    #define osRtxVersionAPI 20010003 ///< API version (2.1.3)
    -
    #define osRtxVersionKernel 50040000 ///< Kernel version (5.4.0)
    -
    #define osRtxKernelId "RTX V5.4.0" ///< Kernel identification string
    +
    #define osRtxVersionKernel 50050001 ///< Kernel version (5.5.1)
    +
    #define osRtxKernelId "RTX V5.5.1" ///< Kernel identification string
    // ==== Common definitions ====
    /// Object Identifier definitions
    #define osRtxIdInvalid 0x00U
    -
    #define osRtxIdThread 0x01U
    -
    #define osRtxIdTimer 0x02U
    -
    #define osRtxIdEventFlags 0x03U
    -
    #define osRtxIdMutex 0x04U
    -
    #define osRtxIdSemaphore 0x05U
    -
    #define osRtxIdMemoryPool 0x06U
    -
    #define osRtxIdMessage 0x07U
    -
    #define osRtxIdMessageQueue 0x08U
    +
    #define osRtxIdThread 0xF1U
    +
    #define osRtxIdTimer 0xF2U
    +
    #define osRtxIdEventFlags 0xF3U
    +
    #define osRtxIdMutex 0xF5U
    +
    #define osRtxIdSemaphore 0xF6U
    +
    #define osRtxIdMemoryPool 0xF7U
    +
    #define osRtxIdMessage 0xF9U
    +
    #define osRtxIdMessageQueue 0xFAU
    /// Object Flags definitions
    #define osRtxFlagSystemObject 0x01U
    @@ -880,14 +883,63 @@ Calls from Interrupt Service Routines
  • osMemoryPoolAlloc, osMemoryPoolFree, osMemoryPoolGetCapacity, osMemoryPoolGetBlockSize, osMemoryPoolGetCount, osMemoryPoolGetSpace
  • osMessageQueuePut, osMessageQueueGet, osMessageQueueGetCapacity, osMessageQueueGetMsgSize, osMessageQueueGetCount, osMessageQueueGetSpace
  • -

    Functions that cannot be called from an ISR are verifying the interrupt status and return the status code osErrorISR, in case they are called from an ISR context. In some implementations, this condition might be caught using the HARD_FAULT vector.

    +

    Functions that cannot be called from an ISR are verifying the interrupt status and return the status code osErrorISR, in case they are called from an ISR context. In some implementations, this condition might be caught using the HARD_FAULT vector.

    +

    +SVC Functions

    +

    Supervisor Calls (SVC) are exceptions targeted at software and operating systems for generating system function calls. They are sometimes called software interrupts. For example, instead of allowing user programs to directly access hardware, an operating system may provide access to hardware through an SVC. So when a user program wants to use certain hardware, it generates the exception using SVC instructions. The software exception handler in the operating system executes and provides the requested service to the user application. In this way, access to hardware is under the control of the OS, which can provide a more robust system by preventing the user applications from directly accessing the hardware.

    +

    SVCs can also make software more portable because the user application does not need to know the programming details of the underlying hardware. The user program will only need to know the application programming interface (API) function ID and parameters; the actual hardware-level programming is handled by device drivers.

    +

    SVCs run in privileged handler mode of the Arm Cortex-M core. SVC functions accept arguments and can return values. The functions are used in the same way as other functions; however, they are executed indirectly through the SVC instruction. When executing SVC instructions, the controller changes to the privileged handler mode.

    +

    Interrupts are not disabled in this mode. To protect SVC functions from interrupts, you need to include the disable/enable intrinsic functions __disable_irq() and __enable_irq() in your code.

    +

    You can use SVC functions to access protected peripherals, for example, to configure NVIC and interrupts. This is required if you run threads in unprivileged (protected) mode and you need to change interrupts from the within the thread.

    +

    To implement SVC functions in your Keil RTX5 project, you need to:

    +
      +
    1. Add the SVC User Table file svc_user.c to your project folder and include it into your project. This file is available as a user code template.
    2. +
    3. Write a function implementation. Example:
      uint32_t svc_atomic_inc32 (uint32_t *mem) {
      +
      // A protected function to increment a counter.
      +
      uint32_t val;
      +
      +
      __disable_irq();
      +
      val = *mem;
      +
      (*mem) = val + 1U;
      +
      __enable_irq();
      +
      +
      return (val);
      +
      }
      +
    4. +
    5. Add the function to the SVC function table in the svc_user.c module:
      void * const osRtxUserSVC[1+USER_SVC_COUNT] = {
      +
      (void *)USER_SVC_COUNT,
      +
      (void *)svc_atomic_inc32,
      +
      };
      +
    6. +
    7. Increment the number of user SVC functions:
      #define USER_SVC_COUNT 1 // Number of user SVC functions
      +
    8. +
    9. Declare a function wrapper to be called by the user to execute the SVC call.
      + Code Example (Arm Compiler 6)

      +
      __STATIC_FORCEINLINE uint32_t atomic_inc32 (uint32_t *mem) {
      +
      register uint32_t val;
      +
      +
      __ASM volatile (
      +
      "svc 1" : "=l" (val) : "l" (mem) : "cc", "memory"
      +
      );
      +
      return (val);
      +
      }
      +

      Code Example (Arm Compiler 5 using __svc(x) attribute)

      +
      uint32_t atomic_inc32 (uint32_t *mem) __svc(1);
      +
    10. +
    +
    Note
      +
    • The SVC function 0 is reserved for the Keil RTX5 kernel.
    • +
    • Do not leave gaps when numbering SVC functions. They must occupy a continuous range of numbers starting from 1.
    • +
    • SVC functions can still be interrupted.
    • +
    +