/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \mainpage \section Introduction FreeRTOS is one of the market leading real-time operating systems (RTOS) for embedded microcontrollers. It is professionally developed, strictly quality controlled, robust, supported (archive), free to use in commercial products without a requirement to expose proprietary source code, and has no IP infringement risk. CMSIS-RTOS v2 is a common API for real-time operating systems (RTOS). It provides a standardized programming interface that is portable to many RTOS and enables software components that can work across multiple RTOS systems. It supports the Armv8-M architecture, dynamic object creation, for multi-core systems, and has a binary compatible interface across ABI compliant compilers. Using this software pack, users can choose between a native FreeRTOS implementation or one that is adhering to the CMSIS-RTOS2 API and using FreeRTOS under the hood. The CMSIS-RTOS2 API enables programmers to create portable application code to be used with different RTOS kernels (for example Keil RTX5). This documentation shows you: - how to \ref cre_freertos_proj "create a new microcontroller project" using FreeRTOS from scratch. - Various \ref examples show you the usage of FreeRTOS in native and CMSIS-RTOS2 mode. - the \ref tech_data of this implementation. - \subpage rev_hist License ------- The CMSIS-FreeRTOS implementation is provided free of charge by Arm under the Apache 2.0 license.
The FreeRTOS kernel source files are released under the MIT open source license. ARM::CMSIS-FreeRTOS Pack ------------------------ The ARM::CMSIS-FreeRTOS pack contains the following: File/Directory |Content :--------------------------|:--------------------------------------------------------------------------------- \b CMSIS/Documentation | This documentation. \b CMSIS/RTOS2 | CMSIS-RTOS2 compliant implementation of FreeRTOS. \b License | FreeRTOS license agreement. \b Source | FreeRTOS kernel source code. \b ARM.CMSIS-FreeRTOS.pdsc | Package description file in CMSIS-Pack format. */ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \page cre_freertos_proj Create a FreeRTOS project You can basically choose between two option when creating a FreeRTOS project: -# \ref native_freertos using the FreeRTOS API and kernel. -# \ref cmsis_freertos using the CMSIS-RTOS2 API with an underlying FreeRTOS kernel. \section native_freertos Create a native FreeRTOS project The steps to create a microcontroller application using FreeRTOS are: - Create a new project and select a microcontroller device. - In the Manage Run-Time Environment window, select \::Device:Startup, \::RTOS:CORE and \::RTOS:Config in the \b FreeRTOS variant and an applicable \::RTOS:Heap scheme (for more information on the heap schemes, visit the FreeRTOS documentation): \image html manage_rte_freertos_native.png \n - If the Validation Output requires other components to be present, try to use the \b Resolve button. - Click \b OK. In the \b Project window, you will see the files that have been automatically added to you project, such as \b %FreeRTOSConfig.h, the source code files, as well as the system and startup files: \image html project_window_freertos_native.png \subsection native_freertos_config Configure FreeRTOS When you have created the native FreeRTOS project, you can configure the real-time operating system using the \b FreeRTOSConfig.h file. Please refer to the FreeRTOS documentation for more information on the specific settings. \image html freertos_config_h_native.png \subsection native_freertos_config_prio Interrupt priority configuration FreeRTOS implements critical sections using the BASEPRI register (available in Armv7-M and Armv8-M architecture based devices) which masks only a subset of interrupts. This is configured via the \c configMAX_SYSCALL_INTERRUPT_PRIORITY setting. Therefore, it is needed to properly configure this setting. It is also needed to set appropriate interrupt priorities for interrupt service routines (ISR) that use RTOS functions. This can especially impact drivers which typically use peripheral interrupts. Normally, these use the RTOS directly or indirectly through registered callbacks. Arm Cortex-M cores store interrupt priority values in the most significant bits of the interrupt priority registers which can have a maximum of eight bits. Many implementations offer only three priority bits. These three bits are shifted up to be bits five, six and seven respectively. \c configMAX_SYSCALL_INTERRUPT_PRIORITY must not be 0 and can be xxx00000. This results in the following table: | configMAX_SYSCALL_INTERRUPT_PRIORITY | Upper three bits | Priority | |:---------------------------------------:|:----------------:|:-----------:| | 32 | 001 | 1 (Highest) | | 64 | 010 | 2 | | 96 | 011 | 3 | | 128 | 100 | 4 | | 160 | 101 | 5 | | 196 | 110 | 6 | | 224 | 111 | 7 (Lowest) | \b Example If you set \c configMAX_SYSCALL_INTERRUPT_PRIORITY to 32, then the priority of an interrupt service routine that uses RTOS functions must then be higher or equal to 1. This ensures that this interrupt will be masked during critical a section. A WiFi driver using the SPI interface registers a callback to SPI which is executed in an interrupt context. The callback function in the WiFi driver uses RTOS functions. Therefore, the SPI interrupt priority must be set to a value equal or higher to the FreeRTOS preempt priority, for example 1. \note For a detailed description of how FreeRTOS is using Cortex-M code registers, refer to Running the RTOS on a ARM Cortex-M Core. \subsection native_freertos_er Add Event Recorder Visibility - To use the Event Recorder together with FreeRTOS, add the software component \::Compiler:Event Recorder to your project. - Open \ref native_freertos_config "FreeRTOSConfig.h" and - verify the header file \b freertos_evr.h is included - add Event Recorder configuration definitions (see \ref cmsis_freertos_evr_config) - Call EvrFreeRTOSSetup() in your application code (ideally in \c main()). - If you are using simulation mode, add an initialization file with the following content: \code MAP 0xE0001000, 0xE0001007 READ WRITE signal void DWT_CYCCNT (void) { while (1) { rwatch(0xE0001004); _WWORD(0xE0001004, states); } } DWT_CYCCNT() \endcode - Build the application code and download it to the debug hardware or run it in simulation. Once the target application generates event information, it can be viewed in the µVision debugger using the Event Recorder. \section cmsis_freertos Create a CMSIS-FreeRTOS project The steps to create a microcontroller application using CMSIS-FreeRTOS are: - Create a new project and select a microcontroller device. - In the Manage Run-Time Environment window, select \::Device:Startup, \::CMSIS::RTOS2 (API)\::FreeRTOS, \::RTOS:CORE in the \b FreeRTOS variant, \::RTOS:Config in the \b CMSIS \b RTOS2 variant, \::RTOS:Timers, \::RTOS:Event Groups, and an applicable \::RTOS:Heap scheme (for more information on the heap schemes, visit the FreeRTOS documentation): \image html manage_rte_freertos_rtos2.png \n - If the Validation Output requires other components to be present, try to use the \b Resolve button. - Click \b OK. In the \b Project window, you will see the files that have been automatically added to you project, such as \b %FreeRTOSConfig.h, the source code files, as well as the system and startup files: \image html project_window_freertos_rtos2.png \subsection cmsis_freertos_config Configure CMSIS-FreeRTOS When you have created the CMSIS-FreeRTOS project, you can configure the real-time operating system using the \b FreeRTOSConfig.h file. It can be opened using the Configuration Wizard view: \image html freertos_config_h_cmsis_rtos.png The following main settings are available: Name | \#define | Description | -------------------------------|--------------------------------------|-----------------------------------------------------------------------| Minimal stack size [words] | configMINIMAL_STACK_SIZE | Stack for idle task and default task stack in words. | Total heap size [bytes] | configTOTAL_HEAP_SIZE | Heap memory size in bytes. | Kernel tick frequency [Hz] | configTICK_RATE_HZ | Kernel tick rate in Hz. | Timer task stack depth [words] | configTIMER_TASK_STACK_DEPTH | Stack for timer task in words. | Timer task priority | configTIMER_TASK_PRIORITY | Timer task priority. | Timer queue length | configTIMER_QUEUE_LENGTH | Timer command queue length. | Preemption interrupt priority | configMAX_SYSCALL_INTERRUPT_PRIORITY | Maximum priority of interrupts that are safe to call FreeRTOS API. | Use time slicing | configUSE_TIME_SLICING | Enable setting to use time slicing. | Use tickless idle | configUSE_TICKLESS_IDLE | Enable low power tickless mode that stops tick interrupt when idle. | Idle should yield | configIDLE_SHOULD_YIELD | Control Yield behavior of the idle task. | Check for stack overflow | configCHECK_FOR_STACK_OVERFLOW | Enable or disable stack overflow checking. | Use idle hook | configUSE_IDLE_HOOK | Enable callback function call on each idle task iteration. | Use tick hook | configUSE_TICK_HOOK | Enable callback function call during each tick interrupt. | Use daemon task startup hook | configUSE_DAEMON_TASK_STARTUP_HOOK | Enable callback function call when timer service starts. | Use malloc failed hook | configUSE_MALLOC_FAILED_HOOK | Enable callback function call when out of dynamic memory. | Queue registry size | configQUEUE_REGISTRY_SIZE | Define maximum number of queue objects registered for debug purposes. | \note Refer to \ref native_freertos_config_prio for more information on the usage of \c configMAX_SYSCALL_INTERRUPT_PRIORITY. Event Recorder Configuration The following settings are available (see \ref cmsis_freertos_evr_config for details): Name | \#define | Description | -------------------------------|--------------------------------------|-----------------------------------------------------------------------------------------| Initialize Event Recorder | configEVR_INITIALIZE | Initialize Event Recorder before FreeRTOS kernel start. | Setup recording level filter | configEVR_SETUP_LEVEL | Enable configuration of FreeRTOS events recording level. | Task functions | configEVR_LEVEL_TASKS | Define event recording level bitmask for events generated from Tasks functions. | Queue functions | configEVR_LEVEL_QUEUE | Define event recording level bitmask for events generated from Queue functions. | Timer functions | configEVR_LEVEL_TIMERS | Define event recording level bitmask for events generated from Timer functions. | Event Groups functions | configEVR_LEVEL_EVENTGROUPS | Define event recording level bitmask for events generated from Event Groups functions. | Heap functions | configEVR_LEVEL_HEAP | Define event recording level bitmask for events generated from Heap functions. | Stream Buffer functions | configEVR_LEVEL_STREAMBUFFER | Define event recording level bitmask for events generated from Stream Buffer functions. | Memory Allocation Configuration The following settings are available: Name | \#define | Description | ---------------------------------------|--------------------------------------|------------------------------------------------------------------------------------| Support static memory allocation | configSUPPORT_STATIC_ALLOCATION | Enable or disable support for static memory allocation. | Support dynamic memory allocation | configSUPPORT_DYNAMIC_ALLOCATION | Enable or disable support for dynamic memory allocation. | Use kernel provided static memory | configKERNEL_PROVIDED_STATIC_MEMORY | When enabled, FreeRTOS kernel provides static memory for Idle and Timer tasks. | Use application allocated heap | configAPPLICATION_ALLOCATED_HEAP | When enabled, application must provide heap buffer externally. | Use separate heap for stack allocation | configSTACK_ALLOCATION_FROM_SEPARATE_HEAP | Enable or disable stack allocation for any task from a separate heap. | Use heap protector | configENABLE_HEAP_PROTECTOR | Enable or disable bounds checking and obfuscation to heap block pointers. | Port Specific Configuration The following settings are available: Name | \#define | Description | ----------------------------------|---------------------------------|------------------------------------------------------------------------------------| Use Floating Point Unit | configENABLE_FPU | Enable or disable support for FPU when switching execution context. | Use M-Profile Vector Extension | configENABLE_MVE | Enable or disable support for MVE when switching execution context. | Use Memory Protection Unit | configENABLE_MPU | Enable or disable support for MPU on ARMv8-M MPU enabled ports. | Use TrustZone Secure Side Only | configRUN_FREERTOS_SECURE_ONLY | Enable this setting when FreeRTOS runs on the Secure side only. | Use TrustZone Security Extension | configENABLE_TRUSTZONE | Enable TrustZone when FreeRTOS runs on the Non-Secure side and calls functions from the Secure side.| Minimal secure stack size [words] | configMINIMAL_SECURE_STACK_SIZE | Stack for idle task Secure side context in words. | Interrupt Controller Configuration \note Settings related to interrupt controller are relevant only on ARMv7-A ports where it is necessary to configure Arm Generic Interrupt Controller (GIC). The following settings are available: Name | \#define | Description | ------------------------------------------|-------------------------------------------------|---------------------------------------------------------------| Interrupt controller base address | configINTERRUPT_CONTROLLER_BASE_ADDRESS | Sets the base address of the interrupt controller peripheral. | Interrupt controller CPU interface offset | configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET | Sets the offset from interrupt controller base address at which the CPU interface starts. | Interrupt controller unique priorities | configUNIQUE_INTERRUPT_PRIORITIES | Sets the number of unique priorities that can be specified in the interrupt controller peripheral. | Symmetric Multiprocessing Configuration \note Symmetric Multiprocessing Configuration (SMP) settings are only relevant if FreeRTOS port implementation supports SMP. The following settings are available: Name | \#define | Description | ----------------------------|-----------------------------|------------------------------------------------------------------| Number of processor cores | configNUMBER_OF_CORES | Sets the number of available processor cores. | Use processor core affinity | configUSE_CORE_AFFINITY | Enables the control for task to run on specific processor cores. | Use passive idle hook | configUSE_PASSIVE_IDLE_HOOK | Enable callback function call on each idle task iteration. | \subsection cmsis_freertos_er Add Event Recorder Visibility - To use the Event Recorder together with FreeRTOS, add the software component \::Compiler:Event Recorder to your project. - Open \ref native_freertos_config "FreeRTOSConfig.h" and - verify the header file \b freertos_evr.h is included - modify Event Recorder configuration definitions (see \ref cmsis_freertos_evr_config) to change default configuration - Call osKernelInitialize() in your application code (ideally in \c main()) to setup Event Recorder according to configuration settings. - If you are using simulation mode, add an initialization file with the following content: \code MAP 0xE0001000, 0xE0001007 READ WRITE signal void DWT_CYCCNT (void) { while (1) { rwatch(0xE0001004); _WWORD(0xE0001004, states); } } DWT_CYCCNT() \endcode - Build the application code and download it to the debug hardware or run it in simulation. Once the target application generates event information, it can be viewed in the µVision debugger using the Event Recorder. \section freertos_interfaces Create a mixed-interface project Using CMSIS-RTOS2 API and native FreeRTOS API simultaneously is possible and some projects do require using the native FreeRTOS API and the CMSIS-RTOS2 API at the same time. Such project should be \ref cmsis_freertos "created as CMSIS-FreeRTOS project". Depending on the application requirements, FreeRTOS kernel can be started either by using FreeRTOS native API or by using CMSIS-RTOS2 API. \subsection freertos_interface_rtos2 Start the kernel using CMSIS-RTOS2 API \code /* Application thread: Initialize and start the Application */ void app_main (void *argument) { while(1) { // Application code // ... } } /* Main function: Initialize and start the kernel */ int main (void) { SystemCoreClockUpdate(); // Initialize CMSIS-RTOS2 osKernelInitialize(); // Create application main thread osThreadNew(app_main, NULL, NULL); // Start the kernel and execute the first thread osKernelStart(); while(1); } \endcode \b Restrictions After the kernel is started using CMSIS-RTOS2 API, FreeRTOS native API can be used with the following restrictions: - vTaskStartScheduler must not be called \subsection freertos_interface_native Start the kernel using native API \code /* Application main thread: Initialize and start the application */ void app_main (void *argument) { while(1) { // Application code // ... } } /* Main function: Initialize and start the kernel */ int main (void) { SystemCoreClockUpdate(); // Setup the Event Recorder (optionally) EvrFreeRTOSSetup(0); // Create application main thread xTaskCreate (app_main, "app_main", 64, NULL, tskIDLE_PRIORITY+1, NULL); // Start the kernel and execute the first thread vTaskStartScheduler(); while(1); } \endcode \b Restrictions After the kernel is started using FreeRTOS native API, CMSIS-RTOS2 API can be used without restrictions. \section cmsis_freertos_evr_config Configure Event Recorder This section describes the configuration settings for the Event Recorder annotations. For more information refer to section \ref native_freertos_er "Add Event Recorder Visibility to native FreeRTOS project" or \ref cmsis_freertos_er "Add Event Recorder Visibility to CMSIS-FreeRTOS project". Use below definitions to configure Event Recorder initialization and recording level filter setup. \code #define configEVR_INITIALIZE \endcode Value | Description | -------|---------------------------------------| 0 | Disable Event Recorder initialization | 1 | Enable Event Recorder initialization | Definition configEVR_INITIALIZE enables Event Recorder initialization during execution of function \ref EvrFreeRTOSSetup. Default value is \token{1}. \code #define configEVR_SETUP_LEVEL \endcode Value | Description | -------|---------------------------------------| 0 | Disable recording level filter setup | 1 | Enable recording level filter setup | Definition configEVR_SETUP_LEVEL enables setup of recording level filter for events generated by FreeRTOS. Recording level is configured during execution of function \ref EvrFreeRTOSSetup. Default value is \token{1}. \code #define configEVR_LEVEL_TASKS #define configEVR_LEVEL_QUEUE #define configEVR_LEVEL_TIMERS #define configEVR_LEVEL_EVENTGROUPS #define configEVR_LEVEL_HEAP #define configEVR_LEVEL_STREAMBUFFER \endcode Value | Description | -------|--------------------------------------------------------| 0x00 | Disable event generation | 0x01 | Enable generation of error events | 0x05 | Enable generation of error and operational events | 0x07 | Enable generation of error, API and operational events | 0x0F | Enable generation of all events | Definitions configEVR_LEVEL_x set the recording level bitmask for events generated by each function group. They are taken into account only when recording level filter setup is enabled. Default value is \token{0x05}. \section dbg_cmsisfreertos Debug a CMSIS-FreeRTOS project \note The following only applies when used with Arm Keil MDK. If you are using a different toolchain, please consult its user's manual. Apart from the debug capabilities that \ref cmsis_freertos_evr_config "Event Recorder" offers, Keil MDK also supports thread aware breakpoints, just like for the standard CMSIS-RTOS. \b Code \b Example \code BS FuncN1, 1, "break = (CURR_TID == tid_phaseA) ? 1 : 0" BS FuncN1, 1, "break = (CURR_TID == tid_phaseA || CURR_TID == tid_phaseD) ? 1 : 0" BS \\Blinky\Blinky.c\FuncN1\179, 1, "break = (CURR_TID == tid_phaseA || CURR_TID == tid_phaseD) ? 1 : 0" \endcode \note - For more information on conditional breakpoints in Keil MDK, consult the user's manual. - Enabling Periodic Window Update is required to capture register values for active running threads while executing. When turned off, only the current FreeRTOS thread can be unwound after execution has been stopped. \b Caveats - You cannot specify individual breakpoints on the same address. The following is not possible: \code BS ThCallee, 1, "break = (CURR_TID==tid_phaseA) ? 1 : 0" BS ThCallee, 1, "break = (CURR_TID==tid_phaseD) ? 1 : 0" \endcode Instead, use this: \code BS ThCallee, 1, "break= (CURR_TID==tid_phaseA || CURR_TID==tid_phaseD) ? 1 : 0" \endcode - If you don't want to use Periodic Window Update, obtain the thread and unwind information by adding a function that gets called from each thread of interest: \code _attribute_((noinline)) int FuncN1 (int n1) { ... } \endcode Then, specify a thread aware breakpoint using an "invalid" thread ID: \code BS FuncN1, 1, "break = (CURR_TID == tid_phaseA + 1) ? 1 : 0" \endcode 'tid_phaseA' would be valid, 'tid_phaseA + 1' is not but will still capture the most recent registers and store them to the actual thread context each time a thread aware breakpoint is checked. - Function inlining typically causes thread aware breakpoints to fail. To avoid this, prepend the 'noinline' attribute to the function that is used to stop when the current FreeRTOS thread id matches: \code _attribute_((noinline)) int FuncN1 (int n1) { ... } \endcode This helps to make thread aware breakpoints far less dependent on the compiler optimization level. - Thread aware breakpoints should be setup using a debug script. Reason being that thread aware breakpoints are of a 'hybrid' type, that is a combined address and condition expression that works best when run from a debug script. */ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \page examples Example projects This pack contains two example projects: - \ref example_hello - \ref example_trustzone The first example shows how to configure a simple application using FreeRTOS with CMSIS-RTOS2, whereas the second example shows how to use the FreeRTOS with CMSIS-RTOS2 in an application that utilizes TrustZone secure/non-secure execution. Provided examples use the [CMSIS Solution Project File Format](https://github.com/Open-CMSIS-Pack/cmsis-toolbox/blob/main/docs/YML-Input-Format.md) and can be build for multiple Cortex-M targets - using [CMSIS Toolbox](https://github.com/Open-CMSIS-Pack/cmsis-toolbox/blob/main/docs/README.md#cmsis-toolbox) either from the command line or - from Visual Studio Code by using [Arm Keil Studio Cloud extensions](https://developer.arm.com/documentation/108029/0000/?lang=en). The \b Examples solution defines projects and build information for each project. \section build_run Build and Run The \b Examples solution supports only "Debug" Build-Type which is optimized for debugging. It disables compiler optimization and retains all debug related information. By default, Arm Compiler 6 is used to build the projects. \subsection build_target_types Targets Each example can be built for multiple target processors. The below table lists supported target processors together with the corresponding context target-types and model executable that shall be used for running the application image. | Target processor | Target-Type | Model Executable | |:-----------------|:------------|:-----------------------| | Cortex-M0 | CM0 | FVP_MPS2_Cortex-M0 | | Cortex-M0+ | CM0plus | FVP_MPS2_Cortex-M0plus | | Cortex-M3 | CM3 | FVP_MPS2_Cortex-M3 | | Cortex-M4 | CM4 | FVP_MPS2_Cortex-M4 | | Cortex-M7 | CM7 | FVP_MPS2_Cortex-M7 | | Cortex-M23 | CM23 | FVP_MPS2_Cortex-M23 | | Cortex-M23 | CM23_noTZ | FVP_MPS2_Cortex-M23 | | Cortex-M33 | CM33 | FVP_MPS2_Cortex-M33 | | Cortex-M33 | CM33_noTZ | FVP_MPS2_Cortex-M33 | | Cortex-M55 | CM55 | FVP_Corstone_SSE-300 | | Cortex-M55 | CM55_noTZ | FVP_Corstone_SSE-300 | | Cortex-M85 | CM85 | FVP_Corstone_SSE-310 | | Cortex-M85 | CM85_noTZ | FVP_Corstone_SSE-310 | \subsection build_vscode Build in VS Code using Arm Keil Studio Pack extensions - See [Arm Keil Studio Visual Studio Code Extensions User Guide](https://developer.arm.com/documentation/108029/0000/?lang=en) for more information about using the Keil Studio extensions. - Search for [Arm Keil Studio Pack](https://marketplace.visualstudio.com/items?itemName=Arm.keil-studio-pack) in the Visual Studio Marketplace to download the extensions. To build a project using Keil Studio extensions open CMSIS view, open "Manage CMSIS Solution" view and select "Active Context" and "Active Projects". Build Type is automatically selected since there is only one option. Once the context and projects are selected one can build them by selecting "Build" in CMSIS view. \subsection build_cmdline Build via command line - See [CMSIS-Toolbox documentation](https://github.com/Open-CMSIS-Pack/cmsis-toolbox/blob/main/docs/README.md) to learn more about CMSIS Solution project build and management tools. To build the project via command line one can use the following command syntax: \code{.sh} cbuild Examples.csolution.yml --context .+ \endcode To list the available contexts execute the following command: \code{.sh} cbuild list contexts Examples.csolution.yml \endcode \subsection example_exec Execute on Virtual Hardware Target [Arm Virtual Hardware Target](https://www.arm.com/products/development-tools/simulation/virtual-hardware) simulation models are used to execute the example application images. To execute application image (axf or elf) on an simulation model use the following command syntax: \code{.sh} -f ./Target//fvp_config.txt -a ./out//.axf \endcode \section example_hello Hello World The Hello World application can be used as a starting point when developing new application. Using it, one can verify initial system setup and configuration. The application is simple and shows how to use CMSIS-RTOS2: - how to initialize and start the RTOS kernel - how to create a new thread - how to retarget stdout Build via command line The following cbuild command may be used to build Hello World example project for Cortex-M3: \code{.sh} cbuild Examples.csolution.yml --context Hello.Debug+CM3 --update-rte \endcode Execute via command line To execute simulation model and run Hello World project executable for Cortex-M3 use the following command: \code{.sh} FVP_MPS2_Cortex-M3 -f ./Target/CM3/fvp_config.txt -a ./out/Hello/Hello.axf \endcode When executed, application outputs the following to the serial terminal: \image html hello_out.png (Press Ctrl + C to stop the simulation model.) \section example_trustzone TrustZone The TrustZone application explains how to setup projects for booting and execution from TrustZone secure to non-secure domain and vice versa. The application shows: - how to boot from the secure domain and switch the execution to the non-secure domain - how to create the interface functions between secure and non-secure domain - how to use the secure/non-secure interface functions Build via command line TrustZone example must always be build in two steps: 1. Build secure side project for Cortex-M55 \code{.sh} cbuild Examples.csolution.yml --context TZ_Secure.Debug+CM55 --update-rte \endcode 2. Build non-secure side project for Cortex-M55 \code{.sh} cbuild Examples.csolution.yml --context TZ_NonSecure.Debug+CM55 --update-rte \endcode Execute via command line To execute simulation model and run TrustZone project executable for Cortex-M55 use the following command: \code{.sh} FVP_Corstone_SSE-300 -f ./Target/CM55/fvp_config.txt -a ./out/TZ_NonSecure/TZ_NonSecure.axf -a ./out/TZ_Secure/TZ_Secure.axf \endcode When executed, application outputs the following to the serial terminal: \image html trustzone_out.png (Press Ctrl + C to stop the simulation model.) */ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \page tech_data Technical data and limitations This lists the technical data of CMSIS-FreeRTOS. \section td_limitations Limitations The following list briefly describes the limitations and unsupported features of the CMSIS-RTOS2 wrapper for FreeRTOS: - Static memory allocation will only work if \a all memory (from attributes structure) is provided statically. In order to allocate object memory statically, you need to: - provide the memory for control blocks and stack in the \c osThreadAttr_t structure for threads. - provide the memory for control blocks and message data in the \c osMessageQueueAttr_t structure for memory queues. - provide the memory for control blocks for other objects in the object's attributes structure. - Each timer object requires additional 8 bytes of memory: - to allocate all memory statically, provide the memory for control block of size (sizeof(StaticTimer_t) + 8 bytes) - otherwise, additional 8 bytes of dynamic memory will be used - \c osKernelSuspend and \c osKernelResume are not supported. - \c osThreadDetach, \c osThreadJoin() and attribute \c osThreadJoinable are not supported (\c osThreadNew returns NULL when osThreadJoinable attribute is specified). - \c osThreadGetStackSize is not implemented. - Event flags are limited to 24 bits. - \c osEventFlagsGetName is not implemented. - \c osEventFlagsWait cannot be called from an ISR. - Priority inherit protocol is used as default mutex behavior (\c osMutexNew creates priority inherit mutex object by default and ignores \c osMutexPrioInherit attribute when specified). - Robust mutex objects are not supported (\c osMutexNew returns NULL when \c osMutexRobust attribute is specified). - \c osMutexGetName is not implemented and always returns NULL. - \c osSemaphoreGetName is not implemented and always returns NULL. - \c osMessageQueueGetName is not implemented and always returns NULL. - \c osMessageQueuePut and \c osMessageQueueGet always ignore message priority. - Process Isolation (Functional Safety) functions are not implemented. \section td_validation Validation suite results CMSIS provides a CMSIS-RTOS2 validation suite that can be used to test a real-time operating system for compliance to the standard. The test suite has been executed successfully on the CMSIS-FreeRTOS implementation (see results). The following table explains the exceptions:
Test Case Result Reason Summary
TC_osKernelGetState_2 not executed unsupported feature Test attempts to call \c osKernelGetState after a \c osKernelSuspend call. osKernelSuspend is not implemented.
TC_osKernelLock_2 not executed unsupported feature Test attempts to call \c osKernelLock after a \c osKernelSuspend call. \c osKernelSuspend is not implemented.
TC_osKernelUnlock_2 not executed unsupported feature Test attempts to call \c osKernelUnlock after a \c osKernelSuspend call. \c osKernelSuspend is not implemented.
TC_osKernelSuspend_1 not executed unsupported feature Test validates \c osKernelSuspend which is not implemented.
TC_osKernelResume_1 not executed unsupported feature Test validates \c osKernelResume which is not implemented.
TC_osThreadNew_3 not executed unsupported feature Test attempts to create joinable thread using \c osThreadJoinable attribute. FreeRTOS does not support joinable threads.
TC_osThreadGetName_1 failed deviation Test attempt to retrieve a name on an unnamed thread. An empty string is returned instead of NULL pointer.
TC_osThreadGetState_3 not executed unsupported feature Test attempts to retrieve a state of a terminated joinable thread. FreeRTOS does not support joinable threads.
TC_osThreadDetach_1 not executed unsupported feature Test validates \c osThreadDetach which is not implemented.
TC_osThreadDetach_2 not executed unsupported feature Test validates \c osThreadDetach which is not implemented.
TC_osThreadJoin_1 not executed unsupported feature Test validates \c osThreadJoin which is not implemented.
TC_osThreadJoin_2 not executed unsupported feature Test validates \c osThreadJoin which is not implemented.
TC_osThreadJoin_3 not executed unsupported feature Test validates \c osThreadJoin which is not implemented.
TC_osThreadGetStackSize_1 not executed unsupported feature Test validates \c osThreadGetStackSize which is not implemented.
TC_ThreadReturn not executed unsupported feature Test attempts to terminate a thread by just returning from a thread. FreeRTOS threads may not return.
TC_osEventFlagsSet_1 failed deviation Test attempts to set event flags by calling \c osEventFlagsSet multiple times without leaving ISR handler.
To process ISR requests, FreeRTOS uses timer deamon which wakes-up after ISR execution.
TC_osEventFlagsClear_1 failed deviation Test attempts to clear event flags by calling \c osEventFlagsClear multiple times without leaving ISR handler.
To process ISR requests, FreeRTOS uses timer deamon which wakes-up after ISR execution.
TC_osEventFlagsWait_1 failed unsupported feature Test attempts to wait for flags from ISR with zero timeout (try-semantic). FreeRTOS does not support such operation.
TC_osEventFlagsGetName_1 not executed unsupported feature Test validates \c osEventFlagsGetName which is not implemented.
TC_osMutexNew_4 not executed unsupported feature Test attempts to create a robust mutex. FreeRTOS implementation does not support robust mutexes.
TC_osMutexGetName_1 not executed unsupported feature Test validates \c osMutexGetName which is not implemented.
TC_MutexRobust not executed unsupported feature Test attempts to validate robust mutex behavior. FreeRTOS implementation does not support robust mutexes.
TC_MutexOwnership not executed unsupported feature Test attempts to release a mutex from a thread which is not the mutex owner.
FreeRTOS implementation does not verify ownership on mutex release.
TC_osSemaphoreGetName_1 not executed unsupported feature Test validates \c osSemaphoreGetName which is not implemented.
TC_osMessageQueueGetName_1 not executed unsupported feature Test validates \c osMessageQueueGetName which is not implemented.
\section td_troubleshooting Troubleshooting Users looking for help shall check subsection of the full FreeRTOS FAQ. It contains many useful information that also apply when using FreeRTOS in context of CMSIS-FreeRTOS. Additionally, please take a look at the following:
  1. Interrupts are disabled when main is called or before the kernel is started
    Before the FreeRTOS kernel is started, threads (i.e. tasks) may be created together with other objects like mutexes, semaphores, message queues etc. When functions like xTaskCreate, xSemaphoreCreateMutex, xQueueCreate and others get called, they prevent interrupt handlers from calling FreeRTOS API functions in order to keep FreeRTOS kernel variables and state machine consistent (see also here Interrupts are not executing).
    In cases when interrupts may be executed after object creation and before the FreeRTOS kernel is started they can be re-enabled: \code{.c} portENABLE_INTERRUPTS(); \endcode Make sure that the interrupts you execute in such case do not call FreeRTOS API.
