/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: _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); }
/********************************************************************************************************* ** 函数名称: _JobQueueDelete ** 功能描述: 删除一个工作队列 ** 输 入 : pjobq 工作队列控制块 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID _jobQueueDelete (PLW_JOB_QUEUE pjobq) { if (pjobq->JOBQ_ulSync) { API_SemaphoreBDelete(&pjobq->JOBQ_ulSync); } __KHEAP_FREE(pjobq); }
/********************************************************************************************************* ** 函数名称: _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 */ }
/********************************************************************************************************* ** 函数名称: 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); } }
/********************************************************************************************************* ** 函数名称: 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 */ }
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: _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; } }
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 */ );
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: 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); /* 理论上是无法运行到这里的 */ }