2023-07-10 08:34 AM - edited 2023-12-07 05:34 AM
In case you are new to Microsoft’s Azure RTOS or you need a review of basic RTOS concepts/synchronization primitives, you can review: Introduction to ThreadX [4].
Minimum hardware requirements:
Optional hardware:
At minimum, this demo requires a Nucleo-U575 + a micro-USB cable for connections between the evaluation board and the PC. If you have the standalone STLINK-V3PWR, you can skip the micro-USB cable, but the STLINK V3PWR requires a USB Type-C® connection (see UM3097).
Minimum software requirements:
Optional software:
Main application thread:
The tx_app_semaphore is released each time a user presses the user button. This is done in the EXTI ISR callback for the blue user button.
Expected success behavior:
Expected error behavior:
Open STM32CubeMX and click the “ACCESS TO BOARD SELECTOR.” Select Nucleo-U575 board as shown in figure 1. You encounter a popup asking whether to initialize the peripherals to their default state; hit yes. Since the STM32U5 is TrustZone® capable MCU, you encounter a second popup asking whether you would like TrustZone® activated; select “without TrustZone® activated.” We are not working with the TrustZone® security feature active for this example.
You can have all the pinouts unconfigured by following figure 2 (Pinout -> Clear Pinouts).
Next, navigate to THREADX RTOS middleware like shown in figure 3 (under the “Middleware and Software Packs” tab).
Checkmark the core services (to activate the ThreadX) and low power support as shown in figure 4.
Like figure 5, check “generate app init code” to generate the application ThreadX initialization code inside the “App_ThreadX_Init(VOID *memory_ptr)” function def. Inside this function, you allocate static memory for the main thread (3*1024), create the main thread itself, and finally create the binary semaphore (initialized to 0).
In addition, we enable the low power support to create the required “macros” for handling the low power setup of the MCU hardware when entering and exiting low power mode. This means that the functions are simply declared without any definitions so it would be up to developers to define the hardware config when enter/exit low power mode.
We utilize the blue user button of the Nucleo evaluation board for waking up the MCU from low power mode. Since the blue user button is mapped to PC13 (see schematic [ ]), we must configure GPIO pin PC13 as an EXTI pin. The EXTI peripheral helps detect the button being pressed from the GPIO line and generate an interrupt/wakeup-events.
Enable the associated interrupt in the GPIO NVIC for PC13 (figure 7).
Next, we configure two additional GPIO pins as output to two different LEDs to help us track our program status. Pin PC7 is configured as the output and it also physically mapped to the green LED1 on the Nucleo board as shown in [1].
Pin PG2 is physically mapped to the red LED3 on the Nucleo board as shown in schematic [1].
Figure 10 below is just for your reference, and nothing needs to be changed.
Figure 10: Overview of all the GPIO pins we configured. “System Core” -> “GPIO”.
Looking at figure 12, to save additional power, disable all the peripherals that you will not use. For instance, we leave SRAM2 page 1 (0x20030000) with full retention during stop mode because that is where some of our data code is stored. We do not need other RAM pages, so we disable retention (content is lost during stop mode) for those; see figure 11. To access the “memory details” like shown in figure 11, click on “build analyzer” in the bottom right side of the STM32CubeIDE window (if not shown, click “window” -> “show view” -> “build analyzer”).
In figure 12, similarly, I-cache is kept with full page retention because our code instruction utilizes it for performance reasons. Refer to the STM32U575 reference manual [2] “PWR power management” section for full details about the power modes and the low power features. Specifically, refer to stop 2 mode power saving features.
Enable I-cache as shown in figure 13 below for performance reasons.
Select one of the timers for HAL time base since ThreadX RTOS already uses the Systick timer for its services. We selected timer 6 because it is one of the basic timers that is good enough for our purpose.
Enable EXTI interrupt used for generating interrupt for waking up MCU after the blue user button is pushed.
In figure 16 below, we modify the visibility of the GPIO initialization function because we use it inside the source file for our RTOS application.
Figure 16: Uncheck visibility (static) so this function is not declared as static to allow for global function visibility.
Finally, we are ready to generate our source files from the STM32CubeMX .ioc file we configured. Before doing that, we set all unused pins to analog to save power consumption.
Figure 17: Configure unused pins as analog to save more power.
As a final step, save your project and then generate your code as shown. You can define your project location/workspace anywhere you like but make sure that the project path is not too long or else you will encounter issues with the IDE. Under “Toolchain/IDE,” select STM32CubeIDE.
Figure 18: Choose “STM32CubeIDE” for Toolchain/ IDE & then click “GENERATE CODE”.