RA Flexible Software Package Documentation  Release v5.5.0

 
Azure RTOS ThreadX Port (rm_threadx_port)

ThreadX port for RA MCUs.

Overview

Note
The ThreadX Port does not provide any interfaces to the user. Consult the ThreadX documentation at https://docs.microsoft.com/en-us/azure/rtos/threadx/ for further information.

Features

The RA ThreadX port supports the following features:

Configuration

Build Time Configurations for ThreadX

The following build time configurations are defined in fsp_cfg/azure/tx/tx_user.h:

ConfigurationOptionsDefaultDescription
General
Custom tx_user.hManual EntryAdd a path to your custom tx_user.h file. It can be used to override some or all of the configurations defined here, and to define additional configurations.
Error Checking
  • Enabled
  • Disabled
Enabled The ThreadX basic API error checking can be bypassed by compiling with the symbol TX_DISABLE_ERROR_CHECKING defined.
Max PrioritiesValue must be a multiple of 32 and in range 32 to 1024 or empty32 Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32.
Minimum StackValue must be greater than 0 or empty200 Define the minimum stack for a ThreadX thread on this processor. If the size supplied during thread creation is less than this value, the thread create call will return an error.
Stack Filling
  • Enabled
  • Disabled
Enabled Determine is stack filling is enabled. By default, ThreadX stack filling is enabled, which places an 0xEF pattern in each byte of each thread's stack. This is used by debuggers with ThreadX-awareness and by the ThreadX run-time stack checking feature.
Preemption Threshold
  • Enabled
  • Disabled
Disabled Determine if preemption-threshold should be disabled. By default, preemption-threshold is disabled. If the application does not use preemption-threshold, it may be disabled to reduce code size and improve performance.
Notify Callbacks
  • Enabled
  • Disabled
Disabled Determine if the notify callback option should be disabled. By default, notify callbacks are disabled. If the application does not use notify callbacks, they may be disabled to reduce code size and improve performance.
Inline Thread Resume Suspend
  • Enabled
  • Disabled
Disabled Determine if the tx_thread_resume and tx_thread_suspend services should have their internal code in-line. This results in a larger image, but improves the performance of the thread resume and suspend services.
Not Interruptable
  • Enabled
  • Disabled
Disabled Determine if the internal ThreadX code is non-interruptable. This results in smaller code size and less processing overhead, but increases the interrupt lockout time.
IAR Library Support
  • Enabled
  • Disabled
Disabled Enable IAR library support (IAR compiler only). When IAR Library Support is Enabled, enable the linker option --threaded_lib. In the IAR IDE, this can be enabled in Project > Options > General Options > Library Configuration > Enable thread support in library.
BSD Support
  • Enabled
  • Disabled
Disabled Defines TX_THREAD_EXTENSION_1 to bsd_err_no in order to support NXD BSD.
FileX Pointer
  • Enabled
  • Disabled
Enabled Determine if there is a FileX pointer in the thread control block. By default, the pointer is there for legacy/backwards compatibility. The pointer must also be there for applications using FileX. Disable this to save space in the thread control block.
Timer
Timer Ticks Per SecondValue must be greater than 0 or empty100 Define the number of times the system timer runs per second. Default is 100 ticks per second, which results in a tick every 10ms.
Timer Thread Stack SizeValue must be greater than 0 or empty1024 Define the system timer thread's default stack size and priority. These are only applicable if TX_TIMER_PROCESS_IN_ISR is disabled.
Timer Thread PriorityValue must be greater than 0 or empty0 Define the system timer thread's default stack size and priority. These are only applicable if TX_TIMER_PROCESS_IN_ISR is disabled.
Timer Process In ISR
  • Enabled
  • Disabled
