RA Flexible Software Package Documentation  Release v5.2.0

 
FreeRTOS Port (rm_freertos_port)

FreeRTOS port for RA MCUs.

Overview

Note
The FreeRTOS Port does not provide any interfaces to the user. Consult the FreeRTOS documentation at https://www.freertos.org/Documentation for further information.

Features

The RA FreeRTOS port supports the following features:

Configuration

Note
The FreeRTOS Port and libraries use printf by default when logging is enabled. printf requires a heap (BSP Tab -> Properties -> RA Common -> Heap size (bytes)).

Build Time Configurations for all

The following build time configurations are defined in aws/FreeRTOSConfig.h:

ConfigurationOptionsDefaultDescription
General
Custom FreeRTOSConfig.hManual EntryAdd a path to your custom FreeRTOSConfig.h file. It can be used to override some or all of the configurations defined here, and to define additional configurations.
Use Preemption
  • Enabled
  • Disabled
Enabled Set to Enabled to use the preemptive RTOS scheduler, or Disabled to use the cooperative RTOS scheduler.
Use Port Optimised Task Selection
  • Enabled
  • Disabled
Disabled Some FreeRTOS ports have two methods of selecting the next task to execute - a generic method, and a method that is specific to that port.

The Generic method:
Is used when Use Port Optimized Task Selection is set to 0, or when a port specific method is not implemented.
Can be used with all FreeRTOS ports.
Is completely written in C, making it less efficient than a port specific method.
Does not impose a limit on the maximum number of available priorities.

A port specific method:
Is not available for all ports.
Is used when Use Port Optimized Task Selection is Enabled.
Relies on one or more architecture specific assembly instructions (typically a Count Leading Zeros [CLZ] or equivalent instruction) so can only be used with the architecture for which it was specifically written.
Is more efficient than the generic method.
Typically imposes a limit of 32 on the maximum number of available priorities.
Use Tickless Idle
  • Enabled
  • Disabled
Disabled Set Use Tickless Idle to Enabled to use the low power tickless mode, or Disabled to keep the tick interrupt running at all times. Low power tickless implementations are not provided for all FreeRTOS ports.
Cpu Clock HzManual EntrySystemCoreClock Enter the frequency in Hz at which the internal clock that drives the peripheral used to generate the tick interrupt will be executing - this is normally the same clock that drives the internal CPU clock. This value is required in order to correctly configure timer peripherals.
Tick Rate HzMust be an integer and greater than 01000 The frequency of the RTOS tick interrupt.
The tick interrupt is used to measure time. Therefore a higher tick frequency means time can be measured to a higher resolution. However, a high tick frequency also means that the RTOS kernel will use more CPU time so be less efficient. The RTOS demo applications all use a tick rate of 1000Hz. This is used to test the RTOS kernel and is higher than would normally be required.

More than one task can share the same priority. The RTOS scheduler will share processor time between tasks of the same priority by switching between the tasks during each RTOS tick. A high tick rate frequency will therefore also have the effect of reducing the 'time slice' given to each task.
Max PrioritiesMust be an integer and greater than 05 The number of priorities available to the application tasks. Any number of tasks can share the same priority.
Each available priority consumes RAM within the RTOS kernel so this value should not be set any higher than actually required by your application.
Minimal Stack SizeMust be an integer and greater than 0128 The size of the stack used by the idle task. Generally this should not be reduced from the value set in the FreeRTOSConfig.h file provided with the demo application for the port you are using.
Like the stack size parameter to the xTaskCreate() and xTaskCreateStatic() functions, the stack size is specified in words, not bytes. If each item placed on the stack is 32-bits, then a stack size of 100 means 400 bytes (each 32-bit stack item consuming 4 bytes).
Max Task Name LenMust be an integer and greater than 016 The maximum permissible length of the descriptive name given to a task when the task is created. The length is specified in the number of characters including the NULL termination byte.
Use 16-bit TicksDisabledDisabled Time is measured in 'ticks' - which is the number of times the tick interrupt has executed since the RTOS kernel was started. The tick count is held in a variable of type TickType_t.
Defining configUSE_16_BIT_TICKS as 1 causes TickType_t to be defined (typedef'ed) as an unsigned 16bit type. Defining configUSE_16_BIT_TICKS as 0 causes TickType_t to be defined (typedef'ed) as an unsigned 32bit type.