*/ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \page functionOverview Function Overview \section rtos_api2 CMSIS-RTOS2 API Overview of all CMSIS-RTOS C API v2 functions that are implemented in CMSIS-FreeRTOS. Kernel Information and Control ------------------------------ See API reference for details about Kernel Information and Control functions. - \b osKernelInitialize: supported - \b osKernelGetInfo: supported - \b osKernelGetState: supported - \b osKernelStart: supported - \b osKernelLock: supported - \b osKernelUnlock: supported - \b osKernelRestoreLock: supported - \b osKernelSuspend: \token{not implemented} - \b osKernelResume: \token{not implemented} - \b osKernelProtect: \token{not implemented} - \b osKernelDestroyClass: \token{not implemented} - \b osKernelGetTickCount: supported - \b osKernelGetTickFreq: supported - \b osKernelGetSysTimerCount: supported - \b osKernelGetSysTimerFreq: supported Thread Management ----------------- See API reference for details about Thread Management functions. - \b osThreadNew: supported - \b osThreadGetName: supported - \b osThreadGetClass: \token{not implemented} - \b osThreadGetZone: \token{not implemented} - \b osThreadGetId: supported - \b osThreadGetState: supported - \b osThreadGetStackSize: \token{not implemented} - \b osThreadGetStackSpace: supported - \b osThreadSetPriority: supported - \b osThreadGetPriority: supported - \b osThreadYield: supported - \b osThreadSuspend: supported - \b osThreadResume: supported - \b osThreadDetach: \token{not implemented} - \b osThreadJoin: \token{not implemented} - \b osThreadExit: supported - \b osThreadTerminate: supported - \b osThreadFeedWatchdog: \token{not implemented} - \b osThreadProtectPrivileged: \token{not implemented} - \b osThreadSuspendClass: \token{not implemented} - \b osThreadResumeClass: \token{not implemented} - \b osThreadTerminateZone: \token{not implemented} - \b osThreadGetCount: supported - \b osThreadEnumerate: supported Thread Flags ------------ See API reference for details about Thread Flags functions. - \b osThreadFlagsSet: supported - \b osThreadFlagsClear: supported - \b osThreadFlagsGet: supported - \b osThreadFlagsWait: supported Generic Wait Functions ---------------------- See API reference for details about Generic Wait functions. - \b osDelay: supported - \b osDelayUntil: supported Timer Management ---------------- See API reference for details about Timer Management functions. - \b osTimerNew: supported - \b osTimerGetName: supported - \b osTimerStart: supported - \b osTimerStop: supported - \b osTimerIsRunning: supported - \b osTimerDelete: supported Event Flags ----------- See API reference for details about Event Flags functions. All event flags are limited to 24 bits. - \b osEventFlagsNew: supported - \b osEventFlagsGetName: \token{not implemented} - \b osEventFlagsSet: supported - \b osEventFlagsClear: supported - \b osEventFlagsGet: supported - \b osEventFlagsWait: cannot be called from an ISR. - \b osEventFlagsDelete: supported Mutex Management ---------------- See API reference for details about Mutex Management functions.\n Priority inherit protocol is used as default mutex behavior (osMutexNew creates priority inherit mutex object by default and ignores osMutexPrioInherit attribute when specified).\n Robust mutex objects are not supported (osMutexNew returns NULL when osMutexRobust attribute is specified).\n - \b osMutexNew: supported - \b osMutexGetName: \token{not implemented} - \b osMutexAcquire: supported - \b osMutexRelease: supported - \b osMutexGetOwner: supported - \b osMutexDelete: supported Semaphores ---------- See API reference for details about Semaphore functions. - \b osSemaphoreNew: supported - \b osSemaphoreGetName: \token{not implemented} - \b osSemaphoreAcquire: supported - \b osSemaphoreRelease: supported - \b osSemaphoreGetCount: supported - \b osSemaphoreDelete: supported Memory Pool ----------- See API reference for details about Memory Pool functions. - \b osMemoryPoolNew: supported - \b osMemoryPoolGetName: supported - \b osMemoryPoolAlloc: supported - \b osMemoryPoolFree: supported - \b osMemoryPoolGetCapacity: supported - \b osMemoryPoolGetBlockSize: supported - \b osMemoryPoolGetCount: supported - \b osMemoryPoolGetSpace: supported - \b osMemoryPoolDelete: supported Message Queue ------------- See API reference for details about Message Queue functions. - \b osMessageQueueNew: supported - \b osMessageQueueGetName: \token{not implemented} - \b osMessageQueuePut: ignores message priority. - \b osMessageQueueGet: ignores message priority. - \b osMessageQueueGetCapacity: supported - \b osMessageQueueGetMsgSize: supported - \b osMessageQueueGetCount: supported - \b osMessageQueueGetSpace: supported - \b osMessageQueueReset: supported - \b osMessageQueueDelete: supported */ /* ======================================================================================================================== */ // Group creation for Reference /** \addtogroup freertos_specific CMSIS-FreeRTOS Specifics \brief This section describes CMSIS-FreeRTOS specifics. \details CMSIS-FreeRTOS interfaces to the Event Recorder to provide event information which helps you to understand and analyze the operation. Refer to \ref freertos_evr for more information. */