cancel
Showing results for 
Search instead for 
Did you mean: 

How does the ThreadX Mutex work on STM32 Part2

B.Montanari
ST Employee

How does the ThreadX Mutex work on STM32?

Welcome to the second part of the article covering how to use the Mutex in the ThreadX using STM32 (Part 1 available here). This will cover the code editing and debugging.

1. Code Editing and debugging

Using the previously code generated, open Core\Src \app_threadx.c – Here we’ll create the 2 threads using the command tx_thread_create and the mutex, by using tx_mutex_create.
Both threads are identical, with only the printf message being different. The 2 threads are sleeping for 2 seconds and then will use the tx_mutex_get to suspend the thread until the mutex is available, the thread that gets the mutex will print and use the tx_mutex_put to release the mutex, allowing the other thread to advance, this will happen in an endless loop. You can copy and paste the code below, but please notice the USER CODE BEGIN number/text, to properly place the code snippet:

/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
/* USER CODE BEGIN PD */
#define THREAD_STACK_SIZE        512
/* USER CODE END PD */
/* USER CODE BEGIN PV */
uint8_t thread_stack1[THREAD_STACK_SIZE];
uint8_t thread_stack2[THREAD_STACK_SIZE];
TX_THREAD thread_ptr1;
TX_THREAD thread_ptr2;
TX_MUTEX mutex_0;
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
VOID Thread1 (ULONG initial_input);
VOID Thread2 (ULONG initial_input);
/* USER CODE END PFP */
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 */
       tx_mutex_create(&mutex_0, "mutex 0", 1);
       tx_thread_create(&thread_ptr1,"Thread1",Thread1, 0, thread_stack1,THREAD_STACK_SIZE,15,15,1,TX_AUTO_START);
       tx_thread_create(&thread_ptr2,"Thread2",Thread2, 0, thread_stack2,THREAD_STACK_SIZE,15,15,1,TX_AUTO_START);
       /* USER CODE END App_ThreadX_Init */
       return ret;
}
/* USER CODE BEGIN 1 */
VOID Thread1 (ULONG initial_input){
       /* Infinite loop */
       for(;;)      {
             /* Sleep for 2seconds */
             tx_thread_sleep(200);
             tx_mutex_get(&mutex_0,TX_NO_WAIT);
             printf("Thread1 print\r\n");
             /* Release the mutex.  */
             tx_mutex_put(&mutex_0);
       }
}
VOID Thread2 (ULONG initial_input){
       for(;;)      {
             /* Sleep for 2seconds */
             tx_thread_sleep(200);
             tx_mutex_get(&mutex_0,TX_NO_WAIT);
             printf("Thread2 print\r\n");
             /* Release the mutex.  */
             tx_mutex_put(&mutex_0);
       }
}
/* USER CODE END 1 */

Open Core\Src \main.c – you can copy and paste the code below:

/* USER CODE BEGIN 0 */
void __io_putchar(char ch) {
    // Code to write character 'ch' on the UART
    HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 10);
}
/* USER CODE END 0 */

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:

242.png

In Edit Configuration window, click Debug:

243.png

Once in the Debug perspective, click in the resume button to enjoy your ThreadX application with mutex working. You can also use the Window/Show View/ThreadX/ThreadX Thread List and do it again for the ThreadX Mutex to enhance the overall debugging options (the thread list will be automatically loaded once the application runs for a bit and is paused):

244.png


Now, the last step is to enable the console inside the STM32CubeIDE to see the print messages. Locate the Console tab and click Command Shell Console:

245.png

In the pop-up window, change the Connection Type to Serial Port and click on New… to add the VCOM related to your STLINK:

246.png

You can give the port a name, so it is easier for later usage as well, in this case, it will be labelled as NUCLEO_H723ZI:

247.png

By clicking finish, the message on the console will indicate it is now connected. By resuming the application (pressing F8), the printf messages will be displayed. Adding a breakpoint allows the Mutex and ThreadX information to be updated:

248.png

2. Useful links:

3. Conclusion:

Adding mutex to a ThreadX application consists of:
    • Adding the ThreadX component in STM32CubeMX/STM32CubeIDE
    • Adapt ThreadX configuration in STM32CubeMX/ STM32CubeIDE
    • Generate the code from STM32CubeMX/ STM32CubeIDE
      1. This will update the project structure with all needed files
    • Use ThreadX API to create ThreadX components thread and mutex
    • Have fun :)
Comments
Bob S
Principal

The Thread1() and Thread2() code is not correct. They call tx_mutex_get() with TX_NO_WAIT. This will return immediately even if the mutex was not available. If you really want to use TX_NO_WAIT, then you must check the tx_mutex_get() return value for TX_SUCCESS (got the mutex) or TX_NOT_AVAILABLE (did not get the mutex).

Better (and in this example, a more realistic) usage would be to use TX_WAIT_FOREVER.

Version history
Last update:
‎2021-12-14 12:32 AM
Updated by: