一、概念
  
 
 在多数情况下,互斥型信号量和二值型信号量非常相似,但是从功能上二值型信号量用于同步,  
 
 
 而互斥型信号量用于资源保护。  
 
 
 互斥型信号量和二值型信号量还有一个最大的区别,互斥型信号量可以有效解决优先级反转现  
 
 
 象。 
 
 
  优先级反转: 
 
 
  系统中有 
  3 
  个不同优先级的任务 
  H/M/L 
  ,最高优先级任务 
  H 
  和最低优先级任务 
  L 
  通过 信号量机制,共享资源。目前任务L 
  占有资源,锁定了信号量, 
  Task H 
  运行后将被阻塞,直到 
  Task L释放信号量后, 
  Task H 
  才能够退出阻塞状态继续运行。但是 
  Task H 
  在等待 
  Task L 
  释放信号量的过程中,中等优先级任务M 
  抢占了任务 
  L 
  ,从而延迟了信号量的释放时间,导致 
  Task H 
  阻塞了更长时 间,这种现象称为优先级倒置或反转。  
 
 
  
  优先级继承:当一个互斥信号量正在被一个低优先级的任务持有时, 如果此时有个高优先级的任  
 
 
  
  务也尝试获取这个互斥信号量,那么这个高优先级的任务就会被阻塞。 
  不过这个高优先级的任务  
 
 
  
  会将低优先级任务的优先级提升到与自己相同的优先级。  
 
 
  
  优先级继承并不能完全的消除优先级翻转的问题,它只是尽可能的降低优先级翻转带来的影响。  
 
 
  
  
 
 二、没有使用互斥量的时候
 配置中、高、低三个优先级
   
  osThreadDef(TaskH, StartTaskH, osPriorityAboveNormal, 0, 128);
  TaskHHandle = osThreadCreate(osThread(TaskH), NULL);
  osThreadDef(TaskM, StartTaskM, osPriorityNormal, 0, 128);
  TaskMHandle = osThreadCreate(osThread(TaskM), NULL);
 
  osThreadDef(TaskL, StartTaskL, osPriorityBelowNormal, 0, 128);
  TaskLHandle = osThreadCreate(osThread(TaskL), NULL);
void StartTaskH(void const * argument)
{
  for(;;)
  {
		xSemaphoreTake(myBinarySemHandle,portMAX_DELAY);
		printf("TaskH:我开始进入厕所,发功中。。\r\n");
		HAL_Delay(1000);
		printf("TaskH:我上完厕所了,真舒服。。。\r\n");
		xSemaphoreGive(myBinarySemHandle);
    osDelay(1000);
  }
}
void StartTaskM(void const * argument)
{
  for(;;)
  {
		printf("TaskM:我就是为了占用资源,带女朋友兜风\r\n");
		
    osDelay(1000);
  }
}
void StartTaskL(void const * argument)
{
  for(;;)
  {
		xSemaphoreTake(myBinarySemHandle,portMAX_DELAY);
		printf("TaskL:我开始进入厕所,发功中。。\r\n");
		HAL_Delay(3000);
		printf("TaskL:我上完厕所了,真舒服。。。\r\n");
		xSemaphoreGive(myBinarySemHandle);
    osDelay(1000);
  }
}
 

互斥量实验(接上半部分)
首先删除二值信号量

创建互斥量

void MX_FREERTOS_Init(void) {
 
  osMutexDef(myMutex);
  myMutexHandle = osMutexCreate(osMutex(myMutex));
  
  osThreadDef(TaskH, StartTaskH, osPriorityAboveNormal, 0, 128);
  TaskHHandle = osThreadCreate(osThread(TaskH), NULL);
  osThreadDef(TaskM, StartTaskM, osPriorityNormal, 0, 128);
  TaskMHandle = osThreadCreate(osThread(TaskM), NULL);
  osThreadDef(TaskL, StartTaskL, osPriorityBelowNormal, 0, 128);
  TaskLHandle = osThreadCreate(osThread(TaskL), NULL);
}
void StartTaskH(void const * argument)
{
 
  for(;;)
  {
		xSemaphoreTake(myMutexHandle,portMAX_DELAY);//句柄变为myMutexHandle
		printf("TaskH:我开始进入厕所,发功中。。\r\n");
		HAL_Delay(1000);
		printf("TaskH:我上完厕所了,真舒服。。。\r\n");
		xSemaphoreGive(myMutexHandle);
    osDelay(1000);
  }
  
}
void StartTaskM(void const * argument)
{
 
  for(;;)
  {
		printf("TaskM:我就是为了占用资源,带女朋友兜风\r\n");
		
    osDelay(1000);
  }
}
void StartTaskL(void const * argument)
{
 
  for(;;)
  {
		xSemaphoreTake(myMutexHandle,portMAX_DELAY);
		printf("TaskL:我开始进入厕所,发功中。。\r\n");
		HAL_Delay(3000);
		printf("TaskL:我上完厕所了,真舒服。。。\r\n");
		xSemaphoreGive(myMutexHandle);
    osDelay(1000);
  }
}运行结果:

通过引入互斥量,可以实现资源的保护功能。



















