/********************************************************************************************************* ** 函数名称: __canWriteQueue ** 功能描述: 向队列中写入数据 ** 输 入 : ** pcanDev 指向设备结构 ** pcanq 队列指针 ** pcanframe 指向要写入数据的指针 ** iNumber 要写入的个数 ** 输 出 : 实际写入的个数 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __canWriteQueue (__CAN_DEV *pcanDev, __PCAN_QUEUE pcanq, PCAN_FRAME pcanframe, INT iNumber) { INT i = 0; INTREG iregInterLevel; while (iNumber) { /* * 关中断,将关中断放在这里是为了关中断时间可预测 */ LW_SPIN_LOCK_QUICK(&pcanDev->CAN_slLock, &iregInterLevel); if (pcanq->CANQ_uiCounter < pcanq->CANQ_uiMaxFrame) { /* 更新接收队列 */ pcanq->CANQ_uiCounter++; pcanq->CANQ_pcanframeIn[0] = *pcanframe; pcanq->CANQ_pcanframeIn++; if (pcanq->CANQ_pcanframeIn >= pcanq->CANQ_pcanframeEnd) { pcanq->CANQ_pcanframeIn = pcanq->CANQ_pcanframeBuffer; } iNumber--; pcanframe++; i++; } else { LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); break; } LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); } return (i); }
/********************************************************************************************************* ** 函数名称: __canReadQueue ** 功能描述: 向队列中写入数据 ** 输 入 : ** pcanDev 指向设备结构 ** pcanq 队列指针 ** pcanframe 指向要读出数据的指针 ** iNumber 要读出的个数 ** 输 出 : 实际读出的个数 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __canReadQueue (__CAN_DEV *pcanDev, __PCAN_QUEUE pcanq, PCAN_FRAME pcanframe, INT iNumber) { INT i = 0; INTREG iregInterLevel; while (iNumber) { /* * 关中断,将关中断放在这里是为了关中断时间可预测 */ LW_SPIN_LOCK_QUICK(&pcanDev->CAN_slLock, &iregInterLevel); if (pcanq->CANQ_uiCounter > 0) { pcanq->CANQ_uiCounter--; *pcanframe = pcanq->CANQ_pcanframeOut[0]; pcanq->CANQ_pcanframeOut++; if (pcanq->CANQ_pcanframeOut == pcanq->CANQ_pcanframeEnd) { pcanq->CANQ_pcanframeOut = pcanq->CANQ_pcanframeBuffer; } iNumber--; pcanframe++; i++; } else { LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); break; } LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); } return (i); }
/********************************************************************************************************* ** 函数名称: __canWrite ** 功能描述: 写 CAN 设备 ** 输 入 : ** pcanDev CAN 设备 ** pcanframe 写缓冲区指针 ** stNbyte 发送缓冲区字节数 ** 输 出 : 返回实际写入的个数 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static ssize_t __canWrite (__CAN_DEV *pcanDev, PCAN_FRAME pcanframe, size_t stNbyte) { INTREG iregInterLevel; INT iFrameput; INT i = 0; ULONG ulError; __CAN_PORT *pcanport = (__CAN_PORT *)pcanDev; size_t stNumber = stNbyte / sizeof(CAN_FRAME); /* 转换为数据包个数 */ while (stNumber > 0) { ulError = API_SemaphoreBPend(pcanDev->CAN_ulSendSemB, pcanDev->CAN_ulSendTimeout); if (ulError) { _ErrorHandle(ERROR_IO_DEVICE_TIMEOUT); /* 超时 */ return ((ssize_t)(i * sizeof(CAN_FRAME))); } CANDEV_LOCK(pcanDev); /* 等待设备使用权 */ LW_SPIN_LOCK_QUICK(&pcanDev->CAN_slLock, &iregInterLevel); if (pcanDev->CAN_uiBusState != CAN_DEV_BUS_ERROR_NONE) { /* 总线错误 */ LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); CANDEV_UNLOCK(pcanDev); _ErrorHandle(EIO); return ((ssize_t)(i * sizeof(CAN_FRAME))); } LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); iFrameput = __canWriteQueue(pcanDev, pcanDev->CAN_pcanqSendQueue, pcanframe, (INT)stNumber); __canTxStartup(pcanport); /* 启动一次发送 */ stNumber -= (size_t)iFrameput; /* 剩余需要发送的数据 */ pcanframe += iFrameput; /* 新的缓冲区起始地址 */ i += iFrameput; LW_SPIN_LOCK_QUICK(&pcanDev->CAN_slLock, &iregInterLevel); /* 关闭中断 */ if (__canQFreeNum(pcanDev->CAN_pcanqSendQueue) > 0) { LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); /* 打开中断 */ API_SemaphoreBPost(pcanDev->CAN_ulSendSemB); /* 缓冲区还有空间 */ } else { LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); /* 打开中断 */ } CANDEV_UNLOCK(pcanDev); /* 释放设备使用权 */ } return ((ssize_t)(i * sizeof(CAN_FRAME))); }
/********************************************************************************************************* ** 函数名称: __canRead ** 功能描述: 读 CAN 设备 ** 输 入 : ** pcanDev CAN 设备 ** pcanframe CAN发送缓冲区指针 ** stNbyte 读取缓冲区的字节数 ** 输 出 : 返回实际读取的个数 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static ssize_t __canRead (__CAN_DEV *pcanDev, PCAN_FRAME pcanframe, size_t stNbyte) { INTREG iregInterLevel; REGISTER ssize_t sstNRead; size_t stNumber = stNbyte / sizeof(CAN_FRAME); /* 转换为数据包个数 */ ULONG ulError; for (;;) { ulError = API_SemaphoreBPend(pcanDev->CAN_ulRcvSemB, pcanDev->CAN_ulRecvTimeout); if (ulError) { _ErrorHandle(ERROR_IO_DEVICE_TIMEOUT); /* 超时 */ return (0); } CANDEV_LOCK(pcanDev); /* 等待设备使用权 */ LW_SPIN_LOCK_QUICK(&pcanDev->CAN_slLock, &iregInterLevel); /* 关闭中断 */ if (__canQCount(pcanDev->CAN_pcanqRecvQueue)) { /* 检查是否有数据 */ break; } else { if (pcanDev->CAN_uiBusState != CAN_DEV_BUS_ERROR_NONE) { /* 总线错误 */ LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); CANDEV_UNLOCK(pcanDev); _ErrorHandle(EIO); return (0); } } LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); /* 打开中断 */ CANDEV_UNLOCK(pcanDev); /* 释放设备使用权 */ } LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); sstNRead = __canReadQueue(pcanDev, pcanDev->CAN_pcanqRecvQueue, pcanframe, (INT)stNumber); LW_SPIN_LOCK_QUICK(&pcanDev->CAN_slLock, &iregInterLevel); if (__canQCount(pcanDev->CAN_pcanqRecvQueue)) { /* 是否还有数据 */ LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); API_SemaphoreBPost(pcanDev->CAN_ulRcvSemB); /* 通知其他等待读的线程 */ } else { LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); } CANDEV_UNLOCK(pcanDev); /* 释放设备使用权 */ return (sstNRead * sizeof(CAN_FRAME)); }
static LW_INLINE BOOL __evtfd_can_write (PLW_EVTFD_FILE pevtfdfil) { INTREG iregInterLevel; LW_SPIN_LOCK_QUICK(&pevtfdfil->EF_slLock, &iregInterLevel); if ((LW_EVENTFD_MAX_CNT - pevtfdfil->EF_u64Counter) > 1) { LW_SPIN_UNLOCK_QUICK(&pevtfdfil->EF_slLock, iregInterLevel); return (LW_TRUE); } LW_SPIN_UNLOCK_QUICK(&pevtfdfil->EF_slLock, iregInterLevel); return (LW_FALSE); }
LW_API ULONG API_CpuDown (ULONG ulCPUId) { INTREG iregInterLevel; PLW_CLASS_CPU pcpu; if ((ulCPUId == 0) || (ulCPUId >= LW_NCPUS)) { _ErrorHandle(EINVAL); return (EINVAL); } __KERNEL_ENTER(); pcpu = LW_CPU_GET(ulCPUId); if (!LW_CPU_IS_ACTIVE(pcpu) || (LW_CPU_GET_IPI_PEND2(pcpu) & LW_IPI_DOWN_MSK)) { __KERNEL_EXIT(); return (ERROR_NONE); } LW_SPIN_LOCK_QUICK(&pcpu->CPU_slIpi, &iregInterLevel); LW_CPU_ADD_IPI_PEND2(pcpu, LW_IPI_DOWN_MSK); LW_SPIN_UNLOCK_QUICK(&pcpu->CPU_slIpi, iregInterLevel); _ThreadOffAffinity(pcpu); /* 关闭与此 CPU 有关的亲和度 */ __KERNEL_EXIT(); _SmpSendIpi(ulCPUId, LW_IPI_DOWN, 0, LW_FALSE); /* 使用核间中断通知 CPU 停止 */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: API_InterVectorGetFlag ** 功能描述: 获得指定中断向量的特性. ** 输 入 : ulVector 中断向量号 ** *pulFlag 特性 ** 输 出 : ERROR CODE ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API ULONG API_InterVectorGetFlag (ULONG ulVector, ULONG *pulFlag) { INTREG iregInterLevel; PLW_CLASS_INTDESC pidesc; if (_Inter_Vector_Invalid(ulVector)) { _ErrorHandle(ERROR_KERNEL_VECTOR_NULL); return (ERROR_KERNEL_VECTOR_NULL); } if (!pulFlag) { _ErrorHandle(ERROR_KERNEL_MEMORY); return (ERROR_KERNEL_MEMORY); } pidesc = LW_IVEC_GET_IDESC(ulVector); LW_SPIN_LOCK_QUICK(&pidesc->IDESC_slLock, &iregInterLevel); /* 关闭中断同时锁住 spinlock */ *pulFlag = LW_IVEC_GET_FLAG(ulVector); LW_SPIN_UNLOCK_QUICK(&pidesc->IDESC_slLock, iregInterLevel); /* 打开中断, 同时打开 spinlock */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: API_InterVectorSetFlag ** 功能描述: 设置指定中断向量的特性. ** 输 入 : ulVector 中断向量号 ** ulFlag 特性 ** 输 出 : ERROR CODE ** 全局变量: ** 调用模块: ** 注 意 : LW_IRQ_FLAG_QUEUE 必须在安装任何一个驱动前设置, 且设置后不再能取消. 最好放在 bspIntInit() 函数中完成设置. API 函数 *********************************************************************************************************/ LW_API ULONG API_InterVectorSetFlag (ULONG ulVector, ULONG ulFlag) { INTREG iregInterLevel; PLW_CLASS_INTDESC pidesc; if (_Inter_Vector_Invalid(ulVector)) { _ErrorHandle(ERROR_KERNEL_VECTOR_NULL); return (ERROR_KERNEL_VECTOR_NULL); } 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) { /* 已经是 QUEUE 类型中断向量 */ LW_IVEC_SET_FLAG(ulVector, ulFlag | LW_IRQ_FLAG_QUEUE); } else { LW_IVEC_SET_FLAG(ulVector, ulFlag); } LW_SPIN_UNLOCK_QUICK(&pidesc->IDESC_slLock, iregInterLevel); /* 打开中断, 同时打开 spinlock */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: _jobQueueExec ** 功能描述: 执行工作队列中的工作 ** 输 入 : pjobq 工作队列控制块 ** ulTimeout 等待超时时间 ** 输 出 : 不为 ERROR_NONE 表示超时 ** 全局变量: ** 调用模块: *********************************************************************************************************/ ULONG _jobQueueExec (PLW_JOB_QUEUE pjobq, ULONG ulTimeout) { INTREG iregInterLevel; PLW_JOB_MSG pjobmsg; LW_JOB_MSG jobmsgRun; if (pjobq->JOBQ_ulSync) { for (;;) { if (API_SemaphoreBPend(pjobq->JOBQ_ulSync, ulTimeout)) { return (ERROR_THREAD_WAIT_TIMEOUT); } LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel); if (pjobq->JOBQ_uiCnt) { break; } LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel); } } else { LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel); } while (pjobq->JOBQ_uiCnt) { pjobmsg = &pjobq->JOBQ_pjobmsgQueue[pjobq->JOBQ_uiOut]; jobmsgRun = *pjobmsg; if (pjobq->JOBQ_uiOut == (pjobq->JOBQ_uiSize - 1)) { pjobq->JOBQ_uiOut = 0; } else { pjobq->JOBQ_uiOut++; } pjobq->JOBQ_uiCnt--; LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel); if (jobmsgRun.JOBM_pfuncFunc) { jobmsgRun.JOBM_pfuncFunc(jobmsgRun.JOBM_pvArg[0], jobmsgRun.JOBM_pvArg[1], jobmsgRun.JOBM_pvArg[2], jobmsgRun.JOBM_pvArg[3], jobmsgRun.JOBM_pvArg[4], jobmsgRun.JOBM_pvArg[5]); } LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel); } LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: _JobQueueAdd ** 功能描述: 添加一个工作到工作队列 ** 输 入 : pjobq 工作队列控制块 ** pfunc 要执行的函数 ** pvArg0 ~ 5 函数参数 ** 输 出 : ERROR ** 全局变量: ** 调用模块: *********************************************************************************************************/ ULONG _jobQueueAdd (PLW_JOB_QUEUE pjobq, VOIDFUNCPTR pfunc, PVOID pvArg0, PVOID pvArg1, PVOID pvArg2, PVOID pvArg3, PVOID pvArg4, PVOID pvArg5) { INTREG iregInterLevel; PLW_JOB_MSG pjobmsg; LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel); if (pjobq->JOBQ_uiCnt == pjobq->JOBQ_uiSize) { pjobq->JOBQ_stLost++; LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel); _DebugHandle(__ERRORMESSAGE_LEVEL, "job message lost.\r\n"); return (ENOSPC); } pjobmsg = &pjobq->JOBQ_pjobmsgQueue[pjobq->JOBQ_uiIn]; pjobmsg->JOBM_pfuncFunc = pfunc; pjobmsg->JOBM_pvArg[0] = pvArg0; pjobmsg->JOBM_pvArg[1] = pvArg1; pjobmsg->JOBM_pvArg[2] = pvArg2; pjobmsg->JOBM_pvArg[3] = pvArg3; pjobmsg->JOBM_pvArg[4] = pvArg4; pjobmsg->JOBM_pvArg[5] = pvArg5; if (pjobq->JOBQ_uiIn == (pjobq->JOBQ_uiSize - 1)) { pjobq->JOBQ_uiIn = 0; } else { pjobq->JOBQ_uiIn++; } pjobq->JOBQ_uiCnt++; LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel); if (pjobq->JOBQ_ulSync) { API_SemaphoreBPost(pjobq->JOBQ_ulSync); } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __canTxStartup ** 功能描述: 启动发送函数 ** 输 入 : ** pcanport CAN 设备 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID __canTxStartup (__CAN_PORT *pcanport) { INTREG iregInterLevel; if (pcanport->CANPORT_can.CAN_canstatWriteState.CANSTAT_bBufEmpty == LW_TRUE) { LW_SPIN_LOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, &iregInterLevel); /* 关闭中断 */ if (pcanport->CANPORT_can.CAN_canstatWriteState.CANSTAT_bBufEmpty == LW_TRUE) { pcanport->CANPORT_can.CAN_canstatWriteState.CANSTAT_bBufEmpty = LW_FALSE; LW_SPIN_UNLOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, iregInterLevel); /* 打开中断 */ /* 启动发送 */ pcanport->CANPORT_pcanchan->pDrvFuncs->txStartup(pcanport->CANPORT_pcanchan); return; } LW_SPIN_UNLOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, iregInterLevel); /* 打开中断 */ } }
/********************************************************************************************************* ** 函数名称: _SmpProcBoot ** 功能描述: 处理核间中断其他核正在启动 (当前未处理) ** 输 入 : pcpuCur 当前 CPU ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID _SmpProcBoot (PLW_CLASS_CPU pcpuCur) { INTREG iregInterLevel; LW_SPIN_LOCK_QUICK(&pcpuCur->CPU_slIpi, &iregInterLevel); /* 锁定 CPU */ LW_CPU_CLR_IPI_PEND2(pcpuCur, LW_IPI_BOOT_MSK); /* 清除 */ LW_SPIN_UNLOCK_QUICK(&pcpuCur->CPU_slIpi, iregInterLevel); /* 解锁 CPU */ LW_SPINLOCK_NOTIFY(); }
static VOID _SmpProcFlushCache (PLW_CLASS_CPU pcpuCur) { INTREG iregInterLevel; API_CacheFlush(DATA_CACHE, (PVOID)0, (size_t)~0); LW_SPIN_LOCK_QUICK(&pcpuCur->CPU_slIpi, &iregInterLevel); /* 锁定 CPU */ LW_CPU_CLR_IPI_PEND2(pcpuCur, LW_IPI_FLUSH_CACHE_MSK); /* 清除 */ LW_SPIN_UNLOCK_QUICK(&pcpuCur->CPU_slIpi, iregInterLevel); /* 解锁 CPU */ LW_SPINLOCK_NOTIFY(); }
/********************************************************************************************************* ** 函数名称: 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) { _StackFree(ptcbCur, pcrcbDel->COROUTINE_pstkStackLowAddr, LW_TRUE); /* 释放内存 */ } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __canFlushRd ** 功能描述: 清除 CAN 设备读缓冲区 ** 输 入 : ** pcanport CAN 设备 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID __canFlushRd (__CAN_PORT *pcanport) { INTREG iregInterLevel; CANPORT_LOCK(pcanport); /* 等待设备使用权 */ LW_SPIN_LOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, &iregInterLevel); __canFlushQueue(pcanport->CANPORT_can.CAN_pcanqRecvQueue); /* 清除缓冲区 */ LW_SPIN_UNLOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, iregInterLevel); API_SemaphoreBClear(pcanport->CANPORT_can.CAN_ulRcvSemB); /* 清除读同步 */ CANPORT_UNLOCK(pcanport); /* 释放设备使用权 */ }
static VOID _SmpProcFlushTlb (PLW_CLASS_CPU pcpuCur) { INTREG iregInterLevel; PLW_MMU_CONTEXT pmmuctx = __vmmGetCurCtx(); iregInterLevel = KN_INT_DISABLE(); __VMM_MMU_INV_TLB(pmmuctx); /* 无效快表 */ KN_INT_ENABLE(iregInterLevel); LW_SPIN_LOCK_QUICK(&pcpuCur->CPU_slIpi, &iregInterLevel); /* 锁定 CPU */ LW_CPU_CLR_IPI_PEND2(pcpuCur, LW_IPI_FLUSH_TLB_MSK); /* 清除 */ LW_SPIN_UNLOCK_QUICK(&pcpuCur->CPU_slIpi, iregInterLevel); /* 解锁 CPU */ LW_SPINLOCK_NOTIFY(); }
/********************************************************************************************************* ** 函数名称: _jobQueueFlush ** 功能描述: 清空工作队列 ** 输 入 : pjobq 工作队列控制块 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID _jobQueueFlush (PLW_JOB_QUEUE pjobq) { INTREG iregInterLevel; if (pjobq->JOBQ_ulSync) { API_SemaphoreBClear(pjobq->JOBQ_ulSync); } LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel); pjobq->JOBQ_uiIn = 0; pjobq->JOBQ_uiOut = 0; pjobq->JOBQ_uiCnt = 0; LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel); }
/********************************************************************************************************* ** 函数名称: __ataDevChk ** 功能描述: ata设备检测函数 ** 输 入 : patactrl ATA控制器结构指针 ** bDevIsExist 设备是否存在标志 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __ataDevChk (__PATA_CTRL patactrl, BOOL bDevIsExist) { INTREG iregInterLevel; if (!patactrl) { _DebugHandle(__ERRORMESSAGE_LEVEL, "parameter error.\r\n"); _ErrorHandle(EINVAL); return (PX_ERROR); } LW_SPIN_LOCK_QUICK(&patactrl->ATACTRL_slLock, &iregInterLevel); patactrl->ATACTRL_bIsExist = bDevIsExist; LW_SPIN_UNLOCK_QUICK(&patactrl->ATACTRL_slLock, iregInterLevel); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __ataWrite ** 功能描述: ata设备写操作回调 ** 输 入 : patactrl ATA控制器节点结构指针 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __ataWrite (__PATA_CTRL patactrl) { INTREG iregInterLevel; if (!patactrl) { _DebugHandle(__ERRORMESSAGE_LEVEL, "parameter error.\r\n"); _ErrorHandle(EINVAL); return (PX_ERROR); } LW_SPIN_LOCK_QUICK(&patactrl->ATACTRL_slLock, &iregInterLevel); patactrl->ATACTRL_iIntStatus = __ATA_CTRL_INBYTE(patactrl, __ATA_STATUS(patactrl)); LW_SPIN_UNLOCK_QUICK(&patactrl->ATACTRL_slLock, iregInterLevel); API_SemaphoreBPost(patactrl->ATACTRL_ulSyncSem); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __canFlushWrt ** 功能描述: 清除 CAN 设备写缓冲区 ** 输 入 : ** pcanport CAN 设备 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID __canFlushWrt (__CAN_PORT *pcanport) { INTREG iregInterLevel; CANPORT_LOCK(pcanport); /* 等待设备使用权 */ LW_SPIN_LOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, &iregInterLevel); __canFlushQueue(pcanport->CANPORT_can.CAN_pcanqSendQueue); /* 清除缓冲区 */ pcanport->CANPORT_can.CAN_canstatWriteState.CANSTAT_bBufEmpty = LW_TRUE; /* 发送队列空 */ LW_SPIN_UNLOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, iregInterLevel); API_SemaphoreBPost(pcanport->CANPORT_can.CAN_ulSendSemB); /* 通知线程可写 */ CANPORT_UNLOCK(pcanport); /* 释放设备使用权 */ SEL_WAKE_UP_ALL(&pcanport->CANPORT_can.CAN_selwulList, SELWRITE); /* 通知 select 线程可写 */ }
/********************************************************************************************************* ** 函数名称: __canSetBusState ** 功能描述: 设置 CAN 设备的总线状态 ** 输 入 : ** pcanDev CAN 设备 ** iState 总线状态 ** 输 出 : ERROR_NONE or PX_ERROR ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID __canSetBusState (__CAN_DEV *pcanDev, INT iState) { INTREG iregInterLevel; __CAN_PORT *pcanport = (__CAN_PORT *)pcanDev; LW_SPIN_LOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, &iregInterLevel); if (iState) { pcanDev->CAN_uiBusState |= iState; } else { pcanDev->CAN_uiBusState = CAN_DEV_BUS_ERROR_NONE; } LW_SPIN_UNLOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, iregInterLevel); if (pcanDev->CAN_uiBusState != CAN_DEV_BUS_ERROR_NONE) { /* 总线异常 */ API_SemaphoreBFlush(pcanDev->CAN_ulSendSemB, LW_NULL); /* 激活写等待任务 */ API_SemaphoreBFlush(pcanDev->CAN_ulRcvSemB, LW_NULL); /* 激活读等待任务 */ SEL_WAKE_UP_ALL(&pcanDev->CAN_selwulList, SELEXCEPT); /* select() 激活 */ } }
/********************************************************************************************************* ** 函数名称: __canITx ** 功能描述: 从发送缓冲区中读出一个数据 ** 输 入 : ** pcanDev CAN 设备 ** pcanframe 指向待读出的数据 ** 输 出 : ERROR_NONE or PX_ERROR ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __canITx (__CAN_DEV *pcanDev, PCAN_FRAME pcanframe) { INTREG iregInterLevel; INT iTemp = 0; if (!pcanDev || !pcanframe) { return (PX_ERROR); } iTemp = __canReadQueue(pcanDev, pcanDev->CAN_pcanqSendQueue, pcanframe, 1); /* 从发送队列中读取一帧数据 */ LW_SPIN_LOCK_QUICK(&pcanDev->CAN_slLock, &iregInterLevel); if (iTemp <= 0) { pcanDev->CAN_canstatWriteState.CANSTAT_bBufEmpty = LW_TRUE; /* 发送队列空 */ } LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); API_SemaphoreBPost(pcanDev->CAN_ulSendSemB); /* 释放信号量 */ SEL_WAKE_UP_ALL(&pcanDev->CAN_selwulList, SELWRITE); /* 释放所有等待写的线程 */ return ((iTemp) ? (ERROR_NONE) : (PX_ERROR)); }
/********************************************************************************************************* ** 函数名称: 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) { _StackFree(ptcbCur, pcrcbExit->COROUTINE_pstkStackLowAddr, LW_TRUE); /* 释放内存 */ } 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); /* 理论上是无法运行到这里的 */ }
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: _JobQueueDel ** 功能描述: 从工作队列中删除一个工作 (懒惰删除) ** 输 入 : pjobq 工作队列控制块 ** uiMatchArgNum 匹配参数的个数 ** pfunc 要删除的函数 ** pvArg0 ~ 5 函数参数 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID _jobQueueDel (PLW_JOB_QUEUE pjobq, UINT uiMatchArgNum, VOIDFUNCPTR pfunc, PVOID pvArg0, PVOID pvArg1, PVOID pvArg2, PVOID pvArg3, PVOID pvArg4, PVOID pvArg5) { INTREG iregInterLevel; UINT i = 0; PLW_JOB_MSG pjobmsg; LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel); pjobmsg = &pjobq->JOBQ_pjobmsgQueue[pjobq->JOBQ_uiOut]; for (i = 0; i < pjobq->JOBQ_uiCnt; i++) { switch (uiMatchArgNum) { case 0: if (pjobmsg->JOBM_pfuncFunc == pfunc) { pjobmsg->JOBM_pfuncFunc = LW_NULL; } break; case 1: if ((pjobmsg->JOBM_pfuncFunc == pfunc) && (pjobmsg->JOBM_pvArg[0] == pvArg0)) { pjobmsg->JOBM_pfuncFunc = LW_NULL; } break; case 2: if ((pjobmsg->JOBM_pfuncFunc == pfunc) && (pjobmsg->JOBM_pvArg[0] == pvArg0) && (pjobmsg->JOBM_pvArg[1] == pvArg1)) { pjobmsg->JOBM_pfuncFunc = LW_NULL; } break; case 3: if ((pjobmsg->JOBM_pfuncFunc == pfunc) && (pjobmsg->JOBM_pvArg[0] == pvArg0) && (pjobmsg->JOBM_pvArg[1] == pvArg1) && (pjobmsg->JOBM_pvArg[2] == pvArg2)) { pjobmsg->JOBM_pfuncFunc = LW_NULL; } break; case 4: if ((pjobmsg->JOBM_pfuncFunc == pfunc) && (pjobmsg->JOBM_pvArg[0] == pvArg0) && (pjobmsg->JOBM_pvArg[1] == pvArg1) && (pjobmsg->JOBM_pvArg[2] == pvArg2) && (pjobmsg->JOBM_pvArg[3] == pvArg3)) { pjobmsg->JOBM_pfuncFunc = LW_NULL; } break; case 5: if ((pjobmsg->JOBM_pfuncFunc == pfunc) && (pjobmsg->JOBM_pvArg[0] == pvArg0) && (pjobmsg->JOBM_pvArg[1] == pvArg1) && (pjobmsg->JOBM_pvArg[2] == pvArg2) && (pjobmsg->JOBM_pvArg[3] == pvArg3) && (pjobmsg->JOBM_pvArg[4] == pvArg4)) { pjobmsg->JOBM_pfuncFunc = LW_NULL; } break; case 6: if ((pjobmsg->JOBM_pfuncFunc == pfunc) && (pjobmsg->JOBM_pvArg[0] == pvArg0) && (pjobmsg->JOBM_pvArg[1] == pvArg1) && (pjobmsg->JOBM_pvArg[2] == pvArg2) && (pjobmsg->JOBM_pvArg[3] == pvArg3) && (pjobmsg->JOBM_pvArg[4] == pvArg4) && (pjobmsg->JOBM_pvArg[5] == pvArg5)) { pjobmsg->JOBM_pfuncFunc = LW_NULL; } break; } pjobmsg++; if (pjobmsg > &pjobq->JOBQ_pjobmsgQueue[pjobq->JOBQ_uiSize - 1]) { pjobmsg = &pjobq->JOBQ_pjobmsgQueue[0]; } } LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel); }
/********************************************************************************************************* ** 函数名称: _evtfdRead ** 功能描述: 读 eventfd 设备 ** 输 入 : pevtfdfil eventfd 文件 ** pcBuffer 接收缓冲区 ** stMaxBytes 接收缓冲区大小 ** 输 出 : ERROR ** 全局变量: ** 调用模块: *********************************************************************************************************/ static ssize_t _evtfdRead (PLW_EVTFD_FILE pevtfdfil, PCHAR pcBuffer, size_t stMaxBytes) { INTREG iregInterLevel; ULONG ulLwErrCode; ULONG ulTimeout; BOOL bRelease = LW_FALSE; if (!pcBuffer || (stMaxBytes < sizeof(UINT64))) { _ErrorHandle(EINVAL); return (PX_ERROR); } if (LW_CPU_GET_CUR_NESTING()) { /* 是否在中断中调用 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n"); _ErrorHandle(ERROR_KERNEL_IN_ISR); return (PX_ERROR); /* 不能在中断中调用 */ } if (pevtfdfil->EF_iFlag & O_NONBLOCK) { ulTimeout = LW_OPTION_NOT_WAIT; } else { ulTimeout = LW_OPTION_WAIT_INFINITE; } for (;;) { ulLwErrCode = API_SemaphoreBPend(pevtfdfil->EF_ulReadLock, ulTimeout); if (ulLwErrCode != ERROR_NONE) { /* 超时 */ _ErrorHandle(EAGAIN); return (0); } LW_SPIN_LOCK_QUICK(&pevtfdfil->EF_slLock, &iregInterLevel); if (pevtfdfil->EF_u64Counter) { break; } LW_SPIN_UNLOCK_QUICK(&pevtfdfil->EF_slLock, iregInterLevel); } if (pevtfdfil->EF_iFlag & EFD_SEMAPHORE) { /* EFD_SEMAPHORE */ UINT64 u64One = 1; lib_memcpy(pcBuffer, &u64One, sizeof(UINT64)); /* host bytes order */ pevtfdfil->EF_u64Counter--; } else { lib_memcpy(pcBuffer, &pevtfdfil->EF_u64Counter, sizeof(UINT64)); pevtfdfil->EF_u64Counter = 0; } if (pevtfdfil->EF_u64Counter) { bRelease = LW_TRUE; } LW_SPIN_UNLOCK_QUICK(&pevtfdfil->EF_slLock, iregInterLevel); if (bRelease) { API_SemaphoreBPost(pevtfdfil->EF_ulReadLock); SEL_WAKE_UP_ALL(&pevtfdfil->EF_selwulist, SELREAD); } API_SemaphoreBPost(pevtfdfil->EF_ulWriteLock); SEL_WAKE_UP_ALL(&pevtfdfil->EF_selwulist, SELWRITE); return (sizeof(UINT64)); }
/********************************************************************************************************* ** 函数名称: _evtfdWrite ** 功能描述: 写 eventfd 设备 ** 输 入 : pevtfdfil eventfd 文件 ** pcBuffer 将要写入的数据指针 ** stNBytes 写入数据大小 ** 输 出 : ERROR ** 全局变量: ** 调用模块: *********************************************************************************************************/ static ssize_t _evtfdWrite (PLW_EVTFD_FILE pevtfdfil, PCHAR pcBuffer, size_t stNBytes) { INTREG iregInterLevel; UINT64 u64Add; ULONG ulLwErrCode; ULONG ulTimeout; BOOL bRelease = LW_FALSE; if (!pcBuffer || (stNBytes < sizeof(UINT64))) { _ErrorHandle(EINVAL); return (PX_ERROR); } if (LW_CPU_GET_CUR_NESTING()) { /* 是否在中断中调用 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n"); _ErrorHandle(ERROR_KERNEL_IN_ISR); return (PX_ERROR); /* 不能在中断中调用 */ } lib_memcpy(&u64Add, pcBuffer, sizeof(UINT64)); if (u64Add == LW_EVENTFD_MAX_CNT) { _ErrorHandle(EINVAL); return (PX_ERROR); } if (pevtfdfil->EF_iFlag & O_NONBLOCK) { ulTimeout = LW_OPTION_NOT_WAIT; } else { ulTimeout = LW_OPTION_WAIT_INFINITE; } for (;;) { ulLwErrCode = API_SemaphoreBPend(pevtfdfil->EF_ulWriteLock, ulTimeout); if (ulLwErrCode != ERROR_NONE) { /* 超时 */ _ErrorHandle(EAGAIN); return (0); } LW_SPIN_LOCK_QUICK(&pevtfdfil->EF_slLock, &iregInterLevel); if ((LW_EVENTFD_MAX_CNT - u64Add) > pevtfdfil->EF_u64Counter) { /* 不能产生溢出 */ break; } LW_SPIN_UNLOCK_QUICK(&pevtfdfil->EF_slLock, iregInterLevel); } pevtfdfil->EF_u64Counter += u64Add; if (pevtfdfil->EF_u64Counter) { bRelease = LW_TRUE; } LW_SPIN_UNLOCK_QUICK(&pevtfdfil->EF_slLock, iregInterLevel); if (bRelease) { API_SemaphoreBPost(pevtfdfil->EF_ulReadLock); SEL_WAKE_UP_ALL(&pevtfdfil->EF_selwulist, SELREAD); } return (sizeof(UINT64)); }
/********************************************************************************************************* ** 函数名称: __canIoctl ** 功能描述: CAN 设备控制 ** 输 入 : ** pcanDev CAN 设备 ** cmd 控制命令 ** lArg 参数 ** 输 出 : ERROR_NONE or PX_ERROR ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __canIoctl (__CAN_DEV *pcanDev, INT cmd, LONG lArg) { INTREG iregInterLevel; INT iStatus = ERROR_NONE; struct stat *pstat; PLW_SEL_WAKEUPNODE pselwunNode; struct timeval *timevalTemp; __CAN_PORT *pcanport = (__CAN_PORT *)pcanDev; CAN_DRV_FUNCS *pCanDevFuncs = pcanport->CANPORT_pcanchan->pDrvFuncs; CANDEV_LOCK(pcanDev); /* 等待设备使用权 */ if (pCanDevFuncs->ioctl) { iStatus = pCanDevFuncs->ioctl(pcanport->CANPORT_pcanchan, cmd, (PVOID)lArg); } else { iStatus = ENOSYS; } if ((iStatus == ENOSYS) || ((iStatus == PX_ERROR) && (errno == ENOSYS))) { /* 驱动程序无法识别的命令 */ iStatus = ERROR_NONE; /* 清除驱动程序错误 */ switch (cmd) { case FIONREAD: /* 读缓冲区有效数据数量 */ { LONG lNFrame = __canQCount(pcanDev->CAN_pcanqRecvQueue); *((INT *)lArg) = (INT)(lNFrame * sizeof(CAN_FRAME)); } break; case FIONWRITE: { LONG lNFrame = __canQCount(pcanDev->CAN_pcanqSendQueue); *((INT *)lArg) = (INT)(lNFrame * sizeof(CAN_FRAME)); } break; case FIOFLUSH: /* 清空设备缓冲区 */ __canFlushRd(pcanport); __canFlushWrt(pcanport); break; case FIOWFLUSH: __canFlushRd(pcanport); /* 清空写缓冲区 */ break; case FIORFLUSH: __canFlushWrt(pcanport); /* 清空读缓冲区 */ break; case FIOFSTATGET: /* 获得文件属性 */ pstat = (struct stat *)lArg; pstat->st_dev = (dev_t)pcanDev; pstat->st_ino = (ino_t)0; /* 相当于唯一节点 */ pstat->st_mode = 0666 | S_IFCHR; /* 默认属性 */ pstat->st_nlink = 1; pstat->st_uid = 0; pstat->st_gid = 0; pstat->st_rdev = 1; pstat->st_size = 0; pstat->st_blksize = 0; pstat->st_blocks = 0; pstat->st_atime = API_RootFsTime(LW_NULL); /* 默认使用 root fs 基准时间 */ pstat->st_mtime = API_RootFsTime(LW_NULL); pstat->st_ctime = API_RootFsTime(LW_NULL); break; case FIOSELECT: pselwunNode = (PLW_SEL_WAKEUPNODE)lArg; SEL_WAKE_NODE_ADD(&pcanDev->CAN_selwulList, pselwunNode); switch (pselwunNode->SELWUN_seltypType) { case SELREAD: /* 等待数据可读 */ if (__canQCount(pcanDev->CAN_pcanqRecvQueue) > 0) { SEL_WAKE_UP(pselwunNode); /* 唤醒节点 */ } break; case SELWRITE: if (__canQFreeNum(pcanDev->CAN_pcanqSendQueue) > 0) { SEL_WAKE_UP(pselwunNode); /* 唤醒节点 */ } break; case SELEXCEPT: /* 总线是否异常 */ LW_SPIN_LOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, &iregInterLevel); if (pcanDev->CAN_uiBusState != CAN_DEV_BUS_ERROR_NONE) { LW_SPIN_UNLOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, iregInterLevel); SEL_WAKE_UP(pselwunNode); /* 唤醒节点 */ } else { LW_SPIN_UNLOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, iregInterLevel); } break; } break; case FIOUNSELECT: SEL_WAKE_NODE_DELETE(&pcanDev->CAN_selwulList, (PLW_SEL_WAKEUPNODE)lArg); break; case CAN_DEV_GET_BUS_STATE: /* 获取 CAN 控制器状态 */ LW_SPIN_LOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, &iregInterLevel); *((LONG *)lArg) = pcanDev->CAN_uiBusState; pcanDev->CAN_uiBusState = CAN_DEV_BUS_ERROR_NONE; /* 读取后清除状态 */ LW_SPIN_UNLOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, iregInterLevel); break; case FIOWTIMEOUT: if (lArg) { timevalTemp = (struct timeval *)lArg; pcanDev->CAN_ulSendTimeout = __timevalToTick(timevalTemp); /* 转换为系统时钟 */ } else { pcanDev->CAN_ulSendTimeout = LW_OPTION_WAIT_INFINITE; } break; case FIORTIMEOUT: if (lArg) { timevalTemp = (struct timeval *)lArg; pcanDev->CAN_ulRecvTimeout = __timevalToTick(timevalTemp); /* 转换为系统时钟 */ } else { pcanDev->CAN_ulRecvTimeout = LW_OPTION_WAIT_INFINITE; } break; default: _ErrorHandle(ERROR_IO_UNKNOWN_REQUEST); iStatus = PX_ERROR; break; } } CANDEV_UNLOCK(pcanDev); /* 释放设备使用权 */ return (iStatus); }