首页 > 编程语言 >UcOs-III 源码阅读: os_mutex.c

UcOs-III 源码阅读: os_mutex.c

时间:2024-10-31 17:01:49浏览次数:1  
标签:ERR UcOs 0u III 互斥 源码 mutex MUTEX OS

//作用:管理互斥量的代码

/*
*********************************************************************************************************
*                                              uC/OS-III
*                                        The Real-Time Kernel
*
*                    Copyright 2009-2022 Silicon Laboratories Inc. www.silabs.com
*
*                                 SPDX-License-Identifier: APACHE-2.0
*
*               This software is subject to an open source license and is distributed by
*                Silicon Laboratories Inc. pursuant to the terms of the Apache License,
*                    Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
*
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           互斥锁管理
*
* 文件    : os_mutex.c
* 版本    : V3.08.02
*********************************************************************************************************
*/

#define  MICRIUM_SOURCE
#include "os.h"

#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const  CPU_CHAR  *os_mutex__c = "$Id: $";
#endif


#if (OS_CFG_MUTEX_EN > 0u)
/*
************************************************************************************************************************
*                                                   创建互斥锁
*
* 描述: 此函数用于创建一个互斥锁。
*
* 参数: p_mutex       指向要初始化的互斥锁的指针。您的应用程序负责为互斥锁分配存储空间。
*
*              p_name        指向您希望给互斥锁命名的指针。
*
*              p_err         指向一个变量,该变量将包含此函数返回的错误代码。
*
*                                OS_ERR_NONE                    如果调用成功
*                                OS_ERR_CREATE_ISR              如果您从中断服务例程 (ISR) 中调用了此函数
*                                OS_ERR_ILLEGAL_CREATE_RUN_TIME 如果您在调用 OSSafetyCriticalStart() 之后尝试创建互斥锁
*                                OS_ERR_OBJ_PTR_NULL            如果 'p_mutex' 是空指针
*                                OS_ERR_OBJ_CREATED             如果互斥锁已经创建
*
* 返回值: 无
*
* 注意: 无
************************************************************************************************************************
*/

void OSMutexCreate(OS_MUTEX *p_mutex, CPU_CHAR *p_name, OS_ERR *p_err)
{
    CPU_SR_ALLOC();  // 分配 CPU 状态寄存器

#ifdef OS_SAFETY_CRITICAL
    if (p_err == (OS_ERR *)0) {  // 检查错误指针是否为空
        OS_SAFETY_CRITICAL_EXCEPTION();  // 安全关键异常处理
        return;
    }
#endif

#ifdef OS_SAFETY_CRITICAL_IEC61508
    if (OSSafetyCriticalStartFlag == OS_TRUE) {  // 检查是否在运行时创建互斥锁
        *p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;  // 运行时创建互斥锁非法
        return;
    }
#endif

#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
    if (OSIntNestingCtr > 0u) {  // 检查是否从中断服务例程 (ISR) 调用
        *p_err = OS_ERR_CREATE_ISR;  // 从中断服务例程 (ISR) 创建互斥锁非法
        return;
    }
#endif

#if (OS_CFG_ARG_CHK_EN > 0u)
    if (p_mutex == (OS_MUTEX *)0) {  // 检查互斥锁指针是否为空
        *p_err = OS_ERR_OBJ_PTR_NULL;  // 互斥锁指针为空
        return;
    }
#endif

    CPU_CRITICAL_ENTER();  // 进入临界区

#if (OS_OBJ_TYPE_REQ > 0u)
#if (OS_CFG_OBJ_CREATED_CHK_EN > 0u)
    if (p_mutex->Type == OS_OBJ_TYPE_MUTEX) {  // 检查互斥锁是否已创建
        CPU_CRITICAL_EXIT();  // 退出临界区
        *p_err = OS_ERR_OBJ_CREATED;  // 互斥锁已创建
        return;
    }
#endif
    p_mutex->Type = OS_OBJ_TYPE_MUTEX;  // 标记数据结构为互斥锁
#endif

#if (OS_CFG_DBG_EN > 0u)
    p_mutex->NamePtr = p_name;  // 设置互斥锁名称
#else
    (void)p_name;  // 忽略名称参数
#endif

    p_mutex->MutexGrpNextPtr = (OS_MUTEX *)0;  // 初始化互斥锁链表指针
    p_mutex->OwnerTCBPtr = (OS_TCB *)0;  // 初始化所有者任务控制块指针
    p_mutex->OwnerNestingCtr = 0u;  // 初始化嵌套计数器,表示互斥锁可用
#if (OS_CFG_TS_EN > 0u)
    p_mutex->TS = 0u;  // 初始化时间戳
#endif

    OS_PendListInit(&p_mutex->PendList);  // 初始化等待列表

#if (OS_CFG_DBG_EN > 0u)
    OS_MutexDbgListAdd(p_mutex);  // 将互斥锁添加到调试列表
    OSMutexQty++;  // 增加互斥锁数量
#endif

    OS_TRACE_MUTEX_CREATE(p_mutex, p_name);  // 跟踪互斥锁创建
    CPU_CRITICAL_EXIT();  // 退出临界区
    *p_err = OS_ERR_NONE;  // 设置错误代码为无错误
}


/*
************************************************************************************************************************
*                                                   删除互斥锁
*
* 描述: 此函数删除一个互斥锁,并准备好所有在该互斥锁上等待的任务。
*
* 参数: p_mutex       指向要删除的互斥锁的指针
*
*              opt           确定删除选项,如下所示:
*
*                                OS_OPT_DEL_NO_PEND          仅在没有任务等待时删除互斥锁
*                                OS_OPT_DEL_ALWAYS           即使有任务等待也删除互斥锁。
*                                                            在这种情况下,所有等待的任务都将被准备好。
*
*              p_err         指向一个变量,该变量将包含此函数返回的错误代码。
*
*                                OS_ERR_NONE                    调用成功且互斥锁已被删除
*                                OS_ERR_DEL_ISR                 如果您尝试从中断服务例程 (ISR) 中删除互斥锁
*                                OS_ERR_ILLEGAL_DEL_RUN_TIME    如果您在调用 OSStart() 之后尝试删除互斥锁
*                                OS_ERR_OBJ_PTR_NULL            如果 'p_mutex' 是空指针
*                                OS_ERR_OBJ_TYPE                如果 'p_mutex' 不是指向互斥锁的指针
*                                OS_ERR_OPT_INVALID             指定了无效的选项
*                                OS_ERR_OS_NOT_RUNNING          如果 uC/OS-III 尚未运行
*                                OS_ERR_TASK_WAITING            有一个或多个任务正在等待互斥锁
*
* 返回值: == 0          如果没有任务在等待互斥锁,或者发生错误。
*              >  0          如果一个或多个等待互斥锁的任务现在已被准备好并通知。
*
* 注意: 1) 使用此函数时必须小心。通常期望互斥锁存在的任务必须检查 OSMutexPend() 的返回代码。
*
*              2) 因为所有在互斥锁上等待的任务都将被准备好,所以在互斥锁用于互斥的应用程序中,您必须小心,因为资源将不再受互斥锁保护。
************************************************************************************************************************
*/

