Exemplo n.º 1
0
/*********************************************************************************************************
** 函数名称: API_ThreadCancel
** 功能描述: 取消一个指定的线程
** 输 入  : ulId                          线程句柄
** 输 出  : ERROR_NONE or ESRCH
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
ULONG  API_ThreadCancel (LW_OBJECT_HANDLE  *pulId)
{
             INTREG                iregInterLevel;
    REGISTER LW_OBJECT_HANDLE      ulId;
    REGISTER UINT16                usIndex;
    REGISTER PLW_CLASS_TCB         ptcbDel;

    ulId = *pulId;
    
    usIndex = _ObjectGetIndex(ulId);
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) {                        /*  检查 ID 类型有效性          */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    
    if (_Thread_Index_Invalid(usIndex)) {                               /*  检查线程有效性              */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_THREAD_NULL);
        return  (ERROR_THREAD_NULL);
    }
#endif

    __KERNEL_ENTER();                                                   /*  进入内核                    */
    if (_Thread_Invalid(usIndex)) {
        __KERNEL_EXIT();                                                /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_THREAD_NULL);
        return  (ERROR_THREAD_NULL);
    }
    
    iregInterLevel = KN_INT_DISABLE();
    
    ptcbDel = _K_ptcbTCBIdTable[usIndex];
    if (ptcbDel->TCB_iCancelState == LW_THREAD_CANCEL_ENABLE) {         /*  允许 CANCEL                 */
        if (ptcbDel->TCB_iCancelType == LW_THREAD_CANCEL_DEFERRED) {    /*  延迟 CANCEL                 */
            ptcbDel->TCB_bCancelRequest = LW_TRUE;                      /*  目标线程进入下一个 TEST 点  */
            __KERNEL_EXIT_IRQ(iregInterLevel);                          /*  退出内核并打开中断          */
        
        } else {                                                        /*  异步取消                    */
            __KERNEL_EXIT_IRQ(iregInterLevel);                          /*  退出内核并打开中断          */
#if LW_CFG_SIGNAL_EN > 0
            kill(ulId, SIGCANCEL);                                      /*  立即发送取消信号            */
#else
            return  (API_ThreadDelete(ulId, LW_NULL));
#endif                                                                  /*  LW_CFG_SIGNAL_EN > 0        */
        }
    
    } else {
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核并打开中断          */
        _ErrorHandle(ERROR_THREAD_DISCANCEL);                           /*  不允许 CACNCEL              */
        return  (ERROR_THREAD_DISCANCEL);
    }
    
    return  (ERROR_NONE);
}
Exemplo n.º 2
0
VOID  _WatchDogTick (VOID)
{
             INTREG                 iregInterLevel;
    REGISTER PLW_CLASS_TCB          ptcb;
             PLW_CLASS_WAKEUP_NODE  pwun;
             ULONG                  ulCounter = 1;
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核同时关闭中断        */
    
    __WAKEUP_PASS_FIRST(&_K_wuWatchDog, pwun, ulCounter);
    
    ptcb = _LIST_ENTRY(pwun, LW_CLASS_TCB, TCB_wunWatchDog);
    
    __DEL_FROM_WATCHDOG_LINE(ptcb);                                     /*  从扫描链表中删除            */
    
    KN_INT_ENABLE(iregInterLevel);
    
    bspWdTimerHook(ptcb->TCB_ulId);
    __LW_WATCHDOG_TIMER_HOOK(ptcb->TCB_ulId);                           /*  执行回调函数                */
    
    iregInterLevel = KN_INT_DISABLE();
    
    __WAKEUP_PASS_SECOND();
    
    KN_INT_ENABLE(iregInterLevel);                                      /*  这里允许响应中断            */
    
    iregInterLevel = KN_INT_DISABLE();
    
    __WAKEUP_PASS_END();
    
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核同时打开中断        */
}
Exemplo n.º 3
0
/*********************************************************************************************************
** 函数名称: pause
** 功能描述: 等待一个信号的到来
** 输 入  : NONE
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
INT  pause (VOID)
{
             INTREG         iregInterLevel;
             PLW_CLASS_TCB  ptcbCur;
    REGISTER PLW_CLASS_PCB  ppcb;
    
    __THREAD_CANCEL_POINT();                                            /*  测试取消点                  */
    
    LW_TCB_GET_CUR_SAFE(ptcbCur);                                       /*  当前任务控制块              */

    MONITOR_EVT_LONG1(MONITOR_EVENT_ID_SIGNAL, MONITOR_EVENT_SIGNAL_PAUSE, 
                      ptcbCur->TCB_ulId, LW_NULL);
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核                    */
    
    ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_SIGNAL;                   /*  等待信号                    */
    ppcb = _GetPcb(ptcbCur);
    __DEL_FROM_READY_RING(ptcbCur, ppcb);                               /*  从就绪表中删除              */
    
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核                    */
    
    _ErrorHandle(EINTR);
    return  (PX_ERROR);
}
Exemplo n.º 4
0
/*********************************************************************************************************
** 函数名称: API_ThreadSetCancelType
** 功能描述: 设置当前线程被动取消时的动作, 
**           可以为 PTHREAD_CANCEL_ASYNCHRONOUS or PTHREAD_CANCEL_DEFERRED
** 输 入  : 
**           iNewType           新类型
**           piOldType          先早类型
** 输 出  : ERRNO
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
INT  API_ThreadSetCancelType (INT  iNewType, INT  *piOldType)
{
    INTREG                iregInterLevel;
    PLW_CLASS_TCB         ptcbCur;

    if (iNewType != LW_THREAD_CANCEL_ASYNCHRONOUS &&
        iNewType != LW_THREAD_CANCEL_DEFERRED) {
        _ErrorHandle(EINVAL);
        return  (EINVAL);
    }
    
    LW_TCB_GET_CUR_SAFE(ptcbCur);                                       /*  当前任务控制块              */
    
    if (ptcbCur->TCB_iCancelState == LW_THREAD_CANCEL_ENABLE   &&
        ptcbCur->TCB_iCancelType  == LW_THREAD_CANCEL_DEFERRED &&
        (ptcbCur->TCB_bCancelRequest)) {                                /*  需要删除                    */
        LW_OBJECT_HANDLE    ulId = ptcbCur->TCB_ulId;
        
#if LW_CFG_THREAD_DEL_EN > 0
        API_ThreadDelete(&ulId, LW_THREAD_CANCELED);
#endif                                                                  /*  LW_CFG_THREAD_DEL_EN > 0    */
        return  (ERROR_NONE);
    }
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核同时关闭中断        */
    if (piOldType) {
        *piOldType = ptcbCur->TCB_iCancelType;
    }
    ptcbCur->TCB_iCancelType = iNewType;
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核同时打开中断        */
    
    return  (ERROR_NONE);
}
Exemplo n.º 5
0
LW_API  
ULONG  API_SemaphoreCStatus (LW_OBJECT_HANDLE   ulId,
                             ULONG             *pulCounter,
                             ULONG             *pulOption,
                             ULONG             *pulThreadBlockNum)
{
             INTREG                iregInterLevel;
    REGISTER UINT16                usIndex;
    REGISTER PLW_CLASS_EVENT       pevent;
    
    usIndex = _ObjectGetIndex(ulId);
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!_ObjectClassOK(ulId, _OBJECT_SEM_C)) {                         /*  类型是否正确                */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "semaphore handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    if (_Event_Index_Invalid(usIndex)) {                                /*  下标是否正正确              */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "semaphore handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
#endif
    pevent = &_K_eventBuffer[usIndex];
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核                    */
    if (_Event_Type_Invalid(usIndex, LW_TYPE_EVENT_SEMC)) {
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "semaphore handle invalidate.\r\n");
        _ErrorHandle(ERROR_EVENT_TYPE);
        return  (ERROR_EVENT_TYPE);
    }
    
    if (pulCounter) {
        *pulCounter = pevent->EVENT_ulCounter;
    }
    if (pulOption) {
        *pulOption  = pevent->EVENT_ulOption;
    }
    if (pulThreadBlockNum) {
        *pulThreadBlockNum = _EventWaitNum(pevent);
    }
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核                    */
    
    return  (ERROR_NONE);
}
Exemplo n.º 6
0
LW_API  
ULONG  API_MsgQueueClear (LW_OBJECT_HANDLE  ulId)
{
             INTREG                iregInterLevel;
    REGISTER UINT16                usIndex;
    REGISTER PLW_CLASS_EVENT       pevent;
    REGISTER PLW_CLASS_MSGQUEUE    pmsgqueue;
    
    usIndex = _ObjectGetIndex(ulId);
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!_ObjectClassOK(ulId, _OBJECT_MSGQUEUE)) {                      /*  类型是否正确                */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "msgqueue handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    if (_Event_Index_Invalid(usIndex)) {                                /*  下标是否正正确              */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "msgqueue handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
#endif
    pevent = &_K_eventBuffer[usIndex];
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核                    */
    if (_Event_Type_Invalid(usIndex, LW_TYPE_EVENT_MSGQUEUE)) {
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "msgqueue handle invalidate.\r\n");
        _ErrorHandle(ERROR_MSGQUEUE_TYPE);
        return  (ERROR_MSGQUEUE_TYPE);
    }
    
    pmsgqueue = (PLW_CLASS_MSGQUEUE)pevent->EVENT_pvPtr;
    
    pevent->EVENT_ulCounter = 0ul;
    
    pmsgqueue->MSGQUEUE_pucInputPtr  = pmsgqueue->MSGQUEUE_pucBufferLowAddr;
    pmsgqueue->MSGQUEUE_pucOutputPtr = pmsgqueue->MSGQUEUE_pucBufferLowAddr;
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核                    */
        
    MONITOR_EVT_LONG1(MONITOR_EVENT_ID_MSGQ, MONITOR_EVENT_MSGQ_CLEAR, ulId, LW_NULL);
    
    return  (ERROR_NONE);
}
Exemplo n.º 7
0
LW_API  
ULONG  API_EventSetStatus (LW_OBJECT_HANDLE  ulId, 
                           ULONG            *pulEvent,
                           ULONG            *pulOption)
{
             INTREG                    iregInterLevel;
    REGISTER UINT16                    usIndex;
    REGISTER PLW_CLASS_EVENTSET        pes;
    
    usIndex = _ObjectGetIndex(ulId);
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!_ObjectClassOK(ulId, _OBJECT_EVENT_SET)) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "eventset handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    if (_EventSet_Index_Invalid(usIndex)) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "eventset handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
#endif
    pes = &_K_esBuffer[usIndex];
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核                    */
    if (_EventSet_Type_Invalid(usIndex, LW_TYPE_EVENT_EVENTSET)) {
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "eventset handle invalidate.\r\n");
        _ErrorHandle(ERROR_EVENTSET_TYPE);
        return  (ERROR_EVENTSET_TYPE);
    }
    
    if (pulEvent) {
        *pulEvent = pes->EVENTSET_ulEventSets;
    }
    
    if (pulOption) {
        *pulOption = 0ul;
    }
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核                    */
    
    return  (ERROR_NONE);
}
Exemplo n.º 8
0
/*********************************************************************************************************
** 函数名称: API_KernelReboot
** 功能描述: 内核重新启动函数
** 输 入  : iRebootType        重启类型 
                                LW_REBOOT_FORCE
                                LW_REBOOT_WARM
                                LW_REBOOT_COLD
                                LW_REBOOT_SHUTDOWN
                                LW_REBOOT_POWEROFF
**           ulStartAddress     启动地址
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
VOID   API_KernelRebootEx (INT  iRebootType, addr_t  ulStartAddress)
{
    INTREG  iregInterLevel;
    ULONG   ulI;
    
    if (iRebootType == LW_REBOOT_FORCE) {
        archReboot(iRebootType, ulStartAddress);                        /*  调用体系架构重启操作        */
        _BugHandle(LW_TRUE, LW_TRUE, "kernel reboot error!\r\n");       /*  不会运行到这里              */
    }

    if (LW_CPU_GET_CUR_NESTING() || (API_ThreadIdSelf() != API_KernelGetExc())) {
        _excJobAdd(API_KernelRebootEx, (PVOID)iRebootType, (PVOID)ulStartAddress, 0, 0, 0, 0);
        return;
    }

    _DebugHandle(__LOGMESSAGE_LEVEL, "kernel rebooting...\r\n");
    
    _K_ulRebootStartAddress = ulStartAddress;                           /*  记录局部变量, 防止 XXX      */
    
