互斥量的使用

官方的描述
在这里插入图片描述互斥量主要是对于共享资源的保护

在这里插入图片描述

其中参数要注意
osMutexRecursive://递归互斥量
互斥锁嵌套属性,同一个线程可以在不锁定自身的情况下多次使用互斥锁。每当拥有互斥锁的线程获得互斥锁时,锁计数就会增加。互斥锁也必须被释放多次,直到锁定计数为零。当互斥量达到0时,互斥量实际上会被释放,其他线程可以获取互斥量。
osMutexPrioInherit://优先级继承
优先级继承属性,使用优先级继承属性的互斥锁将 ”等待线程“ 的优先级转移给当前互斥锁的所有者(如果所有者的线程优先级较低)。这确保了低优先级线程不会阻塞高优先级线程。否则,低优先级线程可能持有互斥锁,但由于另一个中优先级线程而没有获得执行时间。如果没有优先级继承,等待互斥锁的高优先级线程将被中优先级线程阻塞,称为优先级反转。
osMutexRobust://当线程终止时,自动释放互斥锁
互斥锁健壮属性,如果拥有的线程被终止(通过osThreadExit或osThreadTerminate),健壮的互斥锁将被自动释放。非健壮互斥锁不会被释放,用户必须手动确保释放互斥锁。

使用逻辑“OR”操作选择多个选项

互斥量的创建
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

osMutexId_t mutex_id;   /* 互斥量  */
const osMutexAttr_t Thread_Mutex_attr = {
  "myThreadMutex",     // human readable mutex name
//  osMutexRecursive,    // attr_bits  //互斥量的类型
	 osMutexPrioInherit | osMutexRobust,
  NULL,                // memory for control block   
  0U                   // size for control block
};





void thread_Start_App(void *argument)
{
	
	osStatus_t status;
	uint8_t ucKeyCode;		/* 按键代码 */
	
	MsgQueue_T   lt_Qqueue;
    MEM_BLOCK_t *pMem;
	
	
	mpid_MemPool = osMemoryPoolNew(MEMPOOL_OBJECTS, sizeof(MEM_BLOCK_t), NULL);
	 if (mpid_MemPool == NULL)
	{
    	printf("MemoryPool is Failed. \r\n");//创建失败
	 }
	else
	{
		printf("MemoryPool is OK. \r\n");//创建失败
	 }
	

	msgQueue_ID = osMessageQueueNew(QUEUE_SIZE,           //队列的元素数量
									 sizeof(pMem),  //单个元素的大小
									 NULL                 //队列的属性
									 );
	if(NULL==msgQueue_ID)
	{
		printf("msgQueue_ID is Failed. \r\n");//队列创建失败
	}
	else
	{
		printf("msgQueue_ID is Success. \r\n");//队列创建成功
	}																	 
							 
	threadID_LED = osThreadNew(thread_LED_App,NULL,&thread_LED_Attr);   /* 创建LED线程 */  
	if(NULL == threadID_LED)
	{
		printf("threadID_LED is Failed. \r\n");//创建失败
	}
	else
	{
		printf("threadID_LED is OK. \r\n");//创建成功
	}
	
	 mutex_id = osMutexNew(&Thread_Mutex_attr);
  if (mutex_id != NULL)  
	  {
		  printf("(mutex_idD is OK. \r\n");//创建成功
   
     }
	
	threadID_User= osThreadNew(thread_User_App,NULL,&thread_User_Attr);   /* 创建LED线程 */  
	if(NULL == threadID_User)
	{
		printf("threadID_User is Failed. \r\n");//创建失败
	}
	else
	{
		printf("threadID_User is OK. \r\n");//创建成功
	}
	
	while(1)
	{
		
		
		status = osMutexAcquire(mutex_id,osWaitForever);//	永久等待,直到等到互斥量
        printf("threadID_Star  is  Acquire  mutex_id. \r\n");
		
		HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
		
		status = osMutexRelease(mutex_id);//	永久等待,直到等到互斥量
		if (status == osOK) 
		{
		   printf("threadID_Star  is  Release mutex_id. \r\n");
		}
		osDelay(100);
	
	}
}


void thread_LED_App(void *argment)
{
 osStatus_t status;

	   MEM_BLOCK_t *pMem;

	
	while(1)
	{
//		osMessageQueueGet(msgQueue_ID,(void *)&pMem, NULL, osWaitForever);  //出队列,永久等待

//		HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
//	    printf("msgQueue_ID get is OK  pMem->Buf[0] is %d,pMem->Idx is  %d \r\n",pMem->Buf[0],pMem->Idx);//获取队列数据成功
//		 osMemoryPoolFree(mpid_MemPool,pMem);            // free mem block
		
		status = osMutexAcquire(mutex_id,osWaitForever);//	永久等待,直到等到互斥量
        printf("threadID__LED  is  Acquire  mutex_id. \r\n");
		
		
		
		osDelay(2000);
		
		status = osMutexRelease(mutex_id);//	永久等待,直到等到互斥量
		if (status == osOK) 
		{
		   printf("threadID__LED  is  Release mutex_id. \r\n");
		}
		
		
	}
}

看下打印结果
在这里插入图片描述
同时,LED本来是100ms的频率闪烁。由于互斥量的原因,LED也因此变成2秒闪烁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值