Пример #1
0
/*********************************************************************************************************
** 函数名称: __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);
}
Пример #2
0
/*********************************************************************************************************
** 函数名称: __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);
}
Пример #3
0
/*********************************************************************************************************
** 函数名称: __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)));
}
Пример #4
0
/*********************************************************************************************************
** 函数名称: __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));
}
Пример #5
0
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);
}
Пример #6
0
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);
}
Пример #7
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);
}
Пример #8
0
/*********************************************************************************************************
** 函数名称: 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);
}
Пример #9
0
/*********************************************************************************************************
** 函数名称: 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);
}
Пример #10
0
/*********************************************************************************************************
** 函数名称: _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);
}
Пример #11
0
/*********************************************************************************************************
** 函数名称: _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);
}
Пример #12
0
/*********************************************************************************************************
** 函数名称: __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);
        /*  打开中断                    */
    }
}
Пример #13
0
/*********************************************************************************************************
** 函数名称: _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();
}
Пример #14
0
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();
}
Пример #15
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) {
        _StackFree(ptcbCur,
                   pcrcbDel->COROUTINE_pstkStackLowAddr, LW_TRUE);      /*  释放内存                    */
    }
    
    return  (ERROR_NONE);
}
Пример #16
0
/*********************************************************************************************************
** 函数名称: __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);                                           /*  释放设备使用权              */
}
Пример #17
0
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();
}
Пример #18
0
/*********************************************************************************************************
** 函数名称: _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);
}
Пример #19
0
/*********************************************************************************************************
** 函数名称: __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);
}
Пример #20
0
/*********************************************************************************************************
** 函数名称: __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);
}
Пример #21
0
/*********************************************************************************************************
** 函数名称: __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 线程可写        */
}
Пример #22
0
/*********************************************************************************************************
** 函数名称: __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() 激活               */
    }
}
Пример #23
0
/*********************************************************************************************************
** 函数名称: __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));
}
Пример #24
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) {
        _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);                                               /*  理论上是无法运行到这里的    */
}
Пример #25
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);
}
Пример #26
0
/*********************************************************************************************************
** 函数名称: _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);
}
Пример #27
0
/*********************************************************************************************************
** 函数名称: _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));
}
Пример #28
0
/*********************************************************************************************************
** 函数名称: _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));
}
Пример #29
0
/*********************************************************************************************************
** 函数名称: __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);
}