#if LW_CFG_SMP_EN > 0
    if (LW_NCPUS > 1) {
        __makeOtherDown();                                              /*  将其他 CPU 设置为 idle 模式 */
    }
#endif                                                                  /*  LW_CFG_SMP_EN               */
    
    if (iRebootType != LW_REBOOT_FORCE) {
        __LW_KERNEL_REBOOT_HOOK(iRebootType);                           /*  调用回调函数                */
        _cppRtUninit();                                                 /*  卸载 C++ 运行时             */
    }
    
    for (ulI = 0; ulI < LW_CFG_MAX_INTER_SRC; ulI++) {
        API_InterVectorDisable(ulI);                                    /*  关闭所有中断                */
    }
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核同时关闭中断        */

#if LW_CFG_CACHE_EN > 0
    API_CacheDisable(DATA_CACHE);                                       /*  禁能 CACHE                  */
    API_CacheDisable(INSTRUCTION_CACHE);
#endif                                                                  /*  LW_CFG_CACHE_EN > 0         */

#if LW_CFG_VMM_EN > 0
    API_VmmMmuDisable();                                                /*  关闭 MMU                    */
#endif                                                                  /*  LW_CFG_VMM_EN > 0           */

    archReboot(iRebootType, _K_ulRebootStartAddress);                   /*  调用体系架构重启操作        */
    
    _BugHandle(LW_TRUE, LW_TRUE, "kernel reboot error!\r\n");           /*  不会运行到这里              */
    
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核同时打开中断        */
}
Exemplo n.º 9
0
/*********************************************************************************************************
** 函数名称: API_TimeSleepEx
** 功能描述: 线程睡眠函数 (精度为 TICK HZ)
** 输 入  : ulTick            睡眠的时间
**           bSigRet           是否允许信号唤醒
** 输 出  : ERROR_NONE or EINTR
** 全局变量: 
** 调用模块: 
                                           API 函数
                                           
                                       (不得在中断中调用)
*********************************************************************************************************/
LW_API
ULONG  API_TimeSleepEx (ULONG  ulTick, BOOL  bSigRet)
{
             INTREG                iregInterLevel;
             
             PLW_CLASS_TCB         ptcbCur;
	REGISTER PLW_CLASS_PCB         ppcb;
	REGISTER ULONG                 ulKernelTime;
    
    if (LW_CPU_GET_CUR_NESTING()) {                                     /*  不能在中断中调用            */
        _ErrorHandle(ERROR_KERNEL_IN_ISR);
        return  (ERROR_KERNEL_IN_ISR);
    }
    
    LW_TCB_GET_CUR_SAFE(ptcbCur);                                       /*  当前任务控制块              */
    
    MONITOR_EVT_LONG2(MONITOR_EVENT_ID_THREAD, MONITOR_EVENT_THREAD_SLEEP, 
                      ptcbCur->TCB_ulId, ulTick, LW_NULL);
    
__wait_again:
    if (!ulTick) {                                                      /*  不进行延迟                  */
        return  (ERROR_NONE);
    }

    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核                    */

    ppcb = _GetPcb(ptcbCur);
    __DEL_FROM_READY_RING(ptcbCur, ppcb);                               /*  从就绪表中删除              */
    
    ptcbCur->TCB_ulDelay = ulTick;
    __ADD_TO_WAKEUP_LINE(ptcbCur);                                      /*  加入等待扫描链              */
    
    __KERNEL_TIME_GET_NO_SPINLOCK(ulKernelTime, ULONG);                 /*  记录系统时间                */
    
    if (__KERNEL_EXIT_IRQ(iregInterLevel)) {                            /*  被信号激活                  */
        if (bSigRet) {
            _ErrorHandle(EINTR);
            return  (EINTR);
        }
        ulTick = _sigTimeoutRecalc(ulKernelTime, ulTick);               /*  重新计算等待时间            */
        goto __wait_again;                                              /*  继续等待                    */
    }
    
    return  (ERROR_NONE);
}
Exemplo n.º 10
0
/*********************************************************************************************************
** 函数名称: _ThreadTick
** 功能描述: 扫描等待唤醒链表, tick 处理函数
** 输 入  : NONE
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  _ThreadTick (VOID)
{
             INTREG                 iregInterLevel;
    REGISTER PLW_CLASS_TCB          ptcb;
    REGISTER PLW_CLASS_PCB          ppcb;
             PLW_CLASS_WAKEUP_NODE  pwun;
             ULONG                  ulCounter = 1;
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核同时关闭中断        */
    
    __WAKEUP_PASS_FIRST(&_K_wuDelay, pwun, ulCounter);
    
    ptcb = _LIST_ENTRY(pwun, LW_CLASS_TCB, TCB_wunDelay);
    
    __DEL_FROM_WAKEUP_LINE(ptcb);                                       /*  从等待链中删除              */
    
    if (ptcb->TCB_usStatus & LW_THREAD_STATUS_PEND_ANY) {               /*  检查是否在等待事件          */
        ptcb->TCB_usStatus &= (~LW_THREAD_STATUS_PEND_ANY);             /*  等待超时清除事件等待位      */
        ptcb->TCB_ucWaitTimeout = LW_WAIT_TIME_OUT;                     /*  等待超时                    */
    
    } else {
        ptcb->TCB_ucWaitTimeout = LW_WAIT_TIME_CLEAR;                   /*  没有等待事件                */
    }
    
    if (__LW_THREAD_IS_READY(ptcb)) {                                   /*  检查是否就绪                */
        ptcb->TCB_ucSchedActivate = LW_SCHED_ACT_OTHER;
        ppcb = _GetPcb(ptcb);                                           /*  获得优先级控制块            */
        __ADD_TO_READY_RING(ptcb, ppcb);                                /*  加入就绪环                  */
    }
    
    __WAKEUP_PASS_SECOND();
    
    KN_INT_ENABLE(iregInterLevel);                                      /*  这里允许响应中断            */
    
    iregInterLevel = KN_INT_DISABLE();
    
    __WAKEUP_PASS_END();
    
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核同时打开中断        */
}
Exemplo n.º 11
0
PVOID  _ITimerThread (PVOID  pvArg)
{
             INTREG                     iregInterLevel;
    REGISTER PLW_CLASS_TIMER            ptmr;
             PTIMER_CALLBACK_ROUTINE    pfuncRoutine;
             PVOID                      pvRoutineArg;
    
#if (LW_CFG_RMS_EN > 0) && (LW_CFG_MAX_RMSS > 0)
             LW_OBJECT_HANDLE           ulRms = API_RmsCreate("rms_timer", 
                                                               LW_OPTION_OBJECT_GLOBAL, LW_NULL);
#endif
    
    (VOID)pvArg;
    
    for (;;) {
        PLW_CLASS_WAKEUP_NODE  pwun;
        ULONG                  ulCounter = LW_ITIMER_RATE;
        
#if (LW_CFG_RMS_EN > 0) && (LW_CFG_MAX_RMSS > 0)
        API_RmsPeriod(ulRms, LW_ITIMER_RATE);                           /*  使用 RMS 进行周期运行       */
#else
        API_TimeSleep(LW_ITIMER_RATE);                                  /*  等待一个扫描周期            */
#endif

        iregInterLevel = __KERNEL_ENTER_IRQ();                          /*  进入内核同时关闭中断        */
        
        __WAKEUP_PASS_FIRST(&_K_wuITmr, pwun, ulCounter);
        
        ptmr = _LIST_ENTRY(pwun, LW_CLASS_TIMER, TIMER_wunTimer);
        
        _WakeupDel(&_K_wuITmr, pwun);
        
        if (ptmr->TIMER_ulOption & LW_OPTION_AUTO_RESTART) {
            ptmr->TIMER_ulCounter = ptmr->TIMER_ulCounterSave;
            _WakeupAdd(&_K_wuITmr, pwun);
            
        } else {
            ptmr->TIMER_ucStatus = LW_TIMER_STATUS_STOP;                /*  填写停止标志位              */
        }
        
        pfuncRoutine = ptmr->TIMER_cbRoutine;
        pvRoutineArg = ptmr->TIMER_pvArg;
        
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核同时打开中断        */
        
        LW_SOFUNC_PREPARE(pfuncRoutine);
        pfuncRoutine(pvRoutineArg);
        
        iregInterLevel = __KERNEL_ENTER_IRQ();                          /*  进入内核同时关闭中断        */
        
        __WAKEUP_PASS_SECOND();
        
        KN_INT_ENABLE(iregInterLevel);                                  /*  这里允许响应中断            */
    
        iregInterLevel = KN_INT_DISABLE();
        
        __WAKEUP_PASS_END();
        
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核同时打开中断        */
    }
    
    return  (LW_NULL);
}
Exemplo n.º 12
0
LW_API  
ULONG  API_RmsStatus (LW_OBJECT_HANDLE  ulId,
                      UINT8            *pucStatus,
                      ULONG            *pulTimeLeft,
                      LW_OBJECT_HANDLE *pulOwnerId)
{
             INTREG              iregInterLevel;
    REGISTER PLW_CLASS_RMS       prms;
    REGISTER UINT16              usIndex;
    
    usIndex = _ObjectGetIndex(ulId);
    
    if (LW_CPU_GET_CUR_NESTING()) {                                     /*  不能在中断中调用            */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n");
        _ErrorHandle(ERROR_KERNEL_IN_ISR);
        return  (ERROR_KERNEL_IN_ISR);
    }
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!_ObjectClassOK(ulId, _OBJECT_RMS)) {                           /*  对象类型检查                */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "RMS handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    
    if (_Rms_Index_Invalid(usIndex)) {                                  /*  缓冲区索引检查              */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "RMS handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核                    */
    if (_Rms_Type_Invalid(usIndex)) {
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "RMS handle invalidate.\r\n");
        _ErrorHandle(ERROR_RMS_NULL);
        return  (ERROR_RMS_NULL);
    }
#else
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核                    */
#endif
    
    prms = &_K_rmsBuffer[usIndex];
    
    if (pucStatus) {
        *pucStatus = prms->RMS_ucStatus;
    }
    
    if (prms->RMS_ucStatus == LW_RMS_EXPIRED) {                         /*  有线程进行周期等待          */
        if (pulOwnerId) {
            *pulOwnerId = prms->RMS_ptcbOwner->TCB_ulId;
        }
        if (pulTimeLeft) {
            _WakeupStatus(&_K_wuDelay, &prms->RMS_ptcbOwner->TCB_wunDelay, pulTimeLeft);
        }
    
    } else {                                                            /*  无效状态                    */
        if (pulOwnerId) {
            *pulOwnerId = LW_OBJECT_HANDLE_INVALID;
        }
        if (pulTimeLeft) {
            *pulTimeLeft = 0ul;
        }
    }
    
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核                    */
    
    return  (ERROR_NONE);
}
Exemplo n.º 13
0
LW_API 
ULONG  API_SemaphoreBDelete (LW_OBJECT_HANDLE  *pulId)
{
             INTREG                iregInterLevel;
    REGISTER UINT16                usIndex;
    REGISTER PLW_CLASS_EVENT       pevent;
    REGISTER PLW_CLASS_TCB         ptcb;
    REGISTER PLW_LIST_RING        *ppringList;                          /*  等待队列地址                */
    
    REGISTER LW_OBJECT_HANDLE      ulId;
    
    ulId = *pulId;
    
    usIndex = _ObjectGetIndex(ulId);
    
    if (LW_CPU_GET_CUR_NESTING()) {                                     /*  不能在中断中调用            */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n");
        _ErrorHandle(ERROR_KERNEL_IN_ISR);
        return  (ERROR_KERNEL_IN_ISR);
    }
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!_ObjectClassOK(ulId, _OBJECT_SEM_B)) {                         /*  类型是否正确                */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "semaphore handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    if (_Event_Index_Invalid(usIndex)) {                                /*  下标是否正正确              */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "semaphore handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
#endif
    pevent = &_K_eventBuffer[usIndex];
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核                    */
    if (_Event_Type_Invalid(usIndex, LW_TYPE_EVENT_SEMB)) {
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "semaphore handle invalidate.\r\n");
        _ErrorHandle(ERROR_EVENT_TYPE);
        return  (ERROR_EVENT_TYPE);
    }

    _ObjectCloseId(pulId);                                              /*  清除句柄                    */
    
    pevent->EVENT_ucType = LW_TYPE_EVENT_UNUSED;                        /*  事件类型为空                */
    
    while (_EventWaitNum(pevent)) {                                     /*  是否存在正在等待的任务      */
        if (pevent->EVENT_ulOption & LW_OPTION_WAIT_PRIORITY) {         /*  优先级等待队列              */
            _EVENT_DEL_Q_PRIORITY(ppringList);                          /*  检查需要激活的队列          */
                                                                        /*  激活优先级等待线程          */
            ptcb = _EventReadyPriorityLowLevel(pevent, LW_NULL, ppringList);
        
        } else {
            _EVENT_DEL_Q_FIFO(ppringList);                              /*  查找 FIFO 队列指针地址      */
                                                                        /*  激活FIFO等待线程            */
            ptcb = _EventReadyFifoLowLevel(pevent, LW_NULL, ppringList);
        }
        
        KN_INT_ENABLE(iregInterLevel);                                  /*  打开中断                    */
        
        ptcb->TCB_ucIsEventDelete = LW_EVENT_DELETE;                    /*  事件已经被删除              */
        _EventReadyHighLevel(ptcb, LW_THREAD_STATUS_SEM);               /*  处理 TCB                    */
        
        iregInterLevel = KN_INT_DISABLE();                              /*  关闭中断                    */
    }
    
    pevent->EVENT_pvTcbOwn = LW_NULL;
    
    _Free_Event_Object(pevent);                                         /*  交还控制块                  */
    
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核                    */
    
    __LW_OBJECT_DELETE_HOOK(ulId);
    
    MONITOR_EVT_LONG1(MONITOR_EVENT_ID_SEMB, MONITOR_EVENT_SEM_DELETE, ulId, LW_NULL);

    _DebugFormat(__LOGMESSAGE_LEVEL, "semaphore \"%s\" has been delete.\r\n", pevent->EVENT_cEventName);

    return  (ERROR_NONE);
}
Exemplo n.º 14
0
/*********************************************************************************************************
** 函数名称: API_KernelHookDelete
** 功能描述: 删除内核指定 HOOK
** 输 入  : 
**           ulOpt                         HOOK 类型
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
ULONG  API_KernelHookDelete (ULONG  ulOpt)
{
    INTREG  iregInterLevel;
        
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核同时关闭中断        */
    
    switch (ulOpt) {
    
    case LW_OPTION_THREAD_CREATE_HOOK:                                  /*  线程建立钩子                */
        _K_hookKernel.HOOK_ThreadCreate = LW_NULL;
        break;
    
    case LW_OPTION_THREAD_DELETE_HOOK:                                  /*  线程删除钩子                */
        _K_hookKernel.HOOK_ThreadDelete = LW_NULL;
        break;
    
    case LW_OPTION_THREAD_SWAP_HOOK:                                    /*  线程切换钩子                */
        _K_hookKernel.HOOK_ThreadSwap = LW_NULL;
        break;
    
    case LW_OPTION_THREAD_TICK_HOOK:                                    /*  系统时钟中断钩子            */
        _K_hookKernel.HOOK_ThreadTick = LW_NULL;
        break;
    
    case LW_OPTION_THREAD_INIT_HOOK:                                    /*  线程初始化钩子              */
        _K_hookKernel.HOOK_ThreadInit = LW_NULL;
        break;
    
    case LW_OPTION_THREAD_IDLE_HOOK:                                    /*  空闲线程钩子                */
        _K_hookKernel.HOOK_ThreadIdle = LW_NULL;
        break;
    
    case LW_OPTION_KERNEL_INITBEGIN:                                    /*  内核初始化开始钩子          */
        _K_hookKernel.HOOK_KernelInitBegin = LW_NULL;
        break;
    
    case LW_OPTION_KERNEL_INITEND:                                      /*  内核初始化结束钩子          */
        _K_hookKernel.HOOK_KernelInitEnd = LW_NULL;
        break;
    
    case LW_OPTION_WATCHDOG_TIMER:                                      /*  看门狗定时器钩子            */
        _K_hookKernel.HOOK_WatchDogTimer = LW_NULL;
        break;
        
    case LW_OPTION_OBJECT_CREATE_HOOK:                                  /*  创建内核对象钩子            */
        _K_hookKernel.HOOK_ObjectCreate = LW_NULL;
        break;
    
    case LW_OPTION_OBJECT_DELETE_HOOK:                                  /*  删除内核对象钩子            */
        _K_hookKernel.HOOK_ObjectDelete = LW_NULL;
        break;
    
    case LW_OPTION_FD_CREATE_HOOK:                                      /*  文件描述符创建钩子          */
        _K_hookKernel.HOOK_FdCreate = LW_NULL;
        break;
    
    case LW_OPTION_FD_DELETE_HOOK:                                      /*  文件描述符删除钩子          */
        _K_hookKernel.HOOK_FdDelete = LW_NULL;
        break;
        
    case LW_OPTION_CPU_IDLE_ENTER:                                      /*  CPU 进入空闲模式            */
        _K_hookKernel.HOOK_CpuIdleEnter = LW_NULL;
        break;
    
    case LW_OPTION_CPU_IDLE_EXIT:                                       /*  CPU 退出空闲模式            */
        _K_hookKernel.HOOK_CpuIdleExit = LW_NULL;
        break;
    
    case LW_OPTION_CPU_INT_ENTER:                                       /*  CPU 进入中断(异常)模式      */
        _K_hookKernel.HOOK_CpuIntEnter = LW_NULL;
        break;
    
    case LW_OPTION_CPU_INT_EXIT:                                        /*  CPU 退出中断(异常)模式      */
        _K_hookKernel.HOOK_CpuIntExit = LW_NULL;
        break;
    
    default:
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核同时打开中断        */
        _ErrorHandle(ERROR_KERNEL_OPT_NULL);
        return  (ERROR_KERNEL_OPT_NULL);
    }
    
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核同时打开中断        */
    return  (ERROR_NONE);
}
Exemplo n.º 15
0
LW_API  
ULONG  API_SemaphoreCPost (LW_OBJECT_HANDLE  ulId)
{
             INTREG                iregInterLevel;
    REGISTER UINT16                usIndex;
    REGISTER PLW_CLASS_EVENT       pevent;
    REGISTER PLW_CLASS_TCB         ptcb;
    REGISTER PLW_LIST_RING        *ppringList;                          /*  等待队列地址                */
    
    usIndex = _ObjectGetIndex(ulId);
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!_ObjectClassOK(ulId, _OBJECT_SEM_C)) {                         /*  类型是否正确                */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "semaphore handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    if (_Event_Index_Invalid(usIndex)) {                                /*  下标是否正正确              */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "semaphore handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
#endif
    pevent = &_K_eventBuffer[usIndex];
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核                    */
    if (_Event_Type_Invalid(usIndex, LW_TYPE_EVENT_SEMC)) {
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "semaphore handle invalidate.\r\n");
        _ErrorHandle(ERROR_EVENT_TYPE);
        return  (ERROR_EVENT_TYPE);
    }
    
    if (_EventWaitNum(pevent)) {
        if (pevent->EVENT_ulOption & LW_OPTION_WAIT_PRIORITY) {         /*  优先级等待队列              */
            _EVENT_DEL_Q_PRIORITY(ppringList);                          /*  检查需要激活的队列          */
                                                                        /*  激活优先级等待线程          */
            ptcb = _EventReadyPriorityLowLevel(pevent, LW_NULL, ppringList);
        
        } else {
            _EVENT_DEL_Q_FIFO(ppringList);                              /*  检查需要激活的FIFO队列      */
                                                                        /*  激活FIFO等待线程            */
            ptcb = _EventReadyFifoLowLevel(pevent, LW_NULL, ppringList);
        }
        
        KN_INT_ENABLE(iregInterLevel);                                  /*  使能中断                    */
        
        _EventReadyHighLevel(ptcb, LW_THREAD_STATUS_SEM);               /*  处理 TCB                    */
        
        MONITOR_EVT_LONG2(MONITOR_EVENT_ID_SEMC, MONITOR_EVENT_SEM_POST, 
                          ulId, ptcb->TCB_ulId, LW_NULL);
        
        __KERNEL_EXIT();                                                /*  退出内核                    */
        return  (ERROR_NONE);
    
    } else {                                                            /*  没有线程等待                */
        if (pevent->EVENT_ulCounter < pevent->EVENT_ulMaxCounter) {     /*  检查是否还有空间加          */
            pevent->EVENT_ulCounter++;
            __KERNEL_EXIT_IRQ(iregInterLevel);                          /*  退出内核                    */
            return  (ERROR_NONE);
        
        } else {                                                        /*  已经满了                    */
            __KERNEL_EXIT_IRQ(iregInterLevel);                          /*  退出内核                    */
            _ErrorHandle(ERROR_EVENT_FULL);
            return  (ERROR_EVENT_FULL);
        }
    }
}
Exemplo n.º 16
0
/*********************************************************************************************************
** 函数名称: nanosleep 
** 功能描述: 使调用此函数的线程睡眠一个指定的时间, 睡眠过程中可能被信号唤醒. (POSIX)
** 输 入  : rqtp         睡眠的时间
**           rmtp         保存剩余时间的结构.
** 输 出  : ERROR_NONE  or  PX_ERROR

             error == EINTR    表示被信号激活.
** 全局变量: 
** 调用模块: 
                                           API 函数
                                           
                                       (不得在中断中调用)
*********************************************************************************************************/
LW_API  
INT  nanosleep (const struct timespec  *rqtp, struct timespec  *rmtp)
{
             INTREG             iregInterLevel;
             
             PLW_CLASS_TCB      ptcbCur;
    REGISTER PLW_CLASS_PCB      ppcb;
	REGISTER ULONG              ulKernelTime;
	REGISTER INT                iRetVal;
	         INT                iSchedRet;
	
	REGISTER ULONG              ulError;
             ULONG              ulTick;
             
             struct timespec    tvStart;
             struct timespec    tvTemp;
    
    if ((!rqtp)              ||
        (rqtp->tv_nsec <  0) ||
        (rqtp->tv_nsec >= __TIMEVAL_NSEC_MAX)) {                        /*  时间格式错误                */
        _ErrorHandle(EINVAL);
        return  (PX_ERROR);
    }
    
    ulTick = __timespecToTick((struct timespec *)rqtp);
    if (!ulTick) {                                                      /*  不到一个 tick               */
        __timePassSpec(rqtp);                                           /*  平静度过                    */
        if (rmtp) {
            rmtp->tv_sec  = 0;                                          /*  不存在时间差别              */
            rmtp->tv_nsec = 0;
        }
        return  (ERROR_NONE);
    }
    
    __timeGetHighResolution(&tvStart);                                  /*  记录开始的时间              */
    
    __THREAD_CANCEL_POINT();                                            /*  测试取消点                  */
    
    LW_TCB_GET_CUR_SAFE(ptcbCur);                                       /*  当前任务控制块              */
    
    MONITOR_EVT_LONG2(MONITOR_EVENT_ID_THREAD, MONITOR_EVENT_THREAD_SLEEP, 
                      ptcbCur->TCB_ulId, ulTick, LW_NULL);
    
__wait_again:
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核                    */
    
    ppcb = _GetPcb(ptcbCur);
    __DEL_FROM_READY_RING(ptcbCur, ppcb);                               /*  从就绪表中删除              */
    
    ptcbCur->TCB_ulDelay = ulTick;
    __ADD_TO_WAKEUP_LINE(ptcbCur);                                      /*  加入等待扫描链              */
    
    __KERNEL_TIME_GET_NO_SPINLOCK(ulKernelTime, ULONG);                 /*  记录系统时间                */
    
    iSchedRet = __KERNEL_EXIT_IRQ(iregInterLevel);                      /*  调度器解锁                  */
    if (iSchedRet == LW_SIGNAL_EINTR) {
        iRetVal = PX_ERROR;                                             /*  被信号激活                  */
        ulError = EINTR;
    
    } else {
        if (iSchedRet == LW_SIGNAL_RESTART) {                           /*  信号要求重启等待            */
            ulTick = _sigTimeoutRecalc(ulKernelTime, ulTick);           /*  重新计算等待时间            */
            if (ulTick != 0ul) {
                goto    __wait_again;                                   /*  重新等待剩余的 tick         */
            }
        }
        iRetVal = ERROR_NONE;                                           /*  自然唤醒                    */
        ulError = ERROR_NONE;
    }
    
    if (ulError ==  ERROR_NONE) {                                       /*  tick 已经延迟结束           */
        __timeGetHighResolution(&tvTemp);
        __timespecSub(&tvTemp, &tvStart);                               /*  计算已经延迟的时间          */
        if (__timespecLeftTime(&tvTemp, rqtp)) {                        /*  还有剩余时间需要延迟        */
            struct timespec  tvNeed = *rqtp;
            __timespecSub(&tvNeed, &tvTemp);
            __timePassSpec(&tvNeed);                                    /*  平静度过                    */
        }
        if (rmtp) {
            rmtp->tv_sec  = 0;                                          /*  不存在时间差别              */
            rmtp->tv_nsec = 0;
        }
    } else {                                                            /*  信号唤醒                    */
        if (rmtp) {
            *rmtp = *rqtp;
            __timeGetHighResolution(&tvTemp);
            __timespecSub(&tvTemp, &tvStart);                           /*  计算已经延迟的时间          */
            if (__timespecLeftTime(&tvTemp, rmtp)) {                    /*  没有延迟够                  */
                __timespecSub(rmtp, &tvTemp);                           /*  计算没有延迟够的时间        */
            }
        }
    }
             
    _ErrorHandle(ulError);                                              /*  设置 errno 值               */
    return  (iRetVal);
}
Exemplo n.º 17
0
LW_API
ULONG  API_MsgQueueReceive (LW_OBJECT_HANDLE    ulId,
                            PVOID               pvMsgBuffer,
                            size_t              stMaxByteSize,
                            size_t             *pstMsgLen,
                            ULONG               ulTimeout)