#if (OS_CFG_MUTEX_DEL_EN > 0u)
OS_OBJ_QTY OSMutexDel(OS_MUTEX *p_mutex, OS_OPT opt, OS_ERR *p_err)
{
    OS_OBJ_QTY     nbr_tasks;
    OS_PEND_LIST  *p_pend_list;
    OS_TCB        *p_tcb;
    OS_TCB        *p_tcb_owner;
    CPU_TS         ts;
#if (OS_CFG_MUTEX_EN > 0u)
    OS_PRIO        prio_new;
#endif
    CPU_SR_ALLOC();  // 分配 CPU 状态寄存器

#ifdef OS_SAFETY_CRITICAL
    if (p_err == (OS_ERR *)0) {  // 检查错误指针是否为空
        OS_SAFETY_CRITICAL_EXCEPTION();  // 安全关键异常处理
        return (0u);
    }
#endif

    OS_TRACE_MUTEX_DEL_ENTER(p_mutex, opt);  // 跟踪互斥锁删除进入

#ifdef OS_SAFETY_CRITICAL_IEC61508
    if (OSSafetyCriticalStartFlag == OS_TRUE) {  // 检查是否在运行时删除互斥锁
        OS_TRACE_MUTEX_DEL_EXIT(OS_ERR_ILLEGAL_DEL_RUN_TIME);  // 跟踪互斥锁删除退出
        *p_err = OS_ERR_ILLEGAL_DEL_RUN_TIME;  // 运行时删除互斥锁非法
        return (0u);
    }
#endif

#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
    if (OSIntNestingCtr > 0u) {  // 检查是否从中断服务例程 (ISR) 调用
        OS_TRACE_MUTEX_DEL_EXIT(OS_ERR_DEL_ISR);  // 跟踪互斥锁删除退出
        *p_err = OS_ERR_DEL_ISR;  // 从中断服务例程 (ISR) 删除互斥锁非法
        return (0u);
    }
#endif

#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
    if (OSRunning != OS_STATE_OS_RUNNING) {  // 检查内核是否正在运行
        OS_TRACE_MUTEX_DEL_EXIT(OS_ERR_OS_NOT_RUNNING);  // 跟踪互斥锁删除退出
        *p_err = OS_ERR_OS_NOT_RUNNING;  // 内核尚未运行
        return (0u);
    }
#endif

#if (OS_CFG_ARG_CHK_EN > 0u)
    if (p_mutex == (OS_MUTEX *)0) {  // 检查互斥锁指针是否为空
        OS_TRACE_MUTEX_DEL_EXIT(OS_ERR_OBJ_PTR_NULL);  // 跟踪互斥锁删除退出
        *p_err = OS_ERR_OBJ_PTR_NULL;  // 互斥锁指针为空
        return (0u);
    }
#endif

#if (OS_CFG_OBJ_TYPE_CHK_EN > 0u)
    if (p_mutex->Type != OS_OBJ_TYPE_MUTEX) {  // 检查互斥锁是否已创建
        OS_TRACE_MUTEX_DEL_EXIT(OS_ERR_OBJ_TYPE);  // 跟踪互斥锁删除退出
        *p_err = OS_ERR_OBJ_TYPE;  // 互斥锁类型不匹配
        return (0u);
    }
#endif

    CPU_CRITICAL_ENTER();  // 进入临界区
    p_pend_list = &p_mutex->PendList;
    nbr_tasks   = 0u;

    switch (opt) {
        case OS_OPT_DEL_NO_PEND:  // 仅在没有任务等待时删除互斥锁
            if (p_pend_list->HeadPtr == (OS_TCB *)0) {
#if (OS_CFG_DBG_EN > 0u)
                OS_MutexDbgListRemove(p_mutex);  // 从调试列表中移除互斥锁
                OSMutexQty--;  // 减少互斥锁数量
#endif
                OS_TRACE_MUTEX_DEL(p_mutex);  // 跟踪互斥锁删除
                if (p_mutex->OwnerTCBPtr != (OS_TCB *)0) {  // 检查互斥锁是否属于某个任务
                    OS_MutexGrpRemove(p_mutex->OwnerTCBPtr, p_mutex);  // 从任务组中移除互斥锁
                }
                OS_MutexClr(p_mutex);  // 清除互斥锁
                CPU_CRITICAL_EXIT();  // 退出临界区
                *p_err = OS_ERR_NONE;  // 设置错误代码为无错误
            } else {
                CPU_CRITICAL_EXIT();  // 退出临界区
                *p_err = OS_ERR_TASK_WAITING;  // 有任务在等待互斥锁
            }
            break;

        case OS_OPT_DEL_ALWAYS:  // 总是删除互斥锁
#if (OS_CFG_TS_EN > 0u)
            ts = OS_TS_GET();  // 获取时间戳
#else
            ts = 0u;
#endif
            while (p_pend_list->HeadPtr != (OS_TCB *)0) {  // 从等待列表中移除所有任务
                p_tcb = p_pend_list->HeadPtr;
                OS_PendAbort(p_tcb, ts, OS_STATUS_PEND_DEL);  // 中止任务的等待
                nbr_tasks++;  // 增加已准备好的任务数量
            }
#if (OS_CFG_DBG_EN > 0u)
            OS_MutexDbgListRemove(p_mutex);  // 从调试列表中移除互斥锁
            OSMutexQty--;  // 减少互斥锁数量
#endif
            OS_TRACE_MUTEX_DEL(p_mutex);  // 跟踪互斥锁删除
            p_tcb_owner = p_mutex->OwnerTCBPtr;
            if (p_tcb_owner != (OS_TCB *)0) {  // 检查互斥锁是否属于某个任务
                OS_MutexGrpRemove(p_tcb_owner, p_mutex);  // 从任务组中移除互斥锁
            }

            if (p_tcb_owner != (OS_TCB *)0) {  // 检查是否需要更改任务的优先级
                if (p_tcb_owner->Prio != p_tcb_owner->BasePrio) {
                    prio_new = OS_MutexGrpPrioFindHighest(p_tcb_owner);  // 查找任务组中的最高优先级
                    prio_new = (prio_new > p_tcb_owner->BasePrio) ? p_tcb_owner->BasePrio : prio_new;
                    OS_TaskChangePrio(p_tcb_owner, prio_new);  // 更改任务的优先级
                    OS_TRACE_MUTEX_TASK_PRIO_DISINHERIT(p_tcb_owner, p_tcb_owner->Prio);  // 跟踪任务优先级继承解除
                }
            }

            OS_MutexClr(p_mutex);  // 清除互斥锁
            CPU_CRITICAL_EXIT();  // 退出临界区
            OSSched();  // 找到最高优先级的就绪任务
            *p_err = OS_ERR_NONE;  // 设置错误代码为无错误
            break;

        default:
            CPU_CRITICAL_EXIT();  // 退出临界区
            *p_err = OS_ERR_OPT_INVALID;  // 指定了无效的选项
            break;
    }

    OS_TRACE_MUTEX_DEL_EXIT(*p_err);  // 跟踪互斥锁删除退出
    return (nbr_tasks);  // 返回已准备好的任务数量
}
#endif