Using a 16-bit type will greatly improve performance on 8- and 16-bit architectures, but limits the maximum specifiable time period to 65535 'ticks'. Therefore, assuming a tick frequency of 250Hz, the maximum time a task can delay or block when a 16bit counter is used is 262 seconds, compared to 17179869 seconds when using a 32-bit counter.
Idle Should Yield
  • Enabled
  • Disabled
Enabled This parameter controls the behaviour of tasks at the idle priority. It only has an effect if:
The preemptive scheduler is being used.
The application creates tasks that run at the idle priority.
If Use Time Slicing is Enabled then tasks that share the same priority will time slice. If none of the tasks get preempted then it might be assumed that each task at a given priority will be allocated an equal amount of processing time - and if the priority is above the idle priority then this is indeed the case.
When tasks share the idle priority the behaviour can be slightly different. If Idle Should Yield is Enabled then the idle task will yield immediately if any other task at the idle priority is ready to run. This ensures the minimum amount of time is spent in the idle task when application tasks are available for scheduling. This behaviour can however have undesirable effects (depending on the needs of your application) as depicted below:


The diagram above shows the execution pattern of four tasks that are all running at the idle priority. Tasks A, B and C are application tasks. Task I is the idle task. A context switch occurs with regular period at times T0, T1, ..., T6. When the idle task yields task A starts to execute - but the idle task has already consumed some of the current time slice. This results in task I and task A effectively sharing the same time slice. The application tasks B and C therefore get more processing time than the application task A.

This situation can be avoided by:

If appropriate, using an idle hook in place of separate tasks at the idle priority.
Creating all application tasks at a priority greater than the idle priority.
Setting Idle Should Yield to Disabled.
Setting Idle Should Yield to Disabled prevents the idle task from yielding processing time until the end of its time slice. This ensure all tasks at the idle priority are allocated an equal amount of processing time (if none of the tasks get pre-empted) - but at the cost of a greater proportion of the total processing time being allocated to the idle task.
Use Task Notifications
  • Enabled
  • Disabled
Enabled Setting Use Task Notifications to Enabled will include direct to task notification functionality and its associated API in the build.
Setting Use Task Notifications to Disabled will exclude direct to task notification functionality and its associated API from the build.

Each task consumes 8 additional bytes of RAM when direct to task notifications are included in the build.
Use Mutexes
  • Enabled
  • Disabled
Disabled Set to Enabled to include mutex functionality in the build, or Disabled to omit mutex functionality from the build. Readers should familiarise themselves with the differences between mutexes and binary semaphores in relation to the FreeRTOS functionality.
Use Recursive Mutexes
  • Enabled
  • Disabled
Disabled Set to Enabled to include recursive mutex functionality in the build, or Disabled to omit recursive mutex functionality from the build.
Use Counting Semaphores
  • Enabled
  • Disabled
Enabled Set to Enabled to include counting semaphore functionality in the build, or Disabled to omit counting semaphore functionality from the build.
Queue Registry SizeMust be an integer and greater than 010 The queue registry has two purposes, both of which are associated with RTOS kernel aware debugging:
It allows a textual name to be associated with a queue for easy queue identification within a debugging GUI.
It contains the information required by a debugger to locate each registered queue and semaphore.
The queue registry has no purpose unless you are using a RTOS kernel aware debugger. Registry Size defines the maximum number of queues and semaphores that can be registered. Only those queues and semaphores that you want to view using a RTOS kernel aware debugger need be registered. See the API reference documentation for vQueueAddToRegistry() and vQueueUnregisterQueue() for more information.
Use Queue Sets
  • Enabled
  • Disabled
Disabled Set to Enabled to include queue set functionality (the ability to block, or pend, on multiple queues and semaphores), or Disabled to omit queue set functionality.
Use Time Slicing
  • Enabled
  • Disabled
