This application provides an example of Azure RTOS ThreadX stack usage, it shows how to develop an application using the FreeRTOS adaptation layer for ThreadX.
The main entry function tx_application_define() is called by ThreadX during kernel start, at this stage, the application creates 1 thread : 'LED_Thread' (Priority : 5).
The 'LED_Thread' toggles the 'LED_GREEN' every 500ms.
'LED_GREEN' toggles every 500ms.
'LED_RED' toggles every 1 second if any error occurs.
None
None
- Some code parts can be executed in the CCMRAM (64 KB) which decreases critical task execution time, compared to code execution from Flash memory. This feature can be activated using '#pragma location = ".CMRAM"' to be placed above function declaration, or using the toolchain GUI (file options) to execute a whole source file in the CCMRAM.
-
ThreadX uses the Systick as time base, thus it is mandatory that the HAL uses a separate time base through the TIM IPs.
-
ThreadX is configured with 100 ticks/sec by default, this should be taken into account when using delays or timeouts at application. It is always possible to reconfigure it in the "tx_user.h", the "TX_TIMER_TICKS_PER_SECOND" define,but this should be reflected in "tx_initialize_low_level.s" file too.
-
ThreadX is disabling all interrupts during kernel start-up to avoid any unexpected behavior, therefore all system related calls (HAL, BSP) should be done either at the beginning of the application or inside the thread entry functions.
-
ThreadX offers the "tx_application_define()" function, that is automatically called by the tx_kernel_enter() API. It is highly recommended to use it to create all applications ThreadX related resources (threads, semaphores, memory pools...) but it should not in any way contain a system API call (HAL or BSP).
-
Using dynamic memory allocation requires to apply some changes to the linker file. ThreadX needs to pass a pointer to the first free memory location in RAM to the tx_application_define() function, using the "first_unused_memory" argument. This require changes in the linker files to expose this memory location.
- For EWARM add the following section into the .icf file:
place in RAM_region { last section FREE_MEM };
- For MDK-ARM:
either define the RW_IRAM1 region in the ".sct" file or modify the line below in "tx_low_level_initilize.s to match the memory region being used LDR r1, =|Image$$RW_IRAM1$$ZI$$Limit|
- For STM32CubeIDE add the following section into the .ld file:
._threadx_heap : { . = ALIGN(8); __RAM_segment_used_end__ = .; . = . + 64K; . = ALIGN(8); } >RAM_D1 AT> RAM_D1
The simplest way to provide memory for ThreadX is to define a new section, see ._threadx_heap above. In the example above the ThreadX heap size is set to 64KBytes. The ._threadx_heap must be located between the .bss and the ._user_heap_stack sections in the linker script. Caution: Make sure that ThreadX does not need more than the provided heap memory (64KBytes in this example). Read more in STM32CubeIDE User Guide, chapter: "Linker script".
- The "tx_initialize_low_level.s" should be also modified to enable the "USE_DYNAMIC_MEMORY_ALLOCATION" flag.
RTOS, ThreadX, Threading, RTOS compatibility layers
- This application runs on STM32F429xx devices
- This application has been tested with STMicroelectronics STM32F429ZI Nucleo boards Revision MB1137 B-01 and can be easily tailored to any other supported device and development board.
In order to make the program work, you must do the following:
- Open your preferred toolchain
- Rebuild all files and load your image into target memory
- Run the application