在实时操作系统uC/OS-III中,互斥锁(Mutex)是一种用于管理对共享资源的访问的同步机制。互斥锁通过保证在任何时刻只有一个任务可以持有锁,从而防止资源竞争问题。同时,uC/OS-III还实现了递归锁定和优先级继承机制,以增强系统的实时性和稳定性。
1. OSMutexCreate接口
1.1 接口说明
该接口用于创建一个互斥锁。
参数
p_mutex
: 指向待初始化的互斥锁对象的指针。
p_name
: 指向互斥锁名称的指针。
p_err
: 指向错误码的指针。可能的错误码
OS_ERR_NONE
: 操作成功。
OS_ERR_CREATE_ISR
: 在中断服务程序中调用。
OS_ERR_ILLEGAL_CREATE_RUN_TIME
: 在系统启动后调用。
OS_ERR_OBJ_PTR_NULL
:p_mutex
为NULL。
OS_ERR_OBJ_CREATED
: 互斥锁已创建。
1.2 接口实现流程图
2. OSMutexPend接口
2.1 接口说明
该接口用于等待一个互斥锁。
参数
p_mutex
: 指向待等待的互斥锁对象的指针。
timeout
: 等待的最大时钟节拍数。
opt
: 等待选项,可以是阻塞或非阻塞。
p_ts
: 指向接收时间戳的指针。
p_err
: 指向错误码的指针。可能的错误码
OS_ERR_NONE
: 操作成功。
OS_ERR_MUTEX_OWNER
: 当前任务已经拥有互斥锁。
OS_ERR_MUTEX_OVF
: 互斥锁嵌套计数器溢出。
OS_ERR_OBJ_DEL
: 互斥锁被删除。
OS_ERR_OBJ_PTR_NULL
:p_mutex
为NULL。
OS_ERR_OBJ_TYPE
:p_mutex
不是互斥锁。
OS_ERR_OPT_INVALID
: 无效选项。
OS_ERR_OS_NOT_RUNNING
: 系统未运行。
OS_ERR_PEND_ABORT
: 等待被中止。
OS_ERR_PEND_ISR
: 在中断服务程序中调用。
OS_ERR_PEND_WOULD_BLOCK
: 非阻塞等待。
OS_ERR_SCHED_LOCKED
: 调度器被锁定。
OS_ERR_STATUS_INVALID
: 无效等待状态。
OS_ERR_TIMEOUT
: 超时。
2.2 接口实现流程图
3. OSMutexPost接口
3.1 接口说明
该接口用于释放一个互斥锁。
参数
p_mutex
: 指向待释放的互斥锁对象的指针。opt
: 选项,可以指定是否调度。p_err
: 指向错误码的指针。可能的错误码
OS_ERR_NONE
: 操作成功。OS_ERR_MUTEX_NESTING
: 互斥锁嵌套计数器未归零。OS_ERR_MUTEX_NOT_OWNER
: 当前任务不是互斥锁的拥有者。OS_ERR_OBJ_PTR_NULL
:p_mutex
为NULL。OS_ERR_OBJ_TYPE
:p_mutex
不是互斥锁。OS_ERR_OPT_INVALID
: 无效选项。OS_ERR_OS_NOT_RUNNING
: 系统未运行。OS_ERR_POST_ISR
: 在中断服务程序中调用。
3.2 接口实现流程图
4. 互斥锁递归锁定
4.1 递归锁定原理
递归锁定允许同一个任务多次获得同一个互斥锁,而不会引起死锁。实现递归锁定的关键是增加一个嵌套计数器,每当一个任务获取锁时,计数器增加;每当任务释放锁时,计数器减少,直到计数器为零时,才真正释放互斥锁。
4.2 递归锁定应用场景
- 嵌套函数调用:在一个任务中,函数A持有互斥锁,然后调用函数B,函数B也尝试获取同一个互斥锁。如果没有递归锁定,函数B会导致死锁。
4.3 递归锁定实现代码段
void OSMutexPend (OS_MUTEX *p_mutex, OS_TICK timeout, OS_OPT opt, CPU_TS *p_ts, OS_ERR *p_err) {CPU_SR_ALLOC();CPU_CRITICAL_ENTER();if (p_mutex->OwnerNestingCtr == 0u) {p_mutex->OwnerTCBPtr = OSTCBCurPtr;p_mutex->OwnerNestingCtr = 1u;CPU_CRITICAL_EXIT();*p_err = OS_ERR_NONE;return;}if (OSTCBCurPtr == p_mutex->OwnerTCBPtr) {p_mutex->OwnerNestingCtr++;CPU_CRITICAL_EXIT();*p_err = OS_ERR_MUTEX_OWNER;return;}......CPU_CRITICAL_EXIT();
}
5. 互斥锁优先级继承
5.1 优先级继承实现原理
优先级继承机制用于防止优先级反转。当高优先级任务等待被低优先级任务持有的互斥锁时,低优先级任务会临时提升到高优先级任务的优先级,以减少高优先级任务的等待时间。
5.2 优先级继承应用场景
优先级继承在以下场景中非常有用:
实时系统:在实时系统中,优先级反转可能会导致高优先级任务的响应时间过长,影响系统的实时性。
资源竞争:当多个任务竞争同一个资源时,优先级继承可以确保高优先级任务能够尽快获得资源。
5.3 优先级继承实现代码段
void OSMutexPend (OS_MUTEX *p_mutex, OS_TICK timeout, OS_OPT opt, CPU_TS *p_ts, OS_ERR *p_err) {OS_TCB *p_tcb;CPU_SR_ALLOC();CPU_CRITICAL_ENTER();if (p_mutex->OwnerNestingCtr == 0u) {p_mutex->OwnerTCBPtr = OSTCBCurPtr;p_mutex->OwnerNestingCtr = 1u;CPU_CRITICAL_EXIT();*p_err = OS_ERR_NONE;return;}p_tcb = p_mutex->OwnerTCBPtr;if (p_tcb->Prio > OSTCBCurPtr->Prio) {OS_TaskChangePrio(p_tcb, OSTCBCurPtr->Prio);}......CPU_CRITICAL_EXIT();
}
总结
文中详细介绍了uC/OS-III中互斥锁的接口及其实现原理,包括互斥锁的创建、等待和释放过程,同时解析了递归锁定和优先级继承机制。
互斥锁接口
- OSMutexCreate: 创建互斥锁,初始化互斥锁的数据结构,并进行必要的检查。
- OSMutexPend: 等待互斥锁,支持阻塞和非阻塞模式,通过嵌套计数器实现递归锁定,同时支持优先级继承以防止优先级反转。
- OSMutexPost: 释放互斥锁,通过递减嵌套计数器来实现递归锁定的释放,保证只有在嵌套计数器归零时才真正释放锁。
递归锁定
递归锁定允许同一任务多次获得同一互斥锁而不会导致死锁。通过嵌套计数器,每次任务获得锁时计数器递增,释放锁时计数器递减,只有在计数器归零时才真正释放锁。这在复杂代码段或嵌套函数调用中尤为有用,避免了任务的死锁。
优先级继承
优先级继承机制防止优先级反转。当高优先级任务等待低优先级任务持有的锁时,低优先级任务会暂时提升到高优先级任务的优先级,确保高优先级任务能够尽快获得资源。这对于保证实时系统的响应时间和系统稳定性至关重要。