Disabled If Use Time Slicing is Enabled, FreeRTOS uses prioritised preemptive scheduling with time slicing. That means the RTOS scheduler will always run the highest priority task that is in the Ready state, and will switch between tasks of equal priority on every RTOS tick interrupt. If Use Time Slicing is Disabled then the RTOS scheduler will still run the highest priority task that is in the Ready state, but will not switch between tasks of equal priority just because a tick interrupt has occurred.
Use Newlib Reentrant
  • Enabled
  • Disabled
Disabled If Use Newlib Reentrant is Enabled then a newlib reent structure will be allocated for each created task.
Note Newlib support has been included by popular demand, but is not used by the FreeRTOS maintainers themselves. FreeRTOS is not responsible for resulting newlib operation. User must be familiar with newlib and must provide system-wide implementations of the necessary stubs. Be warned that (at the time of writing) the current newlib design implements a system-wide malloc() that must be provided with locks.
Enable Backward Compatibility
  • Enabled
  • Disabled
Disabled The FreeRTOS.h header file includes a set of #define macros that map the names of data types used in versions of FreeRTOS prior to version 8.0.0 to the names used in FreeRTOS version 8.0.0. The macros allow application code to update the version of FreeRTOS they are built against from a pre 8.0.0 version to a post 8.0.0 version without modification. Setting Enable Backward Compatibility to Disabled in FreeRTOSConfig.h excludes the macros from the build, and in so doing allowing validation that no pre version 8.0.0 names are being used.
Num Thread Local Storage PointersMust be an integer and greater than 05 Sets the number of indexes in each task's thread local storage array.
Stack Depth TypeManual Entryuint32_t Sets the type used to specify the stack depth in calls to xTaskCreate(), and various other places stack sizes are used (for example, when returning the stack high water mark).
Older versions of FreeRTOS specified stack sizes using variables of type UBaseType_t, but that was found to be too restrictive on 8-bit microcontrollers. Stack Depth Type removes that restriction by enabling application developers to specify the type to use.
Message Buffer Length TypeManual Entrysize_t FreeRTOS Message buffers use variables of type Message Buffer Length Type to store the length of each message. If Message Buffer Length Type is not defined then it will default to size_t. If the messages stored in a message buffer will never be larger than 255 bytes then defining Message Buffer Length Type to uint8_t will save 3 bytes per message on a 32-bit microcontroller. Likewise if the messages stored in a message buffer will never be larger than 65535 bytes then defining Message Buffer Length Type to uint16_t will save 2 bytes per message on a 32-bit microcontroller.
Library Max Syscall Interrupt PriorityMCU Specific OptionsThe highest interrupt priority that can be used by any interrupt service routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values)

Below is explanation for macros that are set based on this value from FreeRTOS website.

In the RA port, configKERNEL_INTERRUPT_PRIORITY is not used and the kernel runs at the lowest priority.

Note in the following discussion that only API functions that end in "FromISR" can be called from within an interrupt service routine.

configMAX_SYSCALL_INTERRUPT_PRIORITY sets the highest interrupt priority from which interrupt safe FreeRTOS API functions can be called.

A full interrupt nesting model is achieved by setting configMAX_SYSCALL_INTERRUPT_PRIORITY above (that is, at a higher priority level) than configKERNEL_INTERRUPT_PRIORITY. This means the FreeRTOS kernel does not completely disable interrupts, even inside critical sections. Further, this is achieved without the disadvantages of a segmented kernel architecture.

Interrupts that do not call API functions can execute at priorities above configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore never be delayed by the RTOS kernel execution.

A special note for Arm Cortex-M users: Please read the page dedicated to interrupt priority settings on Arm Cortex-M devices. As a minimum, remember that Arm Cortex-M cores use numerically low priority numbers to represent HIGH priority interrupts, which can seem counter-intuitive and is easy to forget! If you wish to assign an interrupt a low priority do NOT assign it a priority of 0 (or other low numeric value) as this can result in the interrupt actually having the highest priority in the system - and therefore potentially make your system crash if this priority is above configMAX_SYSCALL_INTERRUPT_PRIORITY.