Enabled Determine if timer expirations (application timers, timeouts, and tx_thread_sleep calls should be processed within the a system timer thread or directly in the timer ISR. When disabled, the timer thread is used. When enabled, timer expiration processing is done directly from the timer ISR, thereby eliminating the timer thread control block, stack, and context switching to activate it.
Reactivate Inline
  • Enabled
  • Disabled
Disabled Determine if in-line timer reactivation should be used within the timer expiration processing. By default, this is disabled and a function call is used. When enabled, reactivating is performed in-line resulting in faster timer processing but slightly larger code size.
Timer
  • Enabled
  • Disabled
Enabled Determine if no timer processing is required. This option will help eliminate the timer processing when not needed.
Trace
Event Trace
  • Enabled
  • Disabled
Disabled Determine if the trace event logging code should be enabled. This causes slight increases in code size and overhead, but provides the ability to generate system trace information which is available for viewing in TraceX.
Trace Buffer NameName must be a valid C symbolg_tx_trace_buffer Name of trace buffer symbol, only used if Event Trace is enabled.
Memory section for Trace BufferManual Entry.bss Specify the memory section where the Trace Buffer will be allocated, only used if Event Trace is enabled. To view TraceX data, export this buffer as raw binary data to a file (.trx extension recommended) and open it with Azure RTOS TraceX.
Trace Buffer SizeValue must be greater than 065536 Trace buffer size in bytes, only used if Event Trace is enabled
Trace Buffer Number of RegistriesValue must be greater than 030 Number of registries available to TraceX, only used if Event Trace is enabled
Performance
Block Pool Performance Info
  • Enabled
  • Disabled
Disabled When enabled, ThreadX gathers block pool performance information.
Byte Pool Performance Info
  • Enabled
  • Disabled
Disabled When enabled, ThreadX gathers byte pool performance information.
Event Flags Performance Info
  • Enabled
  • Disabled
Disabled When enabled, ThreadX gathers event flags performance information.
Mutex Performance Info
  • Enabled
  • Disabled
Disabled When enabled, ThreadX gathers mutex performance information.
Queue Performance Info
  • Enabled
  • Disabled
Disabled When enabled, ThreadX gathers queue performance information.
Semaphore Performance Info
  • Enabled
  • Disabled
Disabled When enabled, ThreadX gathers semaphore performance information.
Thread Performance Info
  • Enabled
  • Disabled
Disabled When enabled, ThreadX gathers thread performance information.
Timer Performance Info
  • Enabled
  • Disabled
Disabled When enabled, ThreadX gathers timer performance information.
RA
Hardware Thread Stack MonitoringMCU Specific OptionsUse RA Hardware Stack Monitors to monitor thread stacks for overflow. Not available on MCUs that support PSPLIM.
Interrupts
SysTick Interrupt PriorityMCU Specific OptionsSelect the Systick interrupt priority.
Maximum Interrupt PriorityMCU Specific OptionsThe maximum priority (lowest numerical value) an interrupt can have and use scheduler services. Interrupts with higher priority can interrupt most scheduler critical sections. Setting this to Priority 0 (highest) disables this feature. This feature is not available on MCUs that do not have the BASEPRI register.

Clock Configuration

The ThreadX port uses the SysTick timer as the system clock. The timer rate is configured in the ThreadX component under General > Timer Ticks Per Second.

Pin Configuration

This module does not use I/O pins.

Usage Notes

Interrupt Priorities

When no threads are ready to run, the ThreadX port spins in the PendSV_Handler, which is fixed at the lowest interrupt priority. The MCU does not service any other interrupts of the lowest priority while no threads are ready to run.

To get around this limitation, the application can create an idle thread that is always ready to run. If the idle thread enters a lower power mode, make sure all interrupts that are required to resume the scheduler can wake the MCU in the configured power mode. If the application expects to wake after a certain number of ticks, the idle thread should not enter standby mode because the SysTick cannot wake the MCU from standby mode. See Low Power Modes (r_lpm) for more information regarding low power modes.

Warning
Do not attempt to wake a thread from an interrupt with the lowest available interrupt priority unless the application has created an idle thread.

Hardware Stack Monitor

The hardware stack monitor generates an NMI if the PSP goes out of the memory area for the stack allocated for the current thread. 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.

Low Power Modes

The idle processing executes WFI() when no thread is ready to run. If the MCU is configured to enter software standby mode or deep software standby mode when the idle processing executes WFI(), the RA ThreadX port changes the low power mode to sleep mode so the idle processing 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 thread has allocated a secure context (using tx_thread_secure_stack_allocate).

The secure context can be freed by deleting the thread or calling tx_thread_secure_stack_free.

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);
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_threadx_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 thread to a while(1) loop. */
while (1)
{
/* Do nothing. */
}
}
void rm_threadx_port_stack_monitor_example (void)
{
/* Enable usage fault. */
SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk;
}
#endif

TrustZone Example

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

extern TX_THREAD * _tx_thread_current_ptr;
void rm_threadx_port_trustzone_thread_example (void)
{
/* When ThreadX is used in a non-secure TrustZone application, tx_thread_secure_stack_allocate must be called prior
* to calling any non-secure callable function in a thread. The first parameter is a pointer to the thread control block.
* This function can be called when the thread is created or in the thread before an non-secure callable function is
* called. The second parameter is unused in the FSP implementation. */
UINT status = tx_thread_secure_stack_allocate(_tx_thread_current_ptr, 0);
assert(TX_SUCCESS == status);
rm_threadx_port_nsc_function();
}