{
    INTREG                iregInterLevel;

    PLW_CLASS_TCB         ptcbCur;
    REGISTER UINT16                usIndex;
    REGISTER PLW_CLASS_EVENT       pevent;
    REGISTER PLW_CLASS_MSGQUEUE    pmsgqueue;
    REGISTER UINT8                 ucPriorityIndex;
    REGISTER PLW_LIST_RING        *ppringList;
    ULONG                 ulTimeSave;                          /*  系统事件记录                */
    INT                   iSchedRet;

    ULONG                 ulEventOption;                       /*  事件创建选项                */
    size_t                stMsgLenTemp;                        /*  临时记录变量                */

    usIndex = _ObjectGetIndex(ulId);

    if (LW_CPU_GET_CUR_NESTING()) {                                     /*  不能在中断中调用            */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n");
        _ErrorHandle(ERROR_KERNEL_IN_ISR);
        return  (ERROR_KERNEL_IN_ISR);
    }

    LW_TCB_GET_CUR_SAFE(ptcbCur);                                       /*  当前任务控制块              */

    if (pstMsgLen == LW_NULL) {
        pstMsgLen =  &stMsgLenTemp;                                     /*  临时变量记录消息长短        */
    }

__wait_again:
#if LW_CFG_ARG_CHK_EN > 0
    if (!pvMsgBuffer || !stMaxByteSize) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "pvMsgBuffer invalidate.\r\n");
        _ErrorHandle(ERROR_MSGQUEUE_MSG_NULL);
        return  (ERROR_MSGQUEUE_MSG_NULL);
    }
    if (!_ObjectClassOK(ulId, _OBJECT_MSGQUEUE)) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "msgqueue handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    if (_Event_Index_Invalid(usIndex)) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "msgqueue handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