The lowest priority on a Arm Cortex-M core is in fact 255 - however different Arm Cortex-M vendors implement a different number of priority bits and supply library functions that expect priorities to be specified in different ways. For example, on the RA6M3 the lowest priority you can specify is 15 - and the highest priority you can specify is 0.
AssertManual Entryassert(x) The semantics of the configASSERT() macro are the same as the standard C assert() macro. An assertion is triggered if the parameter passed into configASSERT() is zero.
configASSERT() is called throughout the FreeRTOS source files to check how the application is using FreeRTOS. It is highly recommended to develop FreeRTOS applications with configASSERT() defined.

The example definition (shown at the top of the file and replicated below) calls vAssertCalled(), passing in the file name and line number of the triggering configASSERT() call (__FILE__ and __LINE__ are standard macros provided by most compilers). This is just for demonstration as vAssertCalled() is not a FreeRTOS function, configASSERT() can be defined to take whatever action the application writer deems appropriate.

It is normal to define configASSERT() in such a way that it will prevent the application from executing any further. This if for two reasons; stopping the application at the point of the assertion allows the cause of the assertion to be debugged, and executing past a triggered assertion will probably result in a crash anyway.

Note defining configASSERT() will increase both the application code size and execution time. When the application is stable the additional overhead can be removed by simply commenting out the configASSERT() definition in FreeRTOSConfig.h.

/* Define configASSERT() to call vAssertCalled() if the assertion fails. The assertion
has failed if the value of the parameter passed into configASSERT() equals zero. */
#define configASSERT( ( x ) ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
If running FreeRTOS under the control of a debugger, then configASSERT() can be defined to just disable interrupts and sit in a loop, as demonstrated below. That will have the effect of stopping the code on the line that failed the assert test - pausing the debugger will then immediately take you to the offending line so you can see why it failed.

/* Define configASSERT() to disable interrupts and sit in a loop. */
#define configASSERT( ( x ) ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
Include Application Defined Privileged Functions
  • Enabled
  • Disabled
Disabled Include Application Defined Privileged Functions is only used by FreeRTOS MPU.
If Include Application Defined Privileged Functions is Enabled then the application writer must provide a header file called "application_defined_privileged_functions.h", in which functions the application writer needs to execute in privileged mode can be implemented. Note that, despite having a .h extension, the header file should contain the implementation of the C functions, not just the functions' prototypes.

Functions implemented in "application_defined_privileged_functions.h" must save and restore the processor's privilege state using the prvRaisePrivilege() function and portRESET_PRIVILEGE() macro respectively. For example, if a library provided print function accesses RAM that is outside of the control of the application writer, and therefore cannot be allocated to a memory protected user mode task, then the print function can be encapsulated in a privileged function using the following code:

void MPU_debug_printf( const char *pcMessage )
{
/* State the privilege level of the processor when the function was called. */
BaseType_t xRunningPrivileged = prvRaisePrivilege();

/* Call the library function, which now has access to all RAM. */
debug_printf( pcMessage );

/* Reset the processor privilege level to its original value. */
portRESET_PRIVILEGE( xRunningPrivileged );
}
This technique should only be use during development, and not deployment, as it circumvents the memory protection.
Hooks
Use Idle Hook
  • Enabled
  • Disabled
Enabled Set to Enabled if you wish to use an idle hook, or Disabled to omit an idle hook.
Use Malloc Failed Hook
  • Enabled
  • Disabled
Disabled The kernel uses a call to pvPortMalloc() to allocate memory from the heap each time a task, queue or semaphore is created. The official FreeRTOS download includes four sample memory allocation schemes for this purpose. The schemes are implemented in the heap_1.c, heap_2.c, heap_3.c, heap_4.c and heap_5.c source files respectively. Use Malloc Failed Hook is only relevant when one of these three sample schemes is being used.
The malloc() failed hook function is a hook (or callback) function that, if defined and configured, will be called if pvPortMalloc() ever returns NULL. NULL will be returned only if there is insufficient FreeRTOS heap memory remaining for the requested allocation to succeed.

If Use Malloc Failed Hook is Enabled then the application must define a malloc() failed hook function. If Use Malloc Failed Hook is set to Dosab;ed then the malloc() failed hook function will not be called, even if one is defined. Malloc() failed hook functions must have the name and prototype shown below.

