{"id":2476,"date":"2016-12-19T21:53:56","date_gmt":"2016-12-20T05:53:56","guid":{"rendered":"http:\/\/visualgdb.com\/w\/?p=2476"},"modified":"2016-12-19T21:53:56","modified_gmt":"2016-12-20T05:53:56","slug":"using-freertos-mutexes-to-synchronize-threads","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/freertos\/mutexes\/","title":{"rendered":"Using FreeRTOS Mutexes to Synchronize Threads"},"content":{"rendered":"<p>This tutorial shows how to use FreeRTOS mutexes to avoid race conditions between different threads. We will show how preemption could affect the order in which the code executes and even how to modify the FreeRTOS kernel to make thread scheduling more uniform.<\/p>\n<p>Before you begin, install VisualGDB 5.2 or later.<\/p>\n<ol>\n<li>Start Visual Studio and open the Embedded Project Wizard:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/01-newprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2490\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/01-newprj.png\" alt=\"01-newprj\" width=\"833\" height=\"551\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/01-newprj.png 833w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/01-newprj-300x198.png 300w\" sizes=\"(max-width: 833px) 100vw, 833px\" \/><\/a><\/li>\n<li>Select &#8220;Create a new project -&gt; Embedded Binary&#8221;:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/02-msbuild.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2489\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/02-msbuild.png\" alt=\"02-msbuild\" width=\"738\" height=\"565\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/02-msbuild.png 738w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/02-msbuild-300x230.png 300w\" sizes=\"(max-width: 738px) 100vw, 738px\" \/><\/a><\/li>\n<li>Select the ARM toolchain and your device. In this tutorial we will use the UART interface to demonstrate race conditions, so pick a board that has a UART interface and select a device matching your board. In this tutorial we will use the STM32F411-Nucleo board that uses the UART interface from the on-board ST-Link 2.1:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/03-device1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2488\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/03-device1.png\" alt=\"03-device\" width=\"738\" height=\"565\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/03-device1.png 738w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/03-device1-300x230.png 300w\" sizes=\"(max-width: 738px) 100vw, 738px\" \/><\/a><\/li>\n<li>On the Sample Selection page choose LEDBlink (FreeRTOS):<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/04-rtos.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2487\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/04-rtos.png\" alt=\"04-rtos\" width=\"738\" height=\"565\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/04-rtos.png 738w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/04-rtos-300x230.png 300w\" sizes=\"(max-width: 738px) 100vw, 738px\" \/><\/a><\/li>\n<li>Finally pick debug settings that match your board and press &#8220;Finish&#8221; to generate a sample project. We recommend using OpenOCD for debugging most of the boards:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/05-nucleo.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2486\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/05-nucleo.png\" alt=\"05-nucleo\" width=\"738\" height=\"565\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/05-nucleo.png 738w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/05-nucleo-300x230.png 300w\" sizes=\"(max-width: 738px) 100vw, 738px\" \/><\/a><\/li>\n<li>The default FreeRTOS sample consists of 2 threads each one controlling one LED. We will change those threads to print &#8220;Hello&#8221; messages in English and French instead and show how preemption will mix the output from the 2 threads. Rename the first thread to EnglishThread and the second one to FrenchThread:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/06-rename.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2485\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/06-rename.png\" alt=\"06-rename\" width=\"977\" height=\"646\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/06-rename.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/06-rename-300x198.png 300w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a>VisualGDB will update the references automatically.<\/li>\n<li>Replace the thread function contents with the following code:\n<pre class=\"\">static void EnglishThread(void const *argument)\r\n{\r\n\u00a0\u00a0\u00a0 for (int i = 0;; i++)\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 UARTPrintf(\"Hello %d\\r\\n\", i);\r\n\u00a0\u00a0\u00a0 }\r\n}\r\n\r\nstatic void FrenchThread(void const *argument)\r\n{\r\n\u00a0\u00a0\u00a0 for (int i = 0;; i++)\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 UARTPrintf(\"Bonjour %d\\r\\n\", i);\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<p>The English thread will print messages like &#8220;Hello 1&#8221;, &#8220;Hello 2&#8221; and so on and the French one will say Bonjour instead of Hello.<\/li>\n<li>Replace the LED1 and LED2 thread names with ENGLISH and FRENCH:\n<pre class=\"\">\u00a0\u00a0\u00a0 osThreadDef(ENGLISH, EnglishThread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE);\r\n\u00a0 \r\n\u00a0\u00a0 \u00a0 \/*\u00a0 Thread 2 definition *\/\r\n\u00a0\u00a0\u00a0 osThreadDef(FRENCH, FrenchThread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE);\r\n\u00a0 \r\n\u00a0\u00a0 \u00a0\/* Start thread 1 *\/\r\n\u00a0\u00a0\u00a0 LEDThread1Handle = osThreadCreate(osThread(ENGLISH), NULL);\r\n\u00a0 \r\n\u00a0\u00a0 \u00a0\/* Start thread 2 *\/\r\n\u00a0\u00a0\u00a0 LEDThread2Handle = osThreadCreate(osThread(FRENCH), NULL);<\/pre>\n<\/li>\n<li>Add a UARTPrintf() function that will format the messages and print them byte by byte:\n<pre class=\"\">#include &lt;stdarg.h&gt;\r\n\r\nstatic void UARTPrintf(const char *pFormat, ...)\r\n{\r\n\u00a0\u00a0\u00a0 char buffer[64];\r\n\u00a0\u00a0\u00a0 va_list args;\r\n\u00a0\u00a0\u00a0 va_start(args, pFormat);\r\n\u00a0\u00a0\u00a0 __disable_irq();\r\n\u00a0\u00a0\u00a0 int len = vsprintf(buffer, pFormat, args);\r\n\u00a0\u00a0\u00a0 __enable_irq();\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 for (int i = 0; i\u00a0 &lt; len; i++)\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 __disable_irq();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 HAL_UART_Transmit(&amp;g_UART, &amp;buffer[i], 1, HAL_MAX_DELAY);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 __enable_irq();\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 va_end(args);\r\n}<\/pre>\n<\/li>\n<li>Add a g_UART variable that will be used as a UART port handle:\n<pre class=\"\">UART_HandleTypeDef g_UART;<\/pre>\n<\/li>\n<li>Finally add the following code to main() before the call to osKernelStart() that will initialize the UART port. Note that if you are using a different board, the UART number and the GPIO port and pin numbers will be different:\n<pre class=\"\">\u00a0\u00a0\u00a0 __USART2_CLK_ENABLE();\r\n\u00a0\u00a0\u00a0 __GPIOA_CLK_ENABLE();\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 g_UART.Instance\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = USART2;\r\n\u00a0\u00a0\u00a0 g_UART.Init.BaudRate\u00a0\u00a0 = 115200;\r\n\u00a0\u00a0\u00a0 g_UART.Init.WordLength = UART_WORDLENGTH_8B;\r\n\u00a0\u00a0\u00a0 g_UART.Init.StopBits\u00a0\u00a0 = UART_STOPBITS_1;\r\n\u00a0\u00a0\u00a0 g_UART.Init.Parity\u00a0\u00a0\u00a0\u00a0 = UART_PARITY_NONE;\r\n\u00a0\u00a0\u00a0 g_UART.Init.HwFlowCtl\u00a0 = UART_HWCONTROL_NONE;\r\n\u00a0\u00a0\u00a0 g_UART.Init.Mode\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = UART_MODE_TX_RX;\r\n\u00a0\u00a0\u00a0 if (HAL_UART_Init(&amp;g_UART) != HAL_OK)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 asm(\"bkpt 255\");\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 GPIO_InitTypeDef\u00a0 GPIO_InitStruct;\r\n\u00a0 \r\n\u00a0\u00a0\u00a0 GPIO_InitStruct.Pin\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = GPIO_PIN_3;\r\n\u00a0\u00a0\u00a0 GPIO_InitStruct.Mode\u00a0\u00a0\u00a0\u00a0\u00a0 = GPIO_MODE_AF_PP;\r\n\u00a0\u00a0\u00a0 GPIO_InitStruct.Pull\u00a0\u00a0\u00a0\u00a0\u00a0 = GPIO_PULLUP;\r\n\u00a0\u00a0\u00a0 GPIO_InitStruct.Speed\u00a0\u00a0\u00a0\u00a0 = GPIO_SPEED_HIGH;\r\n\u00a0\u00a0\u00a0 GPIO_InitStruct.Alternate = GPIO_AF7_USART2;\r\n\r\n\u00a0\u00a0\u00a0 HAL_GPIO_Init(GPIOA, &amp;GPIO_InitStruct);\r\n\r\n\u00a0\u00a0\u00a0 GPIO_InitStruct.Pin = GPIO_PIN_2;\r\n\u00a0\u00a0\u00a0 GPIO_InitStruct.Alternate = GPIO_AF7_USART2;\r\n\r\n\u00a0\u00a0\u00a0 HAL_GPIO_Init(GPIOA, &amp;GPIO_InitStruct);<\/pre>\n<\/li>\n<li>Enable the Raw Terminal on the COM port connected to your board (you can find the COM port number for the ST-Link 2.1 via Device Manager):<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/term.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2491\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/term.png\" alt=\"term\" width=\"848\" height=\"581\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/term.png 848w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/term-300x206.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/term-130x90.png 130w\" sizes=\"(max-width: 848px) 100vw, 848px\" \/><\/a><\/li>\n<li>Press F5 to start debugging and observe how the messages from 2 threads are mixed together:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/07-mix.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2484\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/07-mix.png\" alt=\"07-mix\" width=\"1024\" height=\"768\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/07-mix.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/07-mix-300x225.png 300w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/li>\n<li>We will now use the VisualGDB Real-time to show what exactly happens on the microsecond level and why the messages get mixed. Enable real-time watch via the Dynamic Analysis page of VisualGDB Project Properties:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/08-analysis.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2483\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/08-analysis.png\" alt=\"08-analysis\" width=\"941\" height=\"730\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/08-analysis.png 941w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/08-analysis-300x233.png 300w\" sizes=\"(max-width: 941px) 100vw, 941px\" \/><\/a><\/li>\n<li>Start debugging. Once the threads are running, add UARTPrintf(), HAL_UART_Transmit() and the two thread names to the real-time watch window. Then continue the program and stop it once real-time watch gathers enough data:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/09-threads.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2482\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/09-threads.png\" alt=\"09-threads\" width=\"1024\" height=\"768\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/09-threads.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/09-threads-300x225.png 300w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a>Notice how the ENGLISH and FRENCH threads run one after the other and the calls to UARTPrintf() seem to overlap.<\/li>\n<li>The current picture does not fully explain why the output is mixed, so we will add custom real-time watches that will show the sent words and characters. Modify the UARTPrintf() function as shown below:\n<pre class=\"\">#include &lt;CustomRealTimeWatches.h&gt;\r\nstruct EventStreamWatch g_SendChar;\r\nstruct EventStreamWatch g_SendText;\r\n\r\nstatic void UARTPrintf(const char *pFormat, ...)\r\n{\r\n\u00a0\u00a0\u00a0 char buffer[64];\r\n\u00a0\u00a0\u00a0 va_list args;\r\n\u00a0\u00a0\u00a0 va_start(args, pFormat);\r\n\u00a0\u00a0\u00a0 __disable_irq();\r\n\u00a0\u00a0\u00a0 int len = vsprintf(buffer, pFormat, args);\r\n\u00a0\u00a0\u00a0 __enable_irq();\r\n\u00a0\u00a0\u00a0 EventStreamWatch_ReportEvent(&amp;g_SendText, buffer);\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 for (int i = 0; i\u00a0 &lt; len; i++)\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 __disable_irq();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 HAL_UART_Transmit(&amp;g_UART, &amp;buffer[i], 1, HAL_MAX_DELAY);\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 char ch[2] = { buffer[i], 0 };\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 EventStreamWatch_ReportEvent(&amp;g_SendChar, ch);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 __enable_irq();\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 va_end(args);\r\n}<\/pre>\n<\/li>\n<li>The EventStreamWatch_ReportEvent() function will only report the events if the <strong>g_SendChar<\/strong> and <strong>g_SendText<\/strong> watches are added to the real-time watch window. Add them once you start debugging and run the program again to collect enough events. You will see how g_SendText is called by the FRENCH thread, sends 2 characters, then the ENGLISH thread takes control and sends 2 characters from the English message:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/10-events.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2481\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/10-events.png\" alt=\"10-events\" width=\"1024\" height=\"768\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/10-events.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/10-events-300x225.png 300w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/li>\n<li>This behavior can be easily fixed using a mechanism called Mutex. A mutex can be &#8220;taken&#8221; by one thread before doing a critical operation (like writing a message) and if any other thread wants to take the same mutex, it will have to wait until the first one releases it. A FreeRTOS mutex should be declared like this:\n<pre class=\"\">SemaphoreHandle_t g_Mutex;<\/pre>\n<\/li>\n<li>Then you need to initialize it from main() before calling osKernelStart():\n<pre class=\"\">g_Mutex = xSemaphoreCreateMutex();<\/pre>\n<\/li>\n<li>Finally both English and French threads can take the mutex before calling UARTPrintf() and release it after calling it:\n<pre class=\"\">static void EnglishThread(void const *argument)\r\n{\r\n\u00a0\u00a0\u00a0 for (int i = 0;; i++)\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 xSemaphoreTake(g_Mutex, portMAX_DELAY);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 UARTPrintf(\"Hello %d\\r\\n\", i);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 xSemaphoreGive(g_Mutex);\r\n\u00a0\u00a0\u00a0 }\r\n}\r\n\r\nstatic void FrenchThread(void const *argument)\r\n{\r\n\u00a0\u00a0\u00a0 for (int i = 0;; i++)\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 xSemaphoreTake(g_Mutex, portMAX_DELAY);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 UARTPrintf(\"Bonjour %d\\r\\n\", i);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 xSemaphoreGive(g_Mutex);\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<\/li>\n<li>Run the program now. Note how the messages are no longer mixed, but the same thread often prints several messages in a row before the other one gets a chance to run:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/11-mutex.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2480\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/11-mutex.png\" alt=\"11-mutex\" width=\"1024\" height=\"768\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/11-mutex.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/11-mutex-300x225.png 300w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/li>\n<li>Add the g_Mutex to real-time watch and observe what causes this:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/retake1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2493\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/retake1.png\" alt=\"retake\" width=\"1024\" height=\"768\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/retake1.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/retake1-300x225.png 300w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a>If the FRENCH thread is preempted immediately after it releases the mutex, the ENGLISH thread starts running and manages to take it. If the preemption happens later, the ENGLISH thread cannot output any text, as the FRENCH thread as taken the mutex again.<\/li>\n<li>If we look into the FreeRTOS kernel sources, we will see that releasing the mutex results in a call to xTaskRemoveFromEventList() that lets the thread waiting for the mutex take control only if its priority is higher than the current thread priority:\n<pre class=\"\">\u00a0\u00a0\u00a0 if (pxUnblockedTCB-&gt;uxPriority &gt; pxCurrentTCB-&gt;uxPriority)\r\n\u00a0\u00a0 \u00a0{\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/* Return true if the task removed from the event list has a higher\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0priority than the calling task.\u00a0 This allows the calling task to know if\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0it should force a context switch now. *\/\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0xReturn = pdTRUE;\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/* Mark that a yield is pending in case the user is not using the\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\"xHigherPriorityTaskWoken\" parameter to an ISR safe FreeRTOS function. *\/\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0xYieldPending = pdTRUE;\r\n\u00a0\u00a0 \u00a0}<\/pre>\n<\/li>\n<li>We could modify the FreeRTOS kernel so that when a mutex is released, the first thread waiting for it will get switched immediately. This will result in more context switches (and lower performance), but no thread will occupy the CPU for too long. Rename xTaskRemoveFromEventList() to xTaskRemoveFromEventListEx() and add an extra parameter to it:\n<pre class=\"\">BaseType_t xTaskRemoveFromEventListEx(const List_t * const pxEventList, BaseType_t yieldIfSamePriority)<\/pre>\n<p>Change the yield condition to also trigger when the thread priorities are the same and <strong>yieldIfSamePriority<\/strong> is true:<\/p>\n<pre class=\"\">if (pxUnblockedTCB-&gt;uxPriority &gt; pxCurrentTCB-&gt;uxPriority || (yieldIfSamePriority &amp;&amp; pxUnblockedTCB-&gt;uxPriority == pxCurrentTCB-&gt;uxPriority))<\/pre>\n<p>Add the following wrapper to task.h so that existing code calling xTaskRemoveFromEventList() can still work:<\/p>\n<pre class=\"\">static BaseType_t xTaskRemoveFromEventList(const List_t * const pxEventList) PRIVILEGED_FUNCTION\r\n{\r\n\u00a0\u00a0\u00a0 xTaskRemoveFromEventListEx(pxEventList, pdFALSE);\r\n}<\/pre>\n<\/li>\n<li>FreeRTOS mutexes are implemented as queues with zero element size. When a mutex is released, FreeRTOS posts a virtual message to the queue. When another thread wants to take the mutex, it reads the message from the queue, making it empty again. We will now add a flag to the queue object that will enable the new &#8220;immediate yield&#8221; behavior. Add a new member to the end of QueueDefinition in queue.c:\n<pre class=\"\">typedef struct QueueDefinition\r\n{\r\n\u00a0\u00a0 \u00a0\/\/...\r\n\u00a0\u00a0\u00a0 uint8_t YieldToSamePriorityTasks;\r\n} xQUEUE;<\/pre>\n<p>Change xQueueGenericSend() to set yieldIfSamePriority to 1 if the new queue flag was set:<\/p>\n<pre class=\"\">if( listLIST_IS_EMPTY( &amp;( pxQueue-&gt;xTasksWaitingToReceive ) ) == pdFALSE )\r\n{\r\n\u00a0\u00a0 \u00a0if( xTaskRemoveFromEventListEx( &amp;( pxQueue-&gt;xTasksWaitingToReceive ), pxQueue-&gt;YieldToSamePriorityTasks ) == pdTRUE )\r\n\u00a0\u00a0 \u00a0{\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0queueYIELD_IF_USING_PREEMPTION();\r\n\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0\/\/...\r\n}<\/pre>\n<p>Finally add a new function that will enable the YieldToSamePriorityTasks mode on the queue and call it from main() after creating the mutex:<\/p>\n<pre class=\"\">void xQueueYieldToSamePriorityTasks(QueueHandle_t xQueue)\r\n{\r\n\u00a0\u00a0\u00a0 Queue_t * const pxQueue = (Queue_t *) xQueue;\r\n\u00a0\u00a0\u00a0 pxQueue-&gt;YieldToSamePriorityTasks = pdTRUE;\r\n}<\/pre>\n<pre class=\"\">xQueueYieldToSamePriorityTasks(g_Mutex);<\/pre>\n<\/li>\n<li>If you run the code now, you will see that the switch between the threads happens much more often:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/12-fair.png\"> <img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2479\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/12-fair.png\" alt=\"12-fair\" width=\"1024\" height=\"768\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/12-fair.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/12-fair-300x225.png 300w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/li>\n<li>The Real-time watch clearly shows how releasing the mutex now immediately results in a switch to the other thread and the only reason why the same thread could print 2 messages consecutively is if the other thread gets preempted before it manages to acquire the mutex:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/13-owner.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2478\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/13-owner.png\" alt=\"13-owner\" width=\"1024\" height=\"768\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/13-owner.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/13-owner-300x225.png 300w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/li>\n<li>If you disable the real-time watch now, the overhead of reporting thread switches and other events will be eliminated and you will see that the threads get to run almost exactly in a round-robin fashion:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/fairrate.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2494\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/fairrate.png\" alt=\"fairrate\" width=\"1024\" height=\"768\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/fairrate.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/12\/fairrate-300x225.png 300w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to use FreeRTOS mutexes to avoid race conditions between different threads. We will show how preemption<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[140],"tags":[67,61],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/2476"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=2476"}],"version-history":[{"count":1,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/2476\/revisions"}],"predecessor-version":[{"id":2495,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/2476\/revisions\/2495"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=2476"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=2476"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=2476"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}