/*
************************************************************************************************************************
*                                                    等待互斥锁
*
* 描述: 此函数等待一个互斥锁。
*
* 参数: p_mutex       指向互斥锁的指针
*
*              timeout       是一个可选的超时周期(以时钟滴答为单位)。如果非零,您的任务将等待资源,最多等待由该参数指定的时间(以“滴答”为单位)。如果您指定 0,则您的任务将在指定的互斥锁上无限期等待,直到资源可用。
*
*              opt           确定用户是否希望在互斥锁可用时阻塞:
*
*                                OS_OPT_PEND_BLOCKING
*                                OS_OPT_PEND_NON_BLOCKING
*
*              p_ts          是一个指向变量的指针,该变量将接收互斥锁被发布、等待被中止或互斥锁被删除的时间戳。如果您传递一个空指针(即 (CPU_TS *)0),则不会获取时间戳。换句话说,传递空指针是有效的,表示您不需要时间戳。
*
*              p_err         是一个指向变量的指针,该变量将包含此函数返回的错误代码。
*
*                                OS_ERR_NONE               调用成功且您的任务拥有资源
*                                OS_ERR_MUTEX_OWNER        如果调用任务已经拥有互斥锁
*                                OS_ERR_MUTEX_OVF          互斥锁嵌套计数器溢出
*                                OS_ERR_OBJ_DEL            如果 'p_mutex' 被删除
*                                OS_ERR_OBJ_PTR_NULL       如果 'p_mutex' 是空指针
*                                OS_ERR_OBJ_TYPE           如果 'p_mutex' 不是指向互斥锁的指针
*                                OS_ERR_OPT_INVALID        如果未指定有效的选项
*                                OS_ERR_OS_NOT_RUNNING     如果 uC/OS-III 尚未运行
*                                OS_ERR_PEND_ABORT         如果等待被其他任务中止
*                                OS_ERR_PEND_ISR           如果您从中断服务例程 (ISR) 调用此函数并且结果会导致挂起
*                                OS_ERR_PEND_WOULD_BLOCK   如果您指定了非阻塞但互斥锁不可用
*                                OS_ERR_SCHED_LOCKED       如果您在调度器锁定时调用此函数
*                                OS_ERR_STATUS_INVALID     如果等待状态具有无效值
*                                OS_ERR_TIMEOUT            互斥锁在指定的超时时间内未收到
*                                OS_ERR_TICK_DISABLED      如果内核滴答被禁用且指定了超时时间
*
* 返回值: 无
*
* 注意: 此 API “不得” 从定时器回调函数中调用。
************************************************************************************************************************
*/

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();

#if (OS_CFG_TS_EN == 0u)
    (void)p_ts;                                                 // 防止编译器警告未使用 'ts'
#endif

#ifdef OS_SAFETY_CRITICAL
    if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return;
    }
#endif

    OS_TRACE_MUTEX_PEND_ENTER(p_mutex, timeout, opt, p_ts);

#if (OS_CFG_TICK_EN == 0u)
    if (timeout != 0u) {
        *p_err = OS_ERR_TICK_DISABLED;
        OS_TRACE_MUTEX_PEND_FAILED(p_mutex);
        OS_TRACE_MUTEX_PEND_EXIT(OS_ERR_TICK_DISABLED);
        return;
    }
#endif

#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
    if (OSIntNestingCtr > 0u) {                                 // 不允许从中断服务例程 (ISR) 调用
        OS_TRACE_MUTEX_PEND_FAILED(p_mutex);
        OS_TRACE_MUTEX_PEND_EXIT(OS_ERR_PEND_ISR);
        *p_err = OS_ERR_PEND_ISR;
        return;
    }
#endif

#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
    if (OSRunning != OS_STATE_OS_RUNNING) {                     // 内核是否正在运行?
        OS_TRACE_MUTEX_PEND_EXIT(OS_ERR_OS_NOT_RUNNING);
        *p_err = OS_ERR_OS_NOT_RUNNING;
        return;
    }
#endif

#if (OS_CFG_ARG_CHK_EN > 0u)
    if (p_mutex == (OS_MUTEX *)0) {                             // 验证参数
        OS_TRACE_MUTEX_PEND_FAILED(p_mutex);
        OS_TRACE_MUTEX_PEND_EXIT(OS_ERR_OBJ_PTR_NULL);
        *p_err = OS_ERR_OBJ_PTR_NULL;
        return;
    }
    switch (opt) {                                              // 验证 'opt'
        case OS_OPT_PEND_BLOCKING:
        case OS_OPT_PEND_NON_BLOCKING:
            break;

        default:
            OS_TRACE_MUTEX_PEND_FAILED(p_mutex);
            OS_TRACE_MUTEX_PEND_EXIT(OS_ERR_OPT_INVALID);
            *p_err = OS_ERR_OPT_INVALID;
            return;
    }
#endif