void vApplicationMallocFailedHook( void );
Use Daemon Task Startup Hook
  • Enabled
  • Disabled
Disabled If Use Timers and Use Daemon Task Startup Hook are both Enabled then the application must define a hook function that has the exact name and prototype as shown below. The hook function will be called exactly once when the RTOS daemon task (also known as the timer service task) executes for the first time. Any application initialisation code that needs the RTOS to be running can be placed in the hook function.
void void vApplicationDaemonTaskStartupHook( void );
Use Tick Hook
  • Enabled
  • Disabled
Disabled Set to Enabled if you wish to use an tick hook, or Disabled to omit an tick hook.
Check For Stack Overflow
  • Enabled
  • Disabled
Disabled The stack overflow detection page describes the use of this parameter. This is not recommended for RA MCUs with hardware stack monitor support. RA MCU designs should enable the RA hardware stack monitor instead.
Stats
Use Trace Facility
  • Enabled
  • Disabled
Disabled Set to Enabled if you wish to include additional structure members and functions to assist with execution visualisation and tracing.
Use Stats Formatting Functions
  • Enabled
  • Disabled
Disabled Set Use Trace Facility and Use Stats Formatting Functions to Enabled to include the vTaskList() and vTaskGetRunTimeStats() functions in the build. Setting either to Disabled will omit vTaskList() and vTaskGetRunTimeStates() from the build.
Generate Run Time Stats
  • Enabled
  • Disabled
Disabled The Run Time Stats page describes the use of this parameter.
Memory Allocation
Clear Memory on Free
  • Enabled
  • Disabled
Disabled If set to 1, then blocks of memory allocated using pvPortMalloc() will be cleared when freed using vPortFree()
Support Static Allocation
  • Enabled
  • Disabled
Enabled If Support Static Allocation is Enabled then RTOS objects can be created using RAM provided by the application writer.
If Support Static Allocation is Disabled then RTOS objects can only be created using RAM allocated from the FreeRTOS heap.

If Support Static Allocation is left undefined it will default to 0.

If Support Static Allocation is Enabled then the application writer must also provide two callback functions: vApplicationGetIdleTaskMemory() to provide the memory for use by the RTOS Idle task, and (if Use Timers is Enabled) vApplicationGetTimerTaskMemory() to provide memory for use by the RTOS Daemon/Timer Service task. Examples are provided below.


/* Support Static Allocation is Enabled, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,<br> StackType_t **ppxIdleTaskStackBuffer,<br> uint32_t *pulIdleTaskStackSize )
{
/* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];

/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */
*ppxIdleTaskTCBBuffer =

/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;

/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/

/* Support Static Allocation and Use Timers are both Enabled, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,<br> StackType_t **ppxTimerTaskStackBuffer,<br> uint32_t *pulTimerTaskStackSize )
{
/* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];

/* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */
*ppxTimerTaskTCBBuffer =

/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;

/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}

Examples of the callback functions that must be provided by the application to
supply the RAM used by the Idle and Timer Service tasks if Support Static Allocation
is Enabled.

See the Static Vs Dynamic Memory Allocation page for more information.
Support Dynamic Allocation
  • Enabled
  • Disabled
Disabled If Support Dynamic Allocation is Enabled then RTOS objects can be created using RAM that is automatically allocated from the FreeRTOS heap.
If Support Dynamic Allocation is set to 0 then RTOS objects can only be created using RAM provided by the application writer.

See the Static Vs Dynamic Memory Allocation page for more information.
Total Heap SizeMust be an integer and greater than 01024 The total amount of RAM available in the FreeRTOS heap.
This value will only be used if Support Dynamic Allocation is Enabled and the application makes use of one of the sample memory allocation schemes provided in the FreeRTOS source code download. See the memory configuration section for further details.
Application Allocated Heap
  • Enabled
  • Disabled
Disabled By default the FreeRTOS heap is declared by FreeRTOS and placed in memory by the linker. Setting Application Allocated Heap to Enabled allows the heap to instead be declared by the application writer, which allows the application writer to place the heap wherever they like in memory.
If heap_1.c, heap_2.c or heap_4.c is used, and Application Allocated Heap is Enabled, then the application writer must provide a uint8_t array with the exact name and dimension as shown below. The array will be used as the FreeRTOS heap. How the array is placed at a specific memory location is dependent on the compiler being used - refer to your compiler's documentation.

uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
Timers
Use Timers
  • Enabled
  • Disabled
Enabled Set to Enabled to include software timer functionality, or Disabled to omit software timer functionality. See the FreeRTOS software timers page for a full description.
Timer Task PriorityMust be an integer and greater than 03 Sets the priority of the software timer service/daemon task. See the FreeRTOS software timers page for a full description.
Timer Queue LengthMust be an integer and greater than 010 Sets the length of the software timer command queue. See the FreeRTOS software timers page for a full description.
Timer Task Stack DepthMust be an integer and greater than 0128 Sets the stack depth allocated to the software timer service/daemon task. See the FreeRTOS software timers page for a full description.
Optional Functions
vTaskPrioritySet() Function
  • Enabled
  • Disabled
Enabled Include vTaskPrioritySet() function in build
uxTaskPriorityGet() Function
  • Enabled
  • Disabled
Enabled Include uxTaskPriorityGet() function in build
vTaskDelete() Function
  • Enabled
  • Disabled
Enabled Include vTaskDelete() function in build
vTaskSuspend() Function
  • Enabled
  • Disabled
Enabled Include vTaskSuspend() function in build
xResumeFromISR() Function
  • Enabled
  • Disabled
Enabled Include xResumeFromISR() function in build
vTaskDelayUntil() Function
  • Enabled
  • Disabled
Enabled Include vTaskDelayUntil() function in build
vTaskDelay() Function
  • Enabled
  • Disabled
Enabled Include vTaskDelay() function in build
xTaskGetSchedulerState() Function
  • Enabled
  • Disabled
Enabled Include xTaskGetSchedulerState() function in build
xTaskGetCurrentTaskHandle() Function
  • Enabled
  • Disabled
Enabled Include xTaskGetCurrentTaskHandle() function in build
uxTaskGetStackHighWaterMark() Function
  • Enabled
  • Disabled
Disabled Include uxTaskGetStackHighWaterMark() function in build
xTaskGetIdleTaskHandle() Function
  • Enabled
  • Disabled
Disabled Include xTaskGetIdleTaskHandle() function in build
eTaskGetState() Function
  • Enabled
  • Disabled
Disabled Include eTaskGetState() function in build
xEventGroupSetBitFromISR() Function
  • Enabled
  • Disabled
Enabled Include xEventGroupSetBitFromISR() function in build
xTimerPendFunctionCall() Function
  • Enabled
  • Disabled
Disabled Include xTimerPendFunctionCall() function in build
xTaskAbortDelay() Function
  • Enabled
  • Disabled
Disabled Include xTaskAbortDelay() function in build
xTaskGetHandle() Function
  • Enabled
  • Disabled
Disabled Include xTaskGetHandle() function in build
xTaskResumeFromISR() Function
  • Enabled
  • Disabled
Enabled Include xTaskResumeFromISR() function in build
RA
Hardware Stack Monitor
  • Enabled
  • Disabled
Disabled Include RA stack monitor
Logging
Print String FunctionManual EntryvLoggingPrint(x)
Logging Include Time and Task Name
  • Disabled
  • Enabled
Disabled
Debug Logging NameManual EntryLog Name
Logging Level
  • LOG_NONE
  • LOG_ERROR
  • LOG_WARN
  • LOG_INFO
  • LOG_DEBUG
LOG_NONE Set the logging level

Clock Configuration

The FreeRTOS port uses the SysTick timer as the system clock. The timer rate is configured in the FreeRTOS component under General > Tick Rate Hz.

Pin Configuration

This module does not use I/O pins.

Usage Notes

Hardware Stack Monitor (PSPLIM)

A UsageFault is generated if PSP goes out of the memory area for the stack allocated for the current task. If UsageFault is not enabled, it is escalated to HardFault.

Hardware Stack Monitor (SPMON)

The hardware stack monitor generates an NMI if the PSP goes out of the memory area for the stack allocated for the current task. A callback can be registered using R_BSP_GroupIrqWrite() to be called whenever a stack overflow or underflow of the PSP for a particular thread is detected.

Stack Monitor Underflow Detection

By default the hardware stack monitor only checks for overflow of the process stack. To check for underflow define configRECORD_STACK_HIGH_ADDRESS as 1 on the command line.

Low Power Modes

When FreeRTOS is configured to use tickless idle, the idle task executes WFI() when no task is ready to run. If the MCU is configured to enter software standby mode or deep software standby mode when the idle task executes WFI(), the RA FreeRTOS port changes the low power mode to sleep mode so the idle task can wake from SysTick. The low power mode settings are restored when the MCU wakes from sleep mode.

TrustZone Integration

When using an RTOS in a TrustZone project, Arm recommends keeping the RTOS in the non-secure project. Tasks may call non-secure callable functions if the task has allocated a secure context (using portALLOCATE_SECURE_CONTEXT).

The secure context can be freed by deleting the thread or using the portCLEAN_UP_TCB(pxTCB) macro.

Examples

Stack Monitor Example

This is an example of using the stack monitor in an application.

#if BSP_FEATURE_BSP_HAS_SP_MON
void stack_monitor_callback (bsp_grp_irq_t irq)
{
if (1U == R_MPU_SPMON->SP[0].CTL_b.ERROR)
{
/* Handle main stack monitor error here. */
}
if (1U == R_MPU_SPMON->SP[1].CTL_b.ERROR)
{
/* Handle process stack monitor error here. */
}
}
void rm_freertos_port_stack_monitor_example (void)
{
/* Register a callback to be called when the stack goes outside the allocated stack area. */
R_BSP_GroupIrqWrite(BSP_GRP_IRQ_MPU_STACK, stack_monitor_callback);
}
#else
/* Allocate stack space to return from UsageFault. */
uint32_t g_stack_overflow_exception_stack[8] BSP_ALIGN_VARIABLE(BSP_STACK_ALIGNMENT) BSP_PLACE_IN_SECTION(
BSP_SECTION_STACK);
/* MCUs that do not have an SPMON stack monitor use PSPLIM to detect stack overflows. When a stack overflow error
* occurs, the UsageFault_Handler fires if it has been enabled. */
void UsageFault_Handler (void)
{
register uint32_t cfsr = SCB->CFSR;
if (cfsr & SCB_CFSR_STKOF_Msk)
{
/* Update PSP and PSPLIM to point to an exception stack frame allocated for stack overflows. */
register uint32_t * p_exception_stack_frame = (uint32_t *) (&g_stack_overflow_exception_stack);
__set_PSP((uint32_t) p_exception_stack_frame);
__set_PSPLIM((uint32_t) p_exception_stack_frame);
/* Clear XPSR, only set T-bit. */
p_exception_stack_frame[7] = 1U << 24;
/* Set PC to stack overflow error while loop. When execution returns from the UsageFault, it will go to the
* stack_overflow_error_occurred function. It cannot return to the location where the fault occurred because
* the MCU does not save the exception stack frame to the stack when a stack overflow error occurs. */
p_exception_stack_frame[6] = (uint32_t) stack_overflow_error_occurred;
}
/* Clear flags. */
SCB->CFSR = cfsr;
}
/* This function is called from UsageFault_Handler after a stack overflow occurs. */
void stack_overflow_error_occurred (void)
{
/* When recovering from a stack overflow, move the task to a while(1) loop. */
while (1)
{
/* Do nothing. */
}
}
void rm_freertos_port_stack_monitor_example (void)
{
/* Enable usage fault. */
SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk;
}
#endif

TrustZone Example

This is an example of calling portALLOCATE_SECURE_CONTEXT before calling any non-secure callable functions in a task.

void rm_freertos_port_trustzone_task_example (void)
{
/* When FreeRTOS is used in a non-secure TrustZone application, portALLOCATE_SECURE_CONTEXT must be called prior
* to calling any non-secure callable function in a task. The parameter is unused in the FSP implementation. */
portALLOCATE_SECURE_CONTEXT(0);
rm_freertos_port_nsc_function();
}