官方的描述
互斥量主要是对于共享资源的保护
其中参数要注意
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 blockstatus = 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秒闪烁