Mutex
Mutex, also known as mutex semaphore (essentially a semaphore, does not have the function of transmitting data), is a special binary semaphore. It is different from a semaphore in that it supports mutex ownership, recursion Features for accessing and preventing priority inversion. For example, if there are two tasks, A is running, but B cannot run.
Experiment: Create three tasks, set the priority from high to low, use mutexes in tasks one and three, and observe the execution order.
Implementation: Modify on the basis of [STM32] FreeRTOS message queue and semaphore learning
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Create the mutex(es) */
/* definition and creation of Mutex01 */
osMutexDef(Mutex01);
Mutex01Handle = osMutexCreate(osMutex(Mutex01));
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* Create the semaphores(s) */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* definition and creation of Task1 */
osThreadDef(Task1, StartDefaultTask, osPriorityHigh, 0, 128);
Task1Handle = osThreadCreate(osThread(Task1), NULL);
/* definition and creation of Task2 */
osThreadDef(Task2, StartTask02, osPriorityAboveNormal, 0, 128);
Task2Handle = osThreadCreate(osThread(Task2), NULL);
/* definition and creation of Task3 */
osThreadDef(Task3, StartTask03, osPriorityNormal, 0, 128);
Task3Handle = osThreadCreate(osThread(Task3), NULL);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
}
/* USER CODE BEGIN Header_StartDefaultTask */
/**
* @brief Function implementing the Task1 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const * argument)
{
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
for(;;)
{
osDelay(10);//堵塞
if(xSemaphoreTake(Mutex01Handle,portMAX_DELAY)!=pdTRUE)
{
printf("task1,进不去\r\n");
}
else
{
printf("task1,抢占进入\r\n");
}
xSemaphoreGive(Mutex01Handle);
printf("task1,完成\r\n");
}
/* USER CODE END StartDefaultTask */
}
/* USER CODE BEGIN Header_StartTask02 */
/**
* @brief Function implementing the Task2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask02 */
void StartTask02(void const * argument)
{
/* USER CODE BEGIN StartTask02 */
/* Infinite loop */
for(;;)
{
osDelay(2);//堵塞
printf("task2,运行\r\n");
}
/* USER CODE END StartTask02 */
}
/* USER CODE BEGIN Header_StartTask03 */
/**
* @brief Function implementing the Task3 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask03 */
void StartTask03(void const * argument)
{
/* USER CODE BEGIN StartTask03 */
/* Infinite loop */
for(;;)
{
xSemaphoreTake(Mutex01Handle,0);
printf("task3,进入\r\n");
xSemaphoreGive(Mutex01Handle);
printf("task3,完成\r\n");
}
/* USER CODE END StartTask03 */
}
Phenomenon:
The lowest priority is executed first, the highest priority is executed next, and the middle priority is executed last.