How to create a Thread using AzureRTOS and STM32CubeIDE
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Email to a Friend
- Printer Friendly Page
- Report Inappropriate Content
on
‎2021-09-16
8:20 AM
- edited on
‎2025-03-17
4:53 AM
by
Laurids_PETERSE
Using the software package available in the STM32Cube ecosystem is straight forward, all steps and a demo code are provided in this article.
- Goal: The purpose of this article is to give you a first overview of how the AZURE-RTOS ThreadX is supported in the STM32Cube ecosystem
This article will show you how to start a project from scratch, with the goal of getting an LED to blink in a few clicks, while using a simple thread to do it.
Demo block diagram:
- STM32CubeIDE – step by step demo:
- Launch STM32CubeIDE (version used 1.7.0)
- Select your preferred workspace, click on Launch
- In the information Center, select to Start New STM32 Project
- For this demo in particular, we’ll use the NUCLEO-H723ZG as the starting point:
- Give your project a name, just remember to avoid space and special characters – if you are missing any libraries, the STM32CubeIDE will automatically start the download now
Then second popup to ask to open device configuration perspective, click yes again:
- Now you should have a view of the MCU with some of its peripherals configured, and on the left side you’ll have the initial code, yet without the ThreadX added
- Browse and locate the AzureRTOS pack in the component selection window:
- Open the RTOS ThreadX and check the Core box and click OK
- This will add the Software Pack in the lower part of the Categories:
- Now, by clicking on it, you can add the RTOS ThreadX box, this will show the configuration options for the AzureRTOS application
- As this demo is just meant to blink an LED, the default settings are all set, but we do need to do one other modification. By default, the HAL driver will use the Systick as its primary time base, but this timer should be left to the AzureRTOS only.
- One final modification, to prevent generating too much unused code, we can decide to not create the functions for USB and Ethernet, as they were natively added when we created the design based on the board, this can be done by removing the Generate Code for them:
- All set, we can press Alt+K to generate the code and Ctrl+S to save it:
This is a detail on the code structure:
- The last part is to create the first thread:
- Open Core\Src \app_threadx.c and start adding the code at around line 37, use the comments to find the proper place for the following code:
- After the stack is allocated, we can create the thread inside the function App_ThreadX_Init:
- Create the thread’s main function
And finally our thread:
It might not have been clear up until this point, but the default time base is 10ms, so by having the tx_thread_sleep(20) will actually wait for 200ms
- From this point, press Ctrl+B to build and you should see 0 errors and 0 warnings.
- Connect the board to the computer and enter in debug mode by first clicking in the project name, then menu Run/Debug As/STM32:
- Once in the Debug perspective, hit play to enjoy your blinking LED with ThreadX. You can also use the Window/Show View/ThreadX/ThreadX Thread List
- Useful links:
- STM32CubeIDE: https://www.st.com/en/development-tools/stm32cubeide.html
- NUCLEO-H723ZG: https://www.st.com/en/evaluation-tools/nucleo-h723zg.html
- ThreadX user guide https://docs.microsoft.com/en-us/azure/rtos/threadx/about-this-guide
- ThreadX api description https://docs.microsoft.com/en-us/azure/rtos/threadx/chapter4
- Github: https://github.com/STMicroelectronics/x-cube-azrtos-h7
- Wiki: https://wiki.st.com/stm32mcu/wiki/STM32CoreMW_overview
- Conclusion:
-
- Adding the ThreadX component in STM32CubeMX/STM32CubeIDE
- Adapt ThreadX configuration in STM32CubeMX/ STM32CubeIDE
- Generate the code from STM32CubeMX/ STM32CubeIDE
- This will update the project structure with all needed files
- Use ThreadX API to create ThreadX components thread, mutex, etc
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Email to a Friend
- Report Inappropriate Content
Is it safe to allocate the stack like this? I see in the examples it's usually allocated with tx_byte_allocate
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Email to a Friend
- Report Inappropriate Content
Hi @OHaza.1​
Thank you for your question, @B.Montanari​ I am sure you can provide some insights.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Email to a Friend
- Report Inappropriate Content
Hi @OHaza.1​ ,
Yes, it is safe to allocate the stack as shown in this example. When calling the tx_thread_create(), among its passing arguments, it expects to receive the starting address of the stack's memory area and the number bytes in the stack memory area. The thread's stack area must be large enough to handle its worst-case function call nesting and local variable usage. The way it is displayed in this article, those arguments are used thru a global vector, so both conditions are properly met and I think it is easier overall to use and edit as needed (but this is just my personal preference). Of course, it is also fine to do it by calling the tx_byte_allocate and then tx_thread_create using the pointer for the stack. The code generated by the STM32CubeIDE will create a pool using the settings showed at step10 - this is done inside the app_azure_rtos.c file in the tx_application_define() . Inside it or in the App_ThreadX_Init() you can add your tx_byte_allocate() call to make use of it.
In a nutshell, these would be the code pieces:
#define DEMO_STACK_SIZE 512
UINT App_ThreadX_Init(VOID *memory_ptr){
UINT ret = TX_SUCCESS;
TX_BYTE_POOL *byte_pool = (TX_BYTE_POOL*)memory_ptr;
/* USER CODE BEGIN App_ThreadX_MEM_POOL */
(void)byte_pool;
/* USER CODE END App_ThreadX_MEM_POOL */
/* USER CODE BEGIN App_ThreadX_Init */
CHAR *pointer;
/* Allocate the stack for thread 0. */
tx_byte_allocate(byte_pool, &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create the main thread. */
tx_thread_create(&thread_ptr, "my_thread", my_thread, 0,pointer, DEMO_STACK_SIZE,15, 15, 1, TX_AUTO_START);
}
let me know if you have any further questions
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Email to a Friend
- Report Inappropriate Content
Ok, thanks for the detailed explanation. Yes it does seem a little cleaner if more involved memory management is not required/desired.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Email to a Friend
- Report Inappropriate Content
I like this post, thanks.
I'm trying to figure out the purpose of these lines in the _Init functions. What does (void)byte_pool; do ?
/* USER CODE BEGIN MX_FileX_MEM_POOL */
(void)byte_pool;
/* USER CODE END MX_FileX_MEM_POOL */
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Email to a Friend
- Report Inappropriate Content
Hello @B.Montanari ,
Thank you for following my tutorial and for your kind words. I'm glad you found it well explained.
However, I am encountering an issue when powering my board. Everything works fine when I upload my program. The 4 threads execute correctly. But if I remove the power and then turn it back on, the threads no longer start. I don't understand why this happens. Could you please help me?
Thank you.