/********************************************************************************************************* ** 函数名称: __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); /* 释放设备使用权 */ }
/********************************************************************************************************* ** 函数名称: _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); }
/********************************************************************************************************* ** 函数名称: waitread ** 功能描述: select() 变种,等待单个文件可读. ** 输 入 : iFd 文件描述符 ** ptmvalTO 等待超时时间, LW_NULL 表示永远等待. ** 输 出 : 正常等待到的文件数, 为 1 表示文件可以读, 为 0 表示超时 ,错误返回 PX_ERROR. ** errno == ERROR_IO_SELECT_UNSUPPORT_IN_DRIVER 驱动程序不支持 ** errno == ERROR_IO_SELECT_CONTEXT 线程不存在 context ** errno == ERROR_THREAD_WAIT_TIMEOUT 等待超时 ** errno == ERROR_KERNEL_IN_ISR 在中断中调用 ** errno == ERROR_IOS_INVALID_FILE_DESCRIPTOR 文件描述符无效. ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT waitread (INT iFd, struct timeval *ptmvalTO) { REGISTER INT iIsOk = ERROR_NONE; /* 初始化为没有错误 */ REGISTER INT iWidth = iFd + 1; /* iFd + 1 */ REGISTER INT iWidthInBytes; /* 需要检测的位数占多少字节 */ REGISTER ULONG ulWaitTime; /* 等待时间 */ REGISTER LW_SEL_CONTEXT *pselctx; PLW_CLASS_TCB ptcbCur; fd_set fdsetRead; LW_SEL_WAKEUPNODE selwunNode; /* 生成的 NODE 模板 */ ULONG ulError; if (LW_CPU_GET_CUR_NESTING()) { _ErrorHandle(ERROR_KERNEL_IN_ISR); /* 不能在中断中调用 */ return (PX_ERROR); } if (iFd > (FD_SETSIZE - 1) || iFd < 0) { /* 文件号错误 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "file descriptor invalidate..\r\n"); _ErrorHandle(ERROR_IOS_INVALID_FILE_DESCRIPTOR); /* 文件描述符无效 */ return (PX_ERROR); } LW_TCB_GET_CUR_SAFE(ptcbCur); pselctx = ptcbCur->TCB_pselctxContext; if (!pselctx) { /* 没有 select context */ _DebugHandle(__ERRORMESSAGE_LEVEL, "no select context.\r\n"); _ErrorHandle(ERROR_IO_SELECT_CONTEXT); return (PX_ERROR); } iWidthInBytes = __HOWMANY(iWidth, NFDBITS) * sizeof(fd_mask); /* 需要检测的位数占多少字节 */ FD_ZERO(&fdsetRead); /* 清除文件集 */ FD_SET(iFd, &fdsetRead); /* 指定文件置位 */ __selFdsetInit(iWidthInBytes, &fdsetRead, /* 设置 OrigRead 文件位 */ LW_NULL, LW_NULL, pselctx); /* __selTaskDeleteHook 使用 */ FD_CLR(iFd, &fdsetRead); /* 清除文件集 */ if (!ptmvalTO) { /* 计算等待时间 */ ulWaitTime = LW_OPTION_WAIT_INFINITE; /* 无限等待 */ } else { ulWaitTime = __timevalToTick(ptmvalTO); /* 计算超时时间 */ } pselctx->SELCTX_pfdsetReadFds = &fdsetRead; pselctx->SELCTX_pfdsetWriteFds = LW_NULL; /* 保存用户参数地址 */ pselctx->SELCTX_pfdsetExceptFds = LW_NULL; API_SemaphoreBClear(pselctx->SELCTX_hSembWakeup); /* 清除信号量 */ selwunNode.SELWUN_hThreadId = API_ThreadIdSelf(); selwunNode.SELWUN_seltypType = SELREAD; selwunNode.SELWUN_iFd = iFd; pselctx->SELCTX_iWidth = iWidth; /* 记录最大文件号 */ pselctx->SELCTX_bPendedOnSelect = LW_TRUE; /* 需要 delete hook 清除 NODE */ iIsOk = ioctl(iFd, FIOSELECT, (LONG)&selwunNode); /* FIOSELECT */ if (iIsOk != ERROR_NONE) { ULONG ulError = API_GetLastError(); iIsOk = ioctl(iFd, FIOUNSELECT, (LONG)&selwunNode); /* FIOUNSELECT */ if (ulError == ERROR_IO_UNKNOWN_REQUEST) { _ErrorHandle(ERROR_IO_SELECT_UNSUPPORT_IN_DRIVER); /* 驱动程序不支持 */ } pselctx->SELCTX_bPendedOnSelect = LW_FALSE; /* 自行清理完毕 */ return (PX_ERROR); /* 错误 */ } API_SemaphoreBPend(pselctx->SELCTX_hSembWakeup, ulWaitTime); /* 开始等待 */ ulError = API_GetLastError(); iIsOk = ioctl(iFd, FIOUNSELECT, (LONG)&selwunNode); /* FIOUNSELECT */ pselctx->SELCTX_bPendedOnSelect = LW_FALSE; /* 自行清理完毕 */ if (iIsOk != ERROR_NONE) { return (PX_ERROR); /* 出现错误 */ } else { _ErrorHandle(ulError); } if (FD_ISSET(iFd, &fdsetRead)) { /* 检查文件是否可读 */ return (1); } else { return (0); } }