互斥型信号量
互斥型信号量是一个二值信号量,可以使任务以独占方式使用共享,他可以独占方式使用共享资源。
互斥型信号量会出现任务优先级反转的问题。
1.优先级反转
在可剥夺型内核中,当任务以独占方式使用共享资源时,会出现低优先级任务先于高优先级 任务而被运行现象,这种现象叫做任务优先级反转。
出现优先级反转现象:
是因为一个优先级别较低的任务在获得了信号量使用共享资源期间,被具有较高优先级别的任务所打断而不能释放信号量,从而使正在等待这个信号量的
更高级别的任务所打断而不能是释放信号量,而从是正在等待这个信号量的更高级别的任务因为得不到信号量而被迫处于等待状态,在这个等待期间,就让优先级别低于它而高于占据信号量 的任务的任务先运行。
解决优先级反转的方法:
将获得信号量任务的优先级别的使用共享资源期间暂时提升到所有任务优先级别高一个优先级上,以使该任务不被其他任务所打断,从而使能尽快低使用共享资源并是否信号量;然后在释放信号量之后,再恢复该任务原来的优先级别。
2. 互斥型信号量
互斥型信号量是一个二值信号量,因此也叫信号。
事件控制块中,OSEventType=OS_EVENT_TYPE_MUTEX表明是一个互斥型信号量,
OSEventCnt被分为低8位和高8位, 低8位用来存放信号值(0xFF有效),高8位用来存放为避免出现优先级反转而要提升的优先级别prio。
3. 创建互斥型信号量
创建互斥型信号量函数OSMUTEXCreate(), 函数原型:
OS_EVENT *OSMutexCreate( INT8U prio, //优先级别
INT8U *err);
从空事件控制块链表中获取一个事件控制块,把成员OSEventType=OS_EVENT_TYPE_MUTEX,表明是互斥型信号量; 容纳后在把OSEventCnt高8位赋以prio(要提升的优先级别), 低8位赋以常数OS_MUTEXT_AVAILABLE(0xFF),以表明信号量尚未被任务任务所占用。
4. 请求互斥型信号量
当任务需要访问一个独占式共享资源时,就要调用函数OSMuexPend()来请求管理这个资源的互斥型信号量。如果信号量有信号 z,则意味着目前无二五年占用资源,于是任务可以继续运行并对该资源进行访问; 否则就进入等待状态,直至占用这个资源的其他任务释放了该信号量。
函数原型:
void OSMutexPend( OS_EVENT *pevent, INT16U timeout, INT8U *err );
注意:
任务也可以通过调用函数OSMutexAccept()无等待地请求一个互斥型信号量。函数原型:
INT8U OSMutexAccept( OS_EVENT *pevent, INT8U *err);
5. 发送互斥型信号量
任务可以通过调用函数OSMutexPost()发送一个互斥型信号量。函数原型:
INT8U OSMutexPost( OS_EVENT *pevent);
6.获取互斥型信号量的当前状态
任务可以通过调用函数OSMutexQuery()来获得互斥型信号量的当前状态。函数原型:
INT8U OSMutexQuery( OS_EVENT *pevent, //互斥型信号量指针
OS_MUTEX_DATA *pdata); // 存放互斥型信号量状态的结构
7. 删除互斥型信号量
函数原型:
OS_EVENT *OSMutexDel( OS_EVENT *pevent, INT8U opt, INT8U *err);