Пример #1
0
/*********************************************************************************************************
** 函数名称: API_InterVectorDisconnect
** 功能描述: 解除系统指定向量中断服务
** 输 入  : ulVector                      中断向量号
**           pfuncIsr                      服务函数
**           pvArg                         服务函数参数
** 输 出  : ERROR CODE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API
ULONG  API_InterVectorDisconnect (ULONG             ulVector,
                                  PINT_SVR_ROUTINE  pfuncIsr,
                                  PVOID             pvArg)
{
    INTREG              iregInterLevel;
    BOOL                bNeedFree = LW_FALSE;
    
    PLW_LIST_LINE       plineTemp;
    PLW_CLASS_INTACT    piaction;
    PLW_CLASS_INTDESC   pidesc;

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

    if (_Inter_Vector_Invalid(ulVector)) {
        _ErrorHandle(ERROR_KERNEL_VECTOR_NULL);
        return  (ERROR_KERNEL_VECTOR_NULL);
    }
    
    if (pfuncIsr == LW_NULL) {
        _ErrorHandle(ERROR_KERNEL_VECTOR_NULL);
        return  (ERROR_KERNEL_VECTOR_NULL);
    }
    
    INTER_SHOWLOCK_LOCK();

    pidesc = LW_IVEC_GET_IDESC(ulVector);

    LW_SPIN_LOCK_QUICK(&pidesc->IDESC_slLock, &iregInterLevel);         /*  关闭中断同时锁住 spinlock   */
    
    for (plineTemp  = pidesc->IDESC_plineAction;
         plineTemp != LW_NULL;
         plineTemp  = _list_line_get_next(plineTemp)) {
         
        piaction = _LIST_ENTRY(plineTemp, LW_CLASS_INTACT, IACT_plineManage);
        if ((piaction->IACT_pfuncIsr == pfuncIsr) &&
            (piaction->IACT_pvArg    == pvArg)) {
            _List_Line_Del(&piaction->IACT_plineManage,
                           &pidesc->IDESC_plineAction);
            bNeedFree = LW_TRUE;
            break;
        }
    }
    
    LW_SPIN_UNLOCK_QUICK(&pidesc->IDESC_slLock, iregInterLevel);        /*  打开中断, 同时打开 spinlock */
    
    INTER_SHOWLOCK_UNLOCK();
    
    if (bNeedFree) {
        __KHEAP_FREE(piaction);
    }
    
    return  (ERROR_NONE);
}
Пример #2
0
/*********************************************************************************************************
** 函数名称: _JobQueueCreate
** 功能描述: 创建一个工作队列
** 输 入  : uiQueueSize       队列大小
**           bNonBlock         执行函数是否为非阻塞方式
** 输 出  : 工作队列控制块
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
PLW_JOB_QUEUE  _jobQueueCreate (UINT uiQueueSize, BOOL bNonBlock)
{
    PLW_JOB_QUEUE pjobq;
    
    pjobq = (PLW_JOB_QUEUE)__KHEAP_ALLOC((size_t)(sizeof(LW_JOB_QUEUE) + 
                                         (uiQueueSize * sizeof(LW_JOB_MSG))));
    if (pjobq == LW_NULL) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "kernel low memory.\r\n");
        _ErrorHandle(ERROR_KERNEL_LOW_MEMORY);
        return  (LW_NULL);
    }
    
    pjobq->JOBQ_pjobmsgQueue = (PLW_JOB_MSG)(pjobq + 1);
    pjobq->JOBQ_uiIn         = 0;
    pjobq->JOBQ_uiOut        = 0;
    pjobq->JOBQ_uiCnt        = 0;
    pjobq->JOBQ_uiSize       = uiQueueSize;
    pjobq->JOBQ_stLost       = 0;
    
    if (bNonBlock == LW_FALSE) {
        pjobq->JOBQ_ulSync = API_SemaphoreBCreate("job_sync", LW_FALSE, LW_OPTION_OBJECT_GLOBAL, LW_NULL);
        if (pjobq->JOBQ_ulSync == LW_OBJECT_HANDLE_INVALID) {
            __KHEAP_FREE(pjobq);
            return  (LW_NULL);
        }
    }
    
    LW_SPIN_INIT(&pjobq->JOBQ_slLock);
    
    return  (pjobq);
}
Пример #3
0
/*********************************************************************************************************
** 函数名称: _JobQueueDelete
** 功能描述: 删除一个工作队列
** 输 入  : pjobq         工作队列控制块
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  _jobQueueDelete (PLW_JOB_QUEUE pjobq)
{
    if (pjobq->JOBQ_ulSync) {
        API_SemaphoreBDelete(&pjobq->JOBQ_ulSync);
    }
    
    __KHEAP_FREE(pjobq);
}
Пример #4
0
/*********************************************************************************************************
** 函数名称: _StackFree
** 功能描述: 回收栈内存
** 输 入  : ptcbDel       任务
**           pstk          栈内存
**           bImmed        立即回收
** 输 出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
VOID  _StackFree (PLW_CLASS_TCB  ptcb, PLW_STACK  pstk, BOOL  bImmed)
{
#if LW_CFG_MODULELOADER_EN > 0
    vprocStackFree(ptcb, (PVOID)pstk, bImmed);
#else
    __KHEAP_FREE((PVOID)pstk);
#endif                                                                  /*  LW_CFG_MODULELOADER_EN > 0  */
}
Пример #5
0
/*********************************************************************************************************
** 函数名称: API_CacheDmaFree
** 功能描述: 归还一块非缓冲的内存
** 输 入  : 
**           pvBuf                         开辟时的首地址
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
VOID    API_CacheDmaFree (PVOID  pvBuf)
{
    if (_G_cacheopLib.CACHEOP_pfuncDmaFree) {
        _G_cacheopLib.CACHEOP_pfuncDmaFree(pvBuf);
    
    } else {
        __KHEAP_FREE(pvBuf);
    }
}
Пример #6
0
/*********************************************************************************************************
** 函数名称: vprocStackFree
** 功能描述: 释放 stack
** 输 入  : ptcbDel       被删除的任务
**           pvStack       线程堆栈
**           bImmed        立即回收
** 输 出  : 堆栈
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  vprocStackFree (PLW_CLASS_TCB  ptcbDel, PVOID  pvStack, BOOL  bImmed)
{
#if (LW_CFG_VMM_EN > 0) && !defined(LW_CFG_CPU_ARCH_PPC)
    LW_LD_VPROC     *pvproc;
    BOOL             bFree = LW_TRUE;

    switch (ptcbDel->TCB_iStkLocation) {
    
    case LW_TCB_STK_VMM:
        pvproc = __LW_VP_GET_TCB_PROC(ptcbDel);
        if (pvproc && (pvproc->VP_ulMainThread == ptcbDel->TCB_ulId)) { /*  如果是主线程                */
            if (bImmed) {
#if LW_CFG_COROUTINE_EN > 0
                if (pvproc->VP_pvMainStack == pvStack) {
                    pvproc->VP_pvMainStack =  LW_NULL;                  /*  主线程堆栈删除              */
                }
#else
                pvproc->VP_pvMainStack = LW_NULL;
#endif                                                                  /*  LW_CFG_COROUTINE_EN > 0     */
            } else {
                bFree = LW_FALSE;                                       /*  延迟删除主线程堆栈          */
            }
        }
        if (bFree) {
            API_VmmFree(pvStack);
        }
        break;
        
    case LW_TCB_STK_HEAP:
        __KHEAP_FREE(pvStack);
        break;
        
    default:
        _BugHandle(LW_TRUE, LW_FALSE, "unknown stack property!\r\n");
        break;
    }