#endif
    pevent = &_K_eventBuffer[usIndex];

    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核                    */
    if (_Event_Type_Invalid(usIndex, LW_TYPE_EVENT_MSGQUEUE)) {
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "msgqueue handle invalidate.\r\n");
        _ErrorHandle(ERROR_MSGQUEUE_TYPE);
        return  (ERROR_MSGQUEUE_TYPE);
    }

    pmsgqueue = (PLW_CLASS_MSGQUEUE)pevent->EVENT_pvPtr;

    ptcbCur->TCB_ulRecvOption = LW_OPTION_NOERROR;                      /*  接收大消息自动截断          */

    if (pevent->EVENT_ulCounter) {                                      /*  事件有效                    */
        pevent->EVENT_ulCounter--;
        _MsgQueueGetMsg(pmsgqueue,
                        pvMsgBuffer,
                        stMaxByteSize,
                        pstMsgLen);                                     /*  获得消息                    */
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核                    */
        return  (ERROR_NONE);
    }

    if (ulTimeout == LW_OPTION_NOT_WAIT) {                              /*  不等待                      */
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核                    */
        _ErrorHandle(ERROR_THREAD_WAIT_TIMEOUT);                        /*  超时                        */
        return  (ERROR_THREAD_WAIT_TIMEOUT);
    }

    ptcbCur->TCB_pstMsgByteSize    = pstMsgLen;
    ptcbCur->TCB_stMaxByteSize     = stMaxByteSize;
    ptcbCur->TCB_pvMsgQueueMessage = pvMsgBuffer;                       /*  记录信息                    */

    ptcbCur->TCB_usStatus      |= LW_THREAD_STATUS_MSGQUEUE;            /*  写状态位,开始等待          */
    ptcbCur->TCB_ucWaitTimeout  = LW_WAIT_TIME_CLEAR;                   /*  清空等待时间                */

    if (ulTimeout == LW_OPTION_WAIT_INFINITE) {                         /*  是否是无穷等待              */
        ptcbCur->TCB_ulDelay = 0ul;
    } else {
        ptcbCur->TCB_ulDelay = ulTimeout;                               /*  设置超时时间                */
    }
    __KERNEL_TIME_GET_NO_SPINLOCK(ulTimeSave, ULONG);                   /*  记录系统时间                */

    if (pevent->EVENT_ulOption & LW_OPTION_WAIT_PRIORITY) {
        _EVENT_INDEX_Q_PRIORITY(ptcbCur->TCB_ucPriority, ucPriorityIndex);
        _EVENT_PRIORITY_Q_PTR(ppringList, ucPriorityIndex);
        ptcbCur->TCB_ppringPriorityQueue = ppringList;                  /*  记录等待队列位置            */
        _EventWaitPriority(pevent, ppringList);                         /*  加入优先级等待表            */

    } else {                                                            /*  按 FIFO 等待                */
        _EVENT_FIFO_Q_PTR(ppringList);                                  /*  确定 FIFO 队列的位置        */
        _EventWaitFifo(pevent, ppringList);                             /*  加入 FIFO 等待表            */
    }

    KN_INT_ENABLE(iregInterLevel);                                      /*  使能中断                    */

    ulEventOption = pevent->EVENT_ulOption;

    MONITOR_EVT_LONG2(MONITOR_EVENT_ID_MSGQ, MONITOR_EVENT_MSGQ_PEND,
                      ulId, ulTimeout, LW_NULL);

    iSchedRet = __KERNEL_EXIT();                                        /*  调度器解锁                  */
    if (iSchedRet == LW_SIGNAL_EINTR) {
        if (ulEventOption & LW_OPTION_SIGNAL_INTER) {
            _ErrorHandle(EINTR);
            return  (EINTR);
        }
        ulTimeout = _sigTimeoutRecalc(ulTimeSave, ulTimeout);           /*  重新计算超时时间            */
        goto    __wait_again;

    } else if (iSchedRet == LW_SIGNAL_RESTART) {
        ulTimeout = _sigTimeoutRecalc(ulTimeSave, ulTimeout);           /*  重新计算超时时间            */
        goto    __wait_again;
    }

    if (ptcbCur->TCB_ucWaitTimeout == LW_WAIT_TIME_OUT) {
        iregInterLevel = __KERNEL_ENTER_IRQ();                          /*  进入内核                    */
        if (ptcbCur->TCB_ucWaitTimeout == LW_WAIT_TIME_CLEAR) {         /*  是否在上面瞬间被激活        */
            __KERNEL_EXIT_IRQ(iregInterLevel);                          /*  退出内核                    */
            return  (ERROR_NONE);
        }

        if (pevent->EVENT_ulOption & LW_OPTION_WAIT_PRIORITY) {
            _EventTimeoutPriority(pevent, ppringList);                  /*  等待超时恢复                */
        } else {
            _EventTimeoutFifo(pevent, ppringList);                      /*  等待超时恢复                */
        }

        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核                    */
        _ErrorHandle(ERROR_THREAD_WAIT_TIMEOUT);                        /*  超时                        */
        return  (ERROR_THREAD_WAIT_TIMEOUT);

    } else {
        if (ptcbCur->TCB_ucIsEventDelete == LW_EVENT_EXIST) {           /*  事件是否存在                */
            return  (ERROR_NONE);

        } else {
            _ErrorHandle(ERROR_MSGQUEUE_WAS_DELETED);                   /*  已经被删除                  */
            return  (ERROR_MSGQUEUE_WAS_DELETED);
        }
    }
}