#if (OS_CFG_OBJ_TYPE_CHK_EN > 0u)
    if (p_mutex->Type != OS_OBJ_TYPE_MUTEX) {                   // 确保互斥锁已创建
        OS_TRACE_MUTEX_PEND_FAILED(p_mutex);
        OS_TRACE_MUTEX_PEND_EXIT(OS_ERR_OBJ_TYPE);
        *p_err = OS_ERR_OBJ_TYPE;
        return;
    }
#endif

    CPU_CRITICAL_ENTER();
    if (p_mutex->OwnerNestingCtr == 0u) {                       // 资源是否可用?
        p_mutex->OwnerTCBPtr     = OSTCBCurPtr;                 // 是,调用者可以继续
        p_mutex->OwnerNestingCtr = 1u;
#if (OS_CFG_TS_EN > 0u)
        if (p_ts != (CPU_TS *)0) {
            *p_ts = p_mutex->TS;
        }
#endif
        OS_MutexGrpAdd(OSTCBCurPtr, p_mutex);                   // 将互斥锁添加到所有者的组中
        CPU_CRITICAL_EXIT();
        OS_TRACE_MUTEX_PEND(p_mutex);
        OS_TRACE_MUTEX_PEND_EXIT(OS_ERR_NONE);
        *p_err = OS_ERR_NONE;
        return;
    }

    if (OSTCBCurPtr == p_mutex->OwnerTCBPtr) {                  // 当前任务是否已经是互斥锁的所有者?
        if (p_mutex->OwnerNestingCtr == (OS_NESTING_CTR)-1) {
            CPU_CRITICAL_EXIT();
            OS_TRACE_MUTEX_PEND_FAILED(p_mutex);
            OS_TRACE_MUTEX_PEND_EXIT(OS_ERR_MUTEX_OVF);
            *p_err = OS_ERR_MUTEX_OVF;
            return;
        }
        p_mutex->OwnerNestingCtr++;
#if (OS_CFG_TS_EN > 0u)
        if (p_ts != (CPU_TS *)0) {
            *p_ts = p_mutex->TS;
        }
#endif
        CPU_CRITICAL_EXIT();
        OS_TRACE_MUTEX_PEND_FAILED(p_mutex);
        OS_TRACE_MUTEX_PEND_EXIT(OS_ERR_MUTEX_OWNER);
        *p_err = OS_ERR_MUTEX_OWNER;                            // 表示当前任务已经拥有互斥锁
        return;
    }

    if ((opt & OS_OPT_PEND_NON_BLOCKING) != 0u) {               // 调用者是否希望在不可用时阻塞?
        CPU_CRITICAL_EXIT();
#if (OS_CFG_TS_EN > 0u)
        if (p_ts != (CPU_TS *)0) {
            *p_ts = 0u;
        }
#endif
        OS_TRACE_MUTEX_PEND_FAILED(p_mutex);
        OS_TRACE_MUTEX_PEND_EXIT(OS_ERR_PEND_WOULD_BLOCK);
        *p_err = OS_ERR_PEND_WOULD_BLOCK;                       // 否
        return;
    } else {
        if (OSSchedLockNestingCtr > 0u) {                       // 调度器锁定时不能等待
            CPU_CRITICAL_EXIT();
#if (OS_CFG_TS_EN > 0u)
            if (p_ts != (CPU_TS *)0) {
                *p_ts = 0u;
            }
#endif
            OS_TRACE_MUTEX_PEND_FAILED(p_mutex);
            OS_TRACE_MUTEX_PEND_EXIT(OS_ERR_SCHED_LOCKED);
            *p_err = OS_ERR_SCHED_LOCKED;
            return;
        }
    }

    p_tcb = p_mutex->OwnerTCBPtr;                               // 指向互斥锁所有者的 TCB
    if (p_tcb->Prio > OSTCBCurPtr->Prio) {                      // 查看互斥锁所有者是否比当前任务优先级低
        OS_TaskChangePrio(p_tcb, OSTCBCurPtr->Prio);
        OS_TRACE_MUTEX_TASK_PRIO_INHERIT(p_tcb, p_tcb->Prio);
    }

    OS_Pend((OS_PEND_OBJ *)((void *)p_mutex),                   // 任务在互斥锁上等待
             OSTCBCurPtr,
             OS_TASK_PEND_ON_MUTEX,
             timeout);

    CPU_CRITICAL_EXIT();
    OS_TRACE_MUTEX_PEND_BLOCK(p_mutex);
    OSSched();                                                  // 找到下一个最高优先级的任务准备运行

    CPU_CRITICAL_ENTER();
    switch (OSTCBCurPtr->PendStatus) {
        case OS_STATUS_PEND_OK:                                 // 获取了互斥锁
#if (OS_CFG_TS_EN > 0u)
            if (p_ts != (CPU_TS *)0) {
                *p_ts = OSTCBCurPtr->TS;
            }
#endif
            OS_TRACE_MUTEX_PEND(p_mutex);
            *p_err = OS_ERR_NONE;
            break;

        case OS_STATUS_PEND_ABORT:                              // 表示已中止
#if (OS_CFG_TS_EN > 0u)
            if (p_ts != (CPU_TS *)0) {
                *p_ts = OSTCBCurPtr->TS;
            }
#endif
            OS_TRACE_MUTEX_PEND_FAILED(p_mutex);
            *p_err = OS_ERR_PEND_ABORT;
            break;

        case OS_STATUS_PEND_TIMEOUT:                            // 表示在超时时间内未获取互斥锁
#if (OS_CFG_TS_EN > 0u)
            if (p_ts != (CPU_TS *)0) {
                *p_ts = 0u;
            }
#endif
            OS_TRACE_MUTEX_PEND_FAILED(p_mutex);
            *p_err = OS_ERR_TIMEOUT;
            break;

        case OS_STATUS_PEND_DEL:                                // 表示等待的对象已被删除
#if (OS_CFG_TS_EN > 0u)
            if (p_ts != (CPU_TS *)0) {
                *p_ts = OSTCBCurPtr->TS;
            }
#endif
            OS_TRACE_MUTEX_PEND_FAILED(p_mutex);
            *p_err = OS_ERR_OBJ_DEL;
            break;

        default:
            OS_TRACE_MUTEX_PEND_FAILED(p_mutex);
            *p_err = OS_ERR_STATUS_INVALID;
            break;
    }
    CPU_CRITICAL_EXIT();
    OS_TRACE_MUTEX_PEND_EXIT(*p_err);
}


/*
************************************************************************************************************************
*                                               中止对互斥锁的等待
*
* 描述: 此函数中止并准备好当前正在等待互斥锁的任务。此函数应用于故障中止对互斥锁的等待,而不是通过 OSMutexPost() 正常信号互斥锁。
*
* 参数:
*   p_mutex       - 指向互斥锁的指针
*
*   opt           - 确定执行的中止类型:
*
*                   OS_OPT_PEND_ABORT_1          - 中止单个任务(最高优先级任务)对互斥锁的等待
*                   OS_OPT_PEND_ABORT_ALL        - 中止所有等待互斥锁的任务
*                   OS_OPT_POST_NO_SCHED         - 不调用调度器
*
*   p_err         - 指向一个变量的指针,该变量将包含此函数返回的错误代码。
*
*                   OS_ERR_NONE               - 至少有一个等待互斥锁的任务被准备好并被告知等待已中止;检查返回值以获取等待互斥锁的任务数量
*                   OS_ERR_OBJ_PTR_NULL       - 如果 'p_mutex' 是空指针
*                   OS_ERR_OBJ_TYPE           - 如果 'p_mutex' 不是指向互斥锁的指针
*                   OS_ERR_OPT_INVALID        - 如果指定了无效的选项
*                   OS_ERR_OS_NOT_RUNNING     - 如果 uC/OS-III 尚未运行
*                   OS_ERR_PEND_ABORT_ISR     - 如果尝试从中断服务例程 (ISR) 调用此函数
*                   OS_ERR_PEND_ABORT_NONE    - 没有任务在等待
*
* 返回值:
*   == 0          - 如果没有任务在等待互斥锁,或者发生错误。
*   >  0          - 如果一个或多个等待互斥锁的任务现在已被准备好并被告知。
*
* 注意:
*   无
************************************************************************************************************************
*/

#if (OS_CFG_MUTEX_PEND_ABORT_EN > 0u)
OS_OBJ_QTY  OSMutexPendAbort (OS_MUTEX  *p_mutex,
                              OS_OPT     opt,
                              OS_ERR    *p_err)
{
    OS_PEND_LIST  *p_pend_list;
    OS_TCB        *p_tcb;
    OS_TCB        *p_tcb_owner;
    CPU_TS         ts;
    OS_OBJ_QTY     nbr_tasks;
    OS_PRIO        prio_new;
    CPU_SR_ALLOC();

    // 安全关键检查
    #ifdef OS_SAFETY_CRITICAL
    if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return ((OS_OBJ_QTY)0u);
    }
    #endif

    // 检查是否从中断服务例程 (ISR) 调用
    #if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
    if (OSIntNestingCtr > 0u) {                                 // 不允许从中断服务例程 (ISR) 中调用 Pend Abort
       *p_err =  OS_ERR_PEND_ABORT_ISR;
        return (0u);
    }
    #endif

    // 检查内核是否正在运行
    #if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
    if (OSRunning != OS_STATE_OS_RUNNING) {                     // 内核是否正在运行?
       *p_err = OS_ERR_OS_NOT_RUNNING;
        return (0u);
    }
    #endif

    // 参数检查
    #if (OS_CFG_ARG_CHK_EN > 0u)
    if (p_mutex == (OS_MUTEX *)0) {                             // 验证 'p_mutex'
       *p_err =  OS_ERR_OBJ_PTR_NULL;
        return (0u);
    }
    switch (opt) {                                              // 验证 'opt'
        case OS_OPT_PEND_ABORT_1:
        case OS_OPT_PEND_ABORT_ALL:
        case OS_OPT_PEND_ABORT_1   | OS_OPT_POST_NO_SCHED:
        case OS_OPT_PEND_ABORT_ALL | OS_OPT_POST_NO_SCHED:
             break;

        default:
            *p_err =  OS_ERR_OPT_INVALID;
             return (0u);
    }
    #endif

    // 对象类型检查
    #if (OS_CFG_OBJ_TYPE_CHK_EN > 0u)
    if (p_mutex->Type != OS_OBJ_TYPE_MUTEX) {                   // 确保互斥锁已创建
       *p_err =  OS_ERR_OBJ_TYPE;
        return (0u);
    }
    #endif

    // 进入临界区
    CPU_CRITICAL_ENTER();
    p_pend_list = &p_mutex->PendList;
    if (p_pend_list->HeadPtr == (OS_TCB *)0) {                  // 有任何任务在等待互斥锁吗?
        CPU_CRITICAL_EXIT();                                    // 没有
       *p_err =  OS_ERR_PEND_ABORT_NONE;
        return (0u);
    }

    nbr_tasks = 0u;
    #if (OS_CFG_TS_EN > 0u)
    ts        = OS_TS_GET();                                    // 获取本地时间戳,以便所有任务获得相同的时间
    #else
    ts        = 0u;
    #endif

    // 处理等待互斥锁的任务
    while (p_pend_list->HeadPtr != (OS_TCB *)0) {
        p_tcb = p_pend_list->HeadPtr;

        OS_PendAbort(p_tcb,
                     ts,
                     OS_STATUS_PEND_ABORT);
        p_tcb_owner = p_mutex->OwnerTCBPtr;
        prio_new    = p_tcb_owner->Prio;
        if ((p_tcb_owner->Prio != p_tcb_owner->BasePrio) &&
            (p_tcb_owner->Prio == p_tcb->Prio)) {               // 拥有者是否继承了优先级?
            prio_new = OS_MutexGrpPrioFindHighest(p_tcb_owner);
            prio_new = (prio_new > p_tcb_owner->BasePrio) ? p_tcb_owner->BasePrio : prio_new;
        }

        if(prio_new != p_tcb_owner->Prio) {
            OS_TaskChangePrio(p_tcb_owner, prio_new);
            OS_TRACE_MUTEX_TASK_PRIO_DISINHERIT(p_tcb_owner, p_tcb_owner->Prio);
        }

        nbr_tasks++;
        if (opt != OS_OPT_PEND_ABORT_ALL) {                     // 是否中止所有等待的任务?
            break;                                              // 否
        }
    }
    CPU_CRITICAL_EXIT();

    // 调用调度器
    if ((opt & OS_OPT_POST_NO_SCHED) == 0u) {
        OSSched();                                              // 运行调度器
    }

   *p_err = OS_ERR_NONE;
    return (nbr_tasks);
}
#endif