#else
    __KHEAP_FREE(pvStack);
#endif                                                                  /*  LW_CFG_VMM_EN > 0           */
}
Пример #7
0
/*********************************************************************************************************
** 函数名称: API_CoroutineDelete
** 功能描述: 删除一个指定的协程.
** 输 入  : pvCrcb                        协程句柄
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
ULONG   API_CoroutineDelete (PVOID  pvCrcb)
{
             INTREG                 iregInterLevel;
    REGISTER PLW_CLASS_COROUTINE    pcrcbDel = (PLW_CLASS_COROUTINE)pvCrcb;
    REGISTER PLW_CLASS_COROUTINE    pcrcbNow;
             PLW_CLASS_TCB          ptcbCur;

    if (!LW_SYS_STATUS_IS_RUNNING()) {                                  /*  系统必须已经启动            */
        _ErrorHandle(ERROR_KERNEL_NOT_RUNNING);
        return  (ERROR_KERNEL_NOT_RUNNING);
    }
    
    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 (!pcrcbDel) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "coroutine handle invalidate.\r\n");
        _ErrorHandle(EINVAL);
        return  (EINVAL);
    }
    
    LW_TCB_GET_CUR_SAFE(ptcbCur);                                       /*  当前任务控制块              */
    
    pcrcbNow = _LIST_ENTRY(ptcbCur->TCB_pringCoroutineHeader, 
                           LW_CLASS_COROUTINE, 
                           COROUTINE_ringRoutine);                      /*  获得当前协程                */
    
    if (pcrcbNow == pcrcbDel) {                                         /*  删除当前协程                */
        return  (API_CoroutineExit());
    }
    
    LW_SPIN_LOCK_QUICK(&ptcbCur->TCB_slLock, &iregInterLevel);
    _List_Ring_Del(&pcrcbDel->COROUTINE_ringRoutine,
                   &ptcbCur->TCB_pringCoroutineHeader);                 /*  从协程表中删除              */
    LW_SPIN_UNLOCK_QUICK(&ptcbCur->TCB_slLock, iregInterLevel);
    
    MONITOR_EVT_LONG2(MONITOR_EVENT_ID_COROUTINE, MONITOR_EVENT_COROUTINE_DELETE, 
                      ptcbCur->TCB_ulId, pcrcbDel, LW_NULL);
    
    if (pcrcbDel->COROUTINE_bIsNeedFree) {
        __KHEAP_FREE(pcrcbDel->COROUTINE_pstkStackLowAddr);             /*  释放内存                    */
    }
    
    return  (ERROR_NONE);
}
Пример #8
0
/*********************************************************************************************************
** 函数名称: _CoroutineDeleteAll
** 功能描述: 释放指定线程所有的协程空间.
** 输 入  : ptcb                     线程控制块
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  _CoroutineFreeAll (PLW_CLASS_TCB    ptcb)
{
    REGISTER PLW_CLASS_COROUTINE    pcrcbTemp;
    REGISTER PLW_LIST_RING          pringTemp;
    
    pringTemp = ptcb->TCB_pringCoroutineHeader;
    
    while (pringTemp) {
        _List_Ring_Del(pringTemp,
                       &ptcb->TCB_pringCoroutineHeader);                /*  从协程表中删除              */
        pcrcbTemp = _LIST_ENTRY(pringTemp, 
                                LW_CLASS_COROUTINE,
                                COROUTINE_ringRoutine);
        if (pcrcbTemp->COROUTINE_bIsNeedFree) {
            __KHEAP_FREE(pcrcbTemp->COROUTINE_pstkStackLowAddr);
        }
        pringTemp = ptcb->TCB_pringCoroutineHeader;
    }
}
Пример #9
0
ULONG  __threadDelete (PLW_CLASS_TCB  ptcbDel, BOOL  bIsInSafe, 
                       PVOID  pvRetVal, BOOL  bIsAlreadyWaitDeath)
{
             INTREG                iregInterLevel;
    REGISTER UINT16                usIndex;
    REGISTER PLW_CLASS_PCB         ppcbDel;
    REGISTER LW_OBJECT_HANDLE      ulId;
    REGISTER PVOID                 pvFreeLowAddr;                       /*  要释放的内存地址            */
             PVOID                 pvVProc;
             
#if (LW_CFG_EVENTSET_EN > 0) && (LW_CFG_MAX_EVENTSETS > 0)
    REGISTER PLW_EVENTSETNODE      pesnPtr;
#endif

    ulId    = ptcbDel->TCB_ulId;
    usIndex = _ObjectGetIndex(ulId);
    
    if (bIsAlreadyWaitDeath == LW_FALSE) {
        _ThreadDeleteWaitDeath(ptcbDel);                                /*  将要删除的线程进入僵死状态  */
    }
    
    __KERNEL_ENTER();                                                   /*  进入内核                    */
    
    ppcbDel = _GetPcb(ptcbDel);
    
    iregInterLevel = KN_INT_DISABLE();                                  /*  关闭中断                    */
    
    if (ptcbDel->TCB_ptcbDeleteWait) {                                  /*  目标线程正在等待其他任务删除*/
        ptcbDel->TCB_ptcbDeleteWait->TCB_ptcbDeleteMe = (PLW_CLASS_TCB)1;
        ptcbDel->TCB_ptcbDeleteWait = LW_NULL;
    }
    
#if (LW_CFG_EVENT_EN > 0) && (LW_CFG_MAX_EVENTS > 0)
    if (ptcbDel->TCB_peventPtr) {                                       /*  等待事件中                  */
        _EventUnlink(ptcbDel);                                          /*  解等待连                    */
    }
#endif

#if (LW_CFG_EVENTSET_EN > 0) && (LW_CFG_MAX_EVENTSETS > 0)
    pesnPtr = ptcbDel->TCB_pesnPtr;
    if (pesnPtr) {
        _EventSetUnlink(pesnPtr);                                       /*  解事件集                    */
    }
#endif

#if LW_CFG_SMP_EN > 0
    if (ptcbDel->TCB_ptcbWaitStatus ||
        ptcbDel->TCB_plineStatusReqHeader) {                            /*  正在请求其他线程改变状态    */
        _ThreadUnwaitStatus(ptcbDel);
    }
#endif                                                                  /*  LW_CFG_SMP_EN               */
    
    if (__LW_THREAD_IS_READY(ptcbDel)) {                                /*  是否就绪                    */
        __DEL_FROM_READY_RING(ptcbDel, ppcbDel);                        /*  从就绪队列中删除            */
        
    } else {
        if (ptcbDel->TCB_usStatus & LW_THREAD_STATUS_DELAY) {
            __DEL_FROM_WAKEUP_LINE(ptcbDel);                            /*  从等待链中删除              */
            ptcbDel->TCB_ulDelay = 0ul;
        }
        ptcbDel->TCB_usStatus = LW_THREAD_STATUS_RDY;                   /*  防止 Tick 中断激活          */
    }
    
#if LW_CFG_SOFTWARE_WATCHDOG_EN > 0
    if (ptcbDel->TCB_bWatchDogInQ) {
        __DEL_FROM_WATCHDOG_LINE(ptcbDel);                              /*  从 watch dog 中删除         */
        ptcbDel->TCB_ulWatchDog = 0ul;
    }
#endif
    KN_INT_ENABLE(iregInterLevel);
    
    pvFreeLowAddr = (PVOID)ptcbDel->TCB_pstkStackLowAddr;               /*  记录地址                    */
    
#if (LW_CFG_THREAD_PRIVATE_VARS_EN > 0) && (LW_CFG_MAX_THREAD_GLB_VARS > 0)
    _ThreadVarDelete(ptcbDel);                                          /*  删除并恢复私有化的全局变量  */
#endif
    
    iregInterLevel = KN_INT_DISABLE();                                  /*  关闭中断                    */ 
    
    _K_usThreadCounter--;
    _K_ptcbTCBIdTable[usIndex] = LW_NULL;                               /*  TCB 表清0                   */
    
    _List_Line_Del(&ptcbDel->TCB_lineManage, &_K_plineTCBHeader);       /*  从管理练表中删除            */
    
    KN_INT_ENABLE(iregInterLevel);                                      /*  打开中断                    */
    
    if (ptcbDel->TCB_ptcbJoin) {
        _ThreadDisjoin(ptcbDel->TCB_ptcbJoin, ptcbDel);                 /*  退出 join 状态, 不操作就绪表*/
    }
    
    _ThreadDisjoinWakeupAll(ptcbDel, pvRetVal);                         /*  DETACH                      */
    
    __KERNEL_EXIT();                                                    /*  退出内核                    */
    
#if LW_CFG_COROUTINE_EN > 0
    _CoroutineFreeAll(ptcbDel);                                         /*  删除协程内存空间            */
#endif                                                                  /*  LW_CFG_COROUTINE_EN > 0     */
    
    if (bIsInSafe) {
        _DebugFormat(__ERRORMESSAGE_LEVEL, 
                     "thread \"%s\" has been delete in SAFE mode.\r\n",
                     ptcbDel->TCB_cThreadName);
    } else {
        _DebugFormat(__LOGMESSAGE_LEVEL, 
                     "thread \"%s\" has been delete.\r\n",
                     ptcbDel->TCB_cThreadName);
    }
    
    pvVProc = ptcbDel->TCB_pvVProcessContext;                           /*  进程信息                    */
    
    if (ptcbDel->TCB_ucStackAutoAllocFlag) {                            /*  是否是内核堆开辟堆栈        */
#if LW_CFG_MODULELOADER_EN > 0
        vprocStackFree(ptcbDel, pvFreeLowAddr, LW_FALSE);
#else
        __KHEAP_FREE(pvFreeLowAddr);                                    /*  释放堆栈空间                */
#endif                                                                  /*  LW_CFG_MODULELOADER_EN > 0  */
    }
    
    _TCBDestroy(ptcbDel);                                               /*  销毁 TCB                    */
    
    __KERNEL_MODE_PROC(
        _Free_Tcb_Object(ptcbDel);                                      /*  释放 ID                     */
    );
Пример #10
0
/*********************************************************************************************************
** 函数名称: API_InterVectorConnectEx
** 功能描述: 设置系统指定向量中断服务
** 输 入  : ulVector                      中断向量号
**           pfuncIsr                      服务函数
**           pfuncClear                    附加中断清除函数(可为 NULL)
**           pvArg                         服务函数参数
**           pcName                        中断服务名称
** 输 出  : ERROR CODE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API
ULONG  API_InterVectorConnectEx (ULONG              ulVector,
                                 PINT_SVR_ROUTINE   pfuncIsr,
                                 VOIDFUNCPTR        pfuncClear,
                                 PVOID              pvArg,
                                 CPCHAR             pcName)
{
    INTREG              iregInterLevel;
    BOOL                bNeedFree;
    
    PLW_LIST_LINE       plineTemp;
    PLW_CLASS_INTACT    piactionOld;
    PLW_CLASS_INTACT    piaction;
    PLW_CLASS_INTDESC   pidesc;
    
    if (LW_CPU_GET_CUR_NESTING()) {                                     /*  不能在中断中调用            */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n");
        _ErrorHandle(ERROR_KERNEL_IN_ISR);
        return  (ERROR_KERNEL_IN_ISR);
    }
    
    INTER_SHOWLOCK_CREATE();

    if (_Object_Name_Invalid(pcName)) {                                 /*  检查名字有效性              */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "name too long.\r\n");
        _ErrorHandle(ERROR_KERNEL_PNAME_TOO_LONG);
        return  (ERROR_KERNEL_PNAME_TOO_LONG);
    }
    
    if (_Inter_Vector_Invalid(ulVector)) {
        _ErrorHandle(ERROR_KERNEL_VECTOR_NULL);
        return  (ERROR_KERNEL_VECTOR_NULL);
    }
    
    if (pfuncIsr == LW_NULL) {
        _ErrorHandle(ERROR_KERNEL_VECTOR_NULL);
        return  (ERROR_KERNEL_VECTOR_NULL);
    }
    
    piaction = (PLW_CLASS_INTACT)__KHEAP_ALLOC(sizeof(LW_CLASS_INTACT));
    if (piaction == LW_NULL) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "kernel low memory.\r\n");
        _ErrorHandle(ERROR_KERNEL_LOW_MEMORY);
        return  (ERROR_KERNEL_LOW_MEMORY);
    }
    lib_bzero(piaction, sizeof(LW_CLASS_INTACT));
    
    piaction->IACT_pfuncIsr   = pfuncIsr;
    piaction->IACT_pfuncClear = pfuncClear;
    piaction->IACT_pvArg      = pvArg;
    if (pcName) {
        lib_strcpy(piaction->IACT_cInterName, pcName);
    } else {
        piaction->IACT_cInterName[0] = PX_EOS;
    }
    
    pidesc = LW_IVEC_GET_IDESC(ulVector);
    
    LW_SPIN_LOCK_QUICK(&pidesc->IDESC_slLock, &iregInterLevel);         /*  关闭中断同时锁住 spinlock   */

    if (LW_IVEC_GET_FLAG(ulVector) & LW_IRQ_FLAG_QUEUE) {               /*  队列服务类型向量            */
        for (plineTemp  = pidesc->IDESC_plineAction;
             plineTemp != LW_NULL;
             plineTemp  = _list_line_get_next(plineTemp)) {
             
            piactionOld = _LIST_ENTRY(plineTemp, LW_CLASS_INTACT, IACT_plineManage);
            if ((piactionOld->IACT_pfuncIsr == pfuncIsr) &&
                (piactionOld->IACT_pvArg    == pvArg)) {                /*  中断处理函数是否被重复安装  */
                break;
            }
        }
        
        if (plineTemp) {                                                /*  此中断被重复安装            */
            bNeedFree = LW_TRUE;
        
        } else {
            _List_Line_Add_Ahead(&piaction->IACT_plineManage,
                                 &pidesc->IDESC_plineAction);
            bNeedFree = LW_FALSE;
        }
    } else {                                                            /*  非队列服务式中断向量        */
        if (pidesc->IDESC_plineAction) {
            piactionOld = _LIST_ENTRY(pidesc->IDESC_plineAction, 
                                      LW_CLASS_INTACT, 
                                      IACT_plineManage);
            piactionOld->IACT_pfuncIsr   = piaction->IACT_pfuncIsr;
            piactionOld->IACT_pfuncClear = piaction->IACT_pfuncClear;
            piactionOld->IACT_pvArg      = piaction->IACT_pvArg;
            lib_strcpy(piactionOld->IACT_cInterName, piaction->IACT_cInterName);
            bNeedFree = LW_TRUE;
        
        } else {
            _List_Line_Add_Ahead(&piaction->IACT_plineManage,
                                 &pidesc->IDESC_plineAction);
            bNeedFree = LW_FALSE;
        }
    }
    
    LW_SPIN_UNLOCK_QUICK(&pidesc->IDESC_slLock, iregInterLevel);        /*  打开中断, 同时打开 spinlock */
    
    if (bNeedFree) {
        __KHEAP_FREE(piaction);
    }
    
    _DebugFormat(__LOGMESSAGE_LEVEL, "IRQ %d : %s connect : 0x%p\r\n",
                 (INT)ulVector, (pcName ? pcName : ""), (PVOID)pfuncIsr);

    return  (ERROR_NONE);
}
Пример #11
0
/*********************************************************************************************************
** 函数名称: API_CoroutineExit
** 功能描述: 在当前线程正在执行的协程删除
** 输 入  : NONE
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
ULONG   API_CoroutineExit (VOID)
{
             INTREG                 iregInterLevel;
             
             PLW_CLASS_CPU          pcpuCur;
             PLW_CLASS_TCB          ptcbCur;
    REGISTER PLW_CLASS_COROUTINE    pcrcbExit;
    REGISTER PLW_CLASS_COROUTINE    pcrcbNext;
    REGISTER PLW_LIST_RING          pringNext;
    
    if (!LW_SYS_STATUS_IS_RUNNING()) {                                  /*  系统必须已经启动            */
        _ErrorHandle(ERROR_KERNEL_NOT_RUNNING);
        return  (ERROR_KERNEL_NOT_RUNNING);
    }
    
    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);
    
    pcrcbExit = _LIST_ENTRY(ptcbCur->TCB_pringCoroutineHeader, 
                            LW_CLASS_COROUTINE, 
                            COROUTINE_ringRoutine);                     /*  获得当前协程                */
    
    if (&pcrcbExit->COROUTINE_ringRoutine == 
        _list_ring_get_next(&pcrcbExit->COROUTINE_ringRoutine)) {       /*  仅有这一个协程              */

#if LW_CFG_THREAD_DEL_EN > 0
        API_ThreadExit(LW_NULL);
#endif                                                                  /*  LW_CFG_THREAD_DEL_EN > 0    */
        return  (ERROR_NONE);
    }
    
    pringNext = _list_ring_get_next(&pcrcbExit->COROUTINE_ringRoutine);
    pcrcbNext = _LIST_ENTRY(pringNext, LW_CLASS_COROUTINE, 
                            COROUTINE_ringRoutine);                     /*  获得下一个协程              */

    LW_SPIN_LOCK_QUICK(&ptcbCur->TCB_slLock, &iregInterLevel);
    _List_Ring_Del(&pcrcbExit->COROUTINE_ringRoutine,
                   &ptcbCur->TCB_pringCoroutineHeader);                 /*  从协程表中删除              */
    LW_SPIN_UNLOCK_QUICK(&ptcbCur->TCB_slLock, iregInterLevel);
    
    ptcbCur->TCB_pringCoroutineHeader = pringNext;                      /*  转动到下一个协程            */
    
    MONITOR_EVT_LONG2(MONITOR_EVENT_ID_COROUTINE, MONITOR_EVENT_COROUTINE_DELETE, 
                      ptcbCur->TCB_ulId, pcrcbExit, LW_NULL);
    
    if (pcrcbExit->COROUTINE_bIsNeedFree) {
        __KHEAP_FREE(pcrcbExit->COROUTINE_pstkStackLowAddr);            /*  释放内存                    */
    }
    
    iregInterLevel = KN_INT_DISABLE();                                  /*  关闭中断                    */
    
    INIT_DUMMY_STACK();
    pcpuCur                = LW_CPU_GET_CUR();
    pcpuCur->CPU_pcrcbCur  = &_K_pcrcbDummy;
    pcpuCur->CPU_pcrcbNext = pcrcbNext;
    archCrtCtxSwitch(LW_CPU_GET_CUR());                                 /*  协程切换                    */
    
    KN_INT_ENABLE(iregInterLevel);                                      /*  打开中断                    */

    return  (ERROR_NONE);                                               /*  理论上是无法运行到这里的    */
}