/*
************************************************************************************************************************
*                                                   信号量互斥锁
*
* 描述: 此函数用于信号互斥锁。
*
* 参数:
*   p_mutex       - 指向互斥锁的指针
*
*   opt           - 可以指定的选项,以改变信号的行为。选择包括:
*
*                   OS_OPT_POST_NONE        - 没有特殊选项被选中
*                   OS_OPT_POST_NO_SCHED    - 如果不希望在信号后调用调度器
*
*   p_err         - 指向一个变量的指针,该变量将包含此函数返回的错误代码。
*
*                   OS_ERR_NONE               - 调用成功,互斥锁已被信号
*                   OS_ERR_MUTEX_NESTING      - 互斥锁的所有者嵌套使用了互斥锁
*                   OS_ERR_MUTEX_NOT_OWNER    - 发送信号的任务不是互斥锁的所有者
*                   OS_ERR_OBJ_PTR_NULL       - 如果 'p_mutex' 是空指针
*                   OS_ERR_OBJ_TYPE           - 如果 'p_mutex' 不是指向互斥锁的指针
*                   OS_ERR_OPT_INVALID        - 如果指定了无效的选项
*                   OS_ERR_OS_NOT_RUNNING     - 如果 uC/OS-III 尚未运行
*                   OS_ERR_POST_ISR           - 如果尝试从中断服务例程 (ISR) 发送信号
*
* 返回值:
*   无
*
* 注意:
*   无
************************************************************************************************************************
*/

void  OSMutexPost (OS_MUTEX  *p_mutex,
                   OS_OPT     opt,
                   OS_ERR    *p_err)
{
    OS_PEND_LIST  *p_pend_list;
    OS_TCB        *p_tcb;
    CPU_TS         ts;
    OS_PRIO        prio_new;
    CPU_SR_ALLOC();

    // 安全关键检查
    #ifdef OS_SAFETY_CRITICAL
    if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return;
    }
    #endif

    // 追踪信号互斥锁进入
    OS_TRACE_MUTEX_POST_ENTER(p_mutex, opt);

    // 检查是否从中断服务例程 (ISR) 调用
    #if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
    if (OSIntNestingCtr > 0u) {                                 // 不允许从中断服务例程 (ISR) 调用
        OS_TRACE_MUTEX_POST_FAILED(p_mutex);
        OS_TRACE_MUTEX_POST_EXIT(OS_ERR_POST_ISR);
       *p_err = OS_ERR_POST_ISR;
        return;
    }
    #endif

    // 检查内核是否正在运行
    #if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
    if (OSRunning != OS_STATE_OS_RUNNING) {                     // 内核是否正在运行?
        OS_TRACE_MUTEX_POST_EXIT(OS_ERR_OS_NOT_RUNNING);
       *p_err = OS_ERR_OS_NOT_RUNNING;
        return;
    }
    #endif

    // 参数检查
    #if (OS_CFG_ARG_CHK_EN > 0u)
    if (p_mutex == (OS_MUTEX *)0) {                             // 验证 'p_mutex'
        OS_TRACE_MUTEX_POST_FAILED(p_mutex);
        OS_TRACE_MUTEX_POST_EXIT(OS_ERR_OBJ_PTR_NULL);
       *p_err = OS_ERR_OBJ_PTR_NULL;
        return;
    }
    switch (opt) {                                              // 验证 'opt'
        case OS_OPT_POST_NONE:
        case OS_OPT_POST_NO_SCHED:
             break;

        default:
             OS_TRACE_MUTEX_POST_FAILED(p_mutex);
             OS_TRACE_MUTEX_POST_EXIT(OS_ERR_OPT_INVALID);
            *p_err =  OS_ERR_OPT_INVALID;
             return;
    }
    #endif

    // 对象类型检查
    #if (OS_CFG_OBJ_TYPE_CHK_EN > 0u)
    if (p_mutex->Type != OS_OBJ_TYPE_MUTEX) {                   // 确保互斥锁已创建
        OS_TRACE_MUTEX_POST_FAILED(p_mutex);
        OS_TRACE_MUTEX_POST_EXIT(OS_ERR_OBJ_TYPE);
       *p_err = OS_ERR_OBJ_TYPE;
        return;
    }
    #endif

    // 进入临界区
    CPU_CRITICAL_ENTER();
    if (OSTCBCurPtr != p_mutex->OwnerTCBPtr) {                  // 确保互斥锁的所有者正在释放互斥锁
        CPU_CRITICAL_EXIT();
        OS_TRACE_MUTEX_POST_FAILED(p_mutex);
        OS_TRACE_MUTEX_POST_EXIT(OS_ERR_MUTEX_NOT_OWNER);
       *p_err = OS_ERR_MUTEX_NOT_OWNER;
        return;
    }

    // 追踪信号互斥锁
    OS_TRACE_MUTEX_POST(p_mutex);

    // 获取时间戳
    #if (OS_CFG_TS_EN > 0u)
    ts          = OS_TS_GET();                                  // 获取时间戳
    p_mutex->TS = ts;
    #else
    ts          = 0u;
    #endif

    p_mutex->OwnerNestingCtr--;                                 // 减少所有者的嵌套计数
    if (p_mutex->OwnerNestingCtr > 0u) {                        // 是否已完成所有嵌套?
        CPU_CRITICAL_EXIT();                                     // 否
        OS_TRACE_MUTEX_POST_EXIT(OS_ERR_MUTEX_NESTING);
       *p_err = OS_ERR_MUTEX_NESTING;
        return;
    }

    // 从所有者的组中移除互斥锁
    OS_MutexGrpRemove(OSTCBCurPtr, p_mutex);

    // 获取等待互斥锁的任务列表
    p_pend_list = &p_mutex->PendList;
    if (p_pend_list->HeadPtr == (OS_TCB *)0) {                  // 有任何任务在等待互斥锁吗?
        p_mutex->OwnerTCBPtr     = (OS_TCB *)0;                 // 没有
        p_mutex->OwnerNestingCtr =           0u;
        CPU_CRITICAL_EXIT();
        OS_TRACE_MUTEX_POST_EXIT(OS_ERR_NONE);
       *p_err = OS_ERR_NONE;
        return;
    }

    // 确定所有者是否继承了优先级
    if (OSTCBCurPtr->Prio != OSTCBCurPtr->BasePrio) {           // 所有者是否继承了优先级?
        prio_new = OS_MutexGrpPrioFindHighest(OSTCBCurPtr);     // 是,找到最高优先级的等待任务
        prio_new = (prio_new > OSTCBCurPtr->BasePrio) ? OSTCBCurPtr->BasePrio : prio_new;
        if (prio_new > OSTCBCurPtr->Prio) {
            OS_RdyListRemove(OSTCBCurPtr);
            OSTCBCurPtr->Prio = prio_new;                       // 降低所有者的优先级回到其原始优先级
            OS_TRACE_MUTEX_TASK_PRIO_DISINHERIT(OSTCBCurPtr, prio_new);
            OS_PrioInsert(prio_new);
            OS_RdyListInsertTail(OSTCBCurPtr);                  // 在新的优先级下插入所有者到就绪列表
            OSPrioCur         = prio_new;
        }
    }

    // 从等待列表头部获取 TCB
    p_tcb                    = p_pend_list->HeadPtr;
    p_mutex->OwnerTCBPtr     = p_tcb;                           // 将互斥锁交给新所有者
    p_mutex->OwnerNestingCtr = 1u;
    OS_MutexGrpAdd(p_tcb, p_mutex);

    // 信号互斥锁
    OS_Post((OS_PEND_OBJ *)((void *)p_mutex),
                           p_tcb,
                           (void *)0,
                           0u,
                           ts);

    // 退出临界区
    CPU_CRITICAL_EXIT();

    // 调用调度器
    if ((opt & OS_OPT_POST_NO_SCHED) == 0u) {
        OSSched();                                              // 运行调度器
    }

    // 追踪信号互斥锁退出
    OS_TRACE_MUTEX_POST_EXIT(OS_ERR_NONE);
   *p_err = OS_ERR_NONE;
}


/*
************************************************************************************************************************
*                                            清除互斥锁的内容
*
* 描述: 此函数由 OSMutexDel() 调用,用于清除互斥锁的内容
*
* 参数:
*   p_mutex      - 指向要清除的互斥锁的指针
*   -------
*
* 返回值:
*   无
*
* 注意:
*   此函数是 uC/OS-III 的内部函数,您的应用程序不应调用它。
************************************************************************************************************************
*/

void  OS_MutexClr (OS_MUTEX  *p_mutex)
{
#if (OS_OBJ_TYPE_REQ > 0u)
    p_mutex->Type              =  OS_OBJ_TYPE_NONE;             // 标记数据结构为 NONE
#endif
#if (OS_CFG_DBG_EN > 0u)
    p_mutex->NamePtr           = (CPU_CHAR *)((void *)"?MUTEX"); // 设置调试名称
#endif
    p_mutex->MutexGrpNextPtr   = (OS_MUTEX *)0;                 // 初始化互斥锁组链表指针
    p_mutex->OwnerTCBPtr       = (OS_TCB   *)0;                 // 初始化所有者任务控制块指针
    p_mutex->OwnerNestingCtr   =             0u;                // 初始化所有者嵌套计数
#if (OS_CFG_TS_EN > 0u)
    p_mutex->TS                =             0u;               // 初始化时间戳
#endif
    OS_PendListInit(&p_mutex->PendList);                        // 初始化等待列表
}


/*
************************************************************************************************************************
*                                          添加/移除互斥锁到/从调试列表
*
* 描述: 这些函数由 uC/OS-III 调用,用于将互斥锁添加到或从调试列表中移除。
*
* 参数:
*   p_mutex     - 指向要添加或移除的互斥锁的指针
*
* 返回值:
*   无
*
* 注意:
*   这些函数是 uC/OS-III 的内部函数,您的应用程序不应调用它们。
************************************************************************************************************************
*/

#if (OS_CFG_DBG_EN > 0u)
void  OS_MutexDbgListAdd (OS_MUTEX  *p_mutex)
{
    p_mutex->DbgNamePtr               = (CPU_CHAR *)((void *)" ");
    p_mutex->DbgPrevPtr               = (OS_MUTEX *)0;
    if (OSMutexDbgListPtr == (OS_MUTEX *)0) {
        p_mutex->DbgNextPtr           = (OS_MUTEX *)0;
    } else {
        p_mutex->DbgNextPtr           =  OSMutexDbgListPtr;
        OSMutexDbgListPtr->DbgPrevPtr =  p_mutex;
    }
    OSMutexDbgListPtr                 =  p_mutex;
}


void  OS_MutexDbgListRemove (OS_MUTEX  *p_mutex)
{
    OS_MUTEX  *p_mutex_next;
    OS_MUTEX  *p_mutex_prev;


    p_mutex_prev = p_mutex->DbgPrevPtr;
    p_mutex_next = p_mutex->DbgNextPtr;

    if (p_mutex_prev == (OS_MUTEX *)0) {
        OSMutexDbgListPtr = p_mutex_next;
        if (p_mutex_next != (OS_MUTEX *)0) {
            p_mutex_next->DbgPrevPtr = (OS_MUTEX *)0;
        }
        p_mutex->DbgNextPtr = (OS_MUTEX *)0;

    } else if (p_mutex_next == (OS_MUTEX *)0) {
        p_mutex_prev->DbgNextPtr = (OS_MUTEX *)0;
        p_mutex->DbgPrevPtr      = (OS_MUTEX *)0;

    } else {
        p_mutex_prev->DbgNextPtr =  p_mutex_next;
        p_mutex_next->DbgPrevPtr =  p_mutex_prev;
        p_mutex->DbgNextPtr      = (OS_MUTEX *)0;
        p_mutex->DbgPrevPtr      = (OS_MUTEX *)0;
    }
}
#endif


/*
************************************************************************************************************************
*                                               互斥锁组添加
*
* 描述: 此函数由内核调用,用于将互斥锁添加到任务的互斥锁组中。
*
* 参数:
*   p_tcb        - 指向要赋予互斥锁的任务的 TCB(任务控制块)的指针。
*   p_mutex      - 指向要添加到组中的互斥锁的指针。
*
* 返回值:
*   无
*
* 注意:
*   1) 此函数是 uC/OS-III 的内部函数,您的应用程序不得调用它。
************************************************************************************************************************
*/

void  OS_MutexGrpAdd (OS_TCB  *p_tcb, OS_MUTEX  *p_mutex)
{
    p_mutex->MutexGrpNextPtr = p_tcb->MutexGrpHeadPtr;      /* The mutex grp is not sorted add to head of list.       */
    p_tcb->MutexGrpHeadPtr   = p_mutex;
}


/*
************************************************************************************************************************
*                                              互斥锁组移除
*
* 描述: 此函数由内核调用,用于从任务的互斥锁组中移除互斥锁。
*
* 参数:
*   p_tcb        - 指向要从中移除互斥锁的任务的 TCB(任务控制块)的指针。
*   p_mutex      - 指向要从组中移除的互斥锁的指针。
*
* 返回值:
*   无
*
* 注意:
*   1) 此函数是 uC/OS-III 的内部函数,您的应用程序不得调用它。
************************************************************************************************************************
*/

void  OS_MutexGrpRemove (OS_TCB  *p_tcb, OS_MUTEX  *p_mutex)
{
    // 定义一个指向互斥量指针的指针,用于遍历互斥量列表
    OS_MUTEX  **pp_mutex;

    // 初始化遍历指针,使其指向TCB中互斥量组的头部指针
    pp_mutex = &p_tcb->MutexGrpHeadPtr;

    // 遍历互斥量列表,直到找到与p_mutex匹配的互斥量
    while(*pp_mutex != p_mutex) {
        // 移动遍历指针到下一个互斥量
        pp_mutex = &(*pp_mutex)->MutexGrpNextPtr;
    }

    // 从列表中移除找到的互斥量,通过更新前一个互斥量的指针来跳过当前互斥量
    *pp_mutex = (*pp_mutex)->MutexGrpNextPtr;
}


/*
************************************************************************************************************************
*                                              查找最高优先级等待的互斥量
*
* 描述: 此函数由内核调用,用于从一组互斥量中查找最高优先级的等待任务。
*
* 参数: p_tcb        是指向要处理的任务的TCB的指针。
*
* 返回值: 最高优先级的等待任务,如果没有找到则返回 OS_CFG_PRIO_MAX - 1u。
*
* 注意: 1) 此函数是 uC/OS-III 的内部函数,您的应用程序必须不得调用它。
************************************************************************************************************************
*/

OS_PRIO  OS_MutexGrpPrioFindHighest (OS_TCB  *p_tcb)
{
    // 用于遍历互斥组的指针
    OS_MUTEX  **pp_mutex;
    // 初始化最高优先级为次高优先级
    OS_PRIO     highest_prio;
    // 临时存储当前遍历到的优先级
    OS_PRIO     prio;
    // 指向互斥组挂起列表的头指针
    OS_TCB     *p_head;

    // 初始化最高优先级为系统允许的最高优先级减一
    highest_prio = (OS_PRIO)(OS_CFG_PRIO_MAX - 1u);
    // 从任务控制块的互斥组头指针开始遍历
    pp_mutex = &p_tcb->MutexGrpHeadPtr;

    // 遍历互斥组链表,直到找到优先级最高的互斥组
    while(*pp_mutex != (OS_MUTEX *)0) {
        // 获取当前互斥组挂起列表的头指针
        p_head = (*pp_mutex)->PendList.HeadPtr;
        // 如果挂起列表不为空,则进一步检查优先级
        if (p_head != (OS_TCB *)0) {
            // 获取挂起列表头任务的优先级
            prio = p_head->Prio;
            // 如果当前优先级低于已知的最高优先级,则更新最高优先级
            if(prio < highest_prio) {
                highest_prio = prio;
            }
        }
        // 移动到下一个互斥组指针
        pp_mutex = &(*pp_mutex)->MutexGrpNextPtr;
    }

    // 返回找到的最高优先级
    return (highest_prio);
}


/*
************************************************************************************************************************
*                                               互斥组全部释放
*
* 描述: 该函数由内核调用,用于释放(解除锁定)一个组中的所有互斥量。通常在删除任务时使用。
*
* 参数: p_tcb        是指向要处理的任务的TCB的指针。
*
* 返回: 无。
*
* 注意: 1) 该函数是uC/OS-III的内部函数,您的应用程序不得调用它。
************************************************************************************************************************
*/

void OS_MutexGrpPostAll(OS_TCB *p_tcb)
{
    OS_MUTEX      *p_mutex;
    OS_MUTEX      *p_mutex_next;
    CPU_TS         ts;
    OS_PEND_LIST  *p_pend_list;
    OS_TCB        *p_tcb_new;

    // 获取任务的互斥量组头指针
    p_mutex = p_tcb->MutexGrpHeadPtr;

    // 遍历互斥量组中的所有互斥量
    while (p_mutex != (OS_MUTEX *)0) {

        // 跟踪互斥量的释放操作
        OS_TRACE_MUTEX_POST(p_mutex);

        // 获取下一个互斥量
        p_mutex_next = p_mutex->MutexGrpNextPtr;

#if (OS_CFG_TS_EN > 0u)
        // 获取当前时间戳
        ts = OS_TS_GET();
        p_mutex->TS = ts;
#else
        ts = 0u;
#endif

        // 从所有者组中移除互斥量
        OS_MutexGrpRemove(p_tcb, p_mutex);

        // 获取等待队列
        p_pend_list = &p_mutex->PendList;

        // 检查是否有任务在等待该互斥量
        if (p_pend_list->HeadPtr == (OS_TCB *)0) {
            // 没有任务等待,重置互斥量的所有者信息
            p_mutex->OwnerNestingCtr = 0u;
            p_mutex->OwnerTCBPtr = (OS_TCB *)0;
        } else {
            // 获取等待队列头部的任务
            p_tcb_new = p_pend_list->HeadPtr;
            // 将互斥量分配给新的所有者
            p_mutex->OwnerTCBPtr = p_tcb_new;
            p_mutex->OwnerNestingCtr = 1u;
            // 将互斥量添加到新所有者的互斥量组中
            OS_MutexGrpAdd(p_tcb_new, p_mutex);

            // 释放互斥量
            OS_Post((OS_PEND_OBJ *)((void *)p_mutex),
                               p_tcb_new,
                               (void *)0,
                               0u,
                               ts);
        }

        // 继续处理下一个互斥量
        p_mutex = p_mutex_next;
    }
}

#endif /* OS_CFG_MUTEX_EN */

标签:ERR,UcOs,0u,III,互斥,源码,mutex,MUTEX,OS
From: https://www.cnblogs.com/lanlincmos/p/18518322

相关文章