⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wncandevio.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
}


/************************************************************************
*
* wncDevIODelete - device delete routine
*
* This routine is only for debugging purposes to test the VxWorks I/O System
*
* RETURNS: OK or ERROR
*
* ERRNO: N/A
*
*/

int wncDevIODelete
(
 WNCAN_DEVIO_DRVINFO*  wncDev,  /* pointer to device descriptor */
 char*                 name     /* device or channel name */
 )
{
    /* Debugging only */
    logMsg("wncDevIODelete() called\n", 0,0,0,0,0,0);
    return OK;
}
#endif    /* DEVIO_DEBUG */


/************************************************************************
*
* wncDevIOOpen - device open routine
*
* This routine opens a CAN device or CAN channel for access using the VxWorks
* I/O System via the returned file descriptor
*
* RETURNS: identifier of opened CAN device or channel
*
* ERRNO: ELOOP
*
*/

int wncDevIOOpen
(
 WNCAN_DEVIO_DRVINFO*  wncDrv,  /* pointer to driver descriptor */
 char*                 name,    /* device or channel name */
 int                   flags,   /* device or channel access */
 int                   mode     /* not used */
 )
{
    WNCAN_DEVIO_FDINFO*   fdInfo = NULL;
    STATUS                status = ERROR;    /* pessimistic */
    
                                             /* 
                                             How to determine if opening CAN device or channel: 
                                             -- device is named /boardName/controller#
                                             -- channel is named /boardName/controller#/channel#
                                             -- User's call to open() results in I/O System searching its internal device
                                             list using that entire name or an initial substring of that name
                                             -- The matching substring is removed and the remaining part of the original
                                             name argument is passed to THIS function
                                             -- For a CAN device, the name argument to this function is a null string.  
                                             For a CAN channel, the name argument to this function is "/channel#".
    */
    
    /* lock device */
    semTake(wncDrv->mutex, WAIT_FOREVER);
    
    /* Open CAN device */
    
    if ((name == NULL) || (!*name))
    {
        WNCAN_DEVICE   *canDev;
        int             bufSize;
        
        /* Check flags argument */
        
        if (flags != O_RDWR)
        {
#if DEVIO_DEBUG
            logMsg("wncDevIOOpen() ERROR: Invalid flags argument for CAN device \n", 
                0,0,0,0,0,0);
#endif
            
            goto ErrorExit;
        }
        
        /* Call WNCAN API to open CAN device */
        
        canDev = CAN_Open (wncDrv->boardType, wncDrv->boardIdx, wncDrv->ctlrIdx);
        
        status = CAN_Init (canDev);
        if (status == ERROR)
            goto ErrorExit;
        
        /* install interrupt handler */
        CAN_InstallISRCallback(canDev, wncDevIOIsrHandler);
        
        /* allow all interrupts */
        CAN_SetIntMask(canDev, WNCAN_INT_ALL);
        CAN_EnableInt(canDev);
        
        /* update devIO info */
        wncDrv->isDeviceOpen = TRUE;
        wncDrv->wncDevice = canDev;
        
        /* Allocate and initialize DevIO file descriptor structure */
        
        fdInfo = (WNCAN_DEVIO_FDINFO *) WNCDEV_MALLOC(sizeof(WNCAN_DEVIO_FDINFO));
        if (fdInfo == NULL)
        {
#if DEVIO_DEBUG
            logMsg("wncDevIOOpen() ERROR: malloc() failed for "
                "WNCAN_DEVIO_FDINFO struct\n", 0,0,0,0,0,0);
#endif
            
            goto ErrorExit;
        }
        
        fdInfo->wnDevIODrv = wncDrv;
        fdInfo->devType = FD_WNCAN_DEVICE;
        
        /* initialize select's wakeup list */            
        selWakeupListInit(&fdInfo->selWakeupList);
        
        /* allocate array of infos for each channel */
        bufSize = sizeof(WNCAN_DEVIO_FDINFO*)*CAN_GetNumChannels(canDev);
        fdInfo->fdtype.device.chnInfo = (WNCAN_DEVIO_FDINFO**)WNCDEV_MALLOC(bufSize);
        if (fdInfo->fdtype.device.chnInfo == NULL)
        {
#if DEVIO_DEBUG
            logMsg("wncDevIOOpen() ERROR: malloc() failed for "
                "WNCAN_DEVIO_FDINFO* array\n", 0,0,0,0,0,0);
#endif
            
            goto ErrorExit;
        }
        
        /* store into can dev pointer */
        WNCDRV_PUT_DEVICEINFO(wncDrv, fdInfo);
    }
    
    /* Open CAN channel */
    
    else
    {
        WNCAN_DEVIO_FDINFO  *pDevInfo = NULL;
        int                  ringBufSize = 0;
        
        /* Check flags argument */
        
        if ( !((flags == O_RDWR) || (flags == O_RDONLY) || (flags == O_WRONLY)) )
        {
#if DEVIO_DEBUG
            logMsg("wncDevIOOpen() ERROR: Invalid flags argument for CAN channel\n", 
                0,0,0,0,0,0);
#endif
            
            goto ErrorExit;
        }
        
        /* Ensure that CAN device is open */
        
        if (wncDrv->isDeviceOpen == FALSE)
        {
#if DEVIO_DEBUG
            logMsg("wncDevIOOpen() ERROR: CAN device not open\n", 0,0,0,0,0,0);
#endif
            
            goto ErrorExit;
        }
        
        /* Allocate and initialize DevIO file descriptor structure */
        
        fdInfo = (WNCAN_DEVIO_FDINFO *) WNCDEV_MALLOC(sizeof(WNCAN_DEVIO_FDINFO));
        if (fdInfo == NULL)
        {
#if DEVIO_DEBUG
            logMsg("wncDevIOOpen() ERROR: malloc() failed for "
                "WNCAN_DEVIO_FDINFO struct\n", 0,0,0,0,0,0);
#endif
            
            goto ErrorExit;
        }
        
        fdInfo->wnDevIODrv = wncDrv;
        fdInfo->devType = FD_WNCAN_CHANNEL;
        
        /* initialize select's wakeup list */            
        selWakeupListInit(&fdInfo->selWakeupList);
        
        /* Create input and output data buffers as indicated by flags argument */
        
        if ( (flags == O_RDWR) || (flags == O_RDONLY) )
        {
            /* Create input ring buffer */
            
            ringBufSize = wncUtilCalcRingBufSize (WNCAN_DEFAULT_RINGBUF_SIZE);
            fdInfo->fdtype.channel.inputBuf = rngCreate (ringBufSize);
            if (fdInfo->fdtype.channel.inputBuf == NULL)
            {
#if DEVIO_DEBUG
                logMsg("wncDevIOOpen() ERROR: Could not create input ring buffer\n", 
                    0,0,0,0,0,0);
#endif
                
                goto ErrorExit;
            }
            fdInfo->fdtype.channel.intType = WNCAN_INT_RX;
        }
        else
            fdInfo->fdtype.channel.inputBuf = NULL;
        
        if ( (flags == O_RDWR) || (flags == O_WRONLY) )
        {
            /* Create output ring buffer */
            
            ringBufSize = wncUtilCalcRingBufSize (WNCAN_DEFAULT_RINGBUF_SIZE);
            fdInfo->fdtype.channel.outputBuf = rngCreate (ringBufSize);
            if (fdInfo->fdtype.channel.outputBuf == NULL)
            {
#if DEVIO_DEBUG
                logMsg("wncDevIOOpen() ERROR: Could not create output ring buffer\n", 
                    0,0,0,0,0,0);
#endif
                
                    /*
                    * If creation of outputBuf failed but inputBuf succeeded,
                    * delete inputBuf before proceeding
                */
                if((flags == O_RDWR) && (fdInfo->fdtype.channel.inputBuf))
                    rngDelete (fdInfo->fdtype.channel.inputBuf);
                
                goto ErrorExit;
            }
            fdInfo->fdtype.channel.intType = WNCAN_INT_TX;
        }
        else
            fdInfo->fdtype.channel.outputBuf = NULL;
        
        /* Finish initializing DevIO file descriptor struct */
        fdInfo->fdtype.channel.enabled = TRUE;
        fdInfo->fdtype.channel.flag = flags;
        /* skip leading slash */
        fdInfo->fdtype.channel.channel = (UINT32) stringToUlong(&name[1]);
        
        /* store this channel's info into the device's info */
        pDevInfo = WNCDRV_GET_DEVICEINFO(wncDrv);
        pDevInfo->fdtype.device.chnInfo[fdInfo->fdtype.channel.channel] = fdInfo; 
        
        /* Indicate in DevIO driver struct that a channel was opened */
        wncDrv->numOpenChans++;
    }
    
    /* unlock device */
    semGive(wncDrv->mutex);
    
    /* 
    Return pointer to file descriptor struct so that the I/O system can save 
    and automatically use as argument for all subsequent calls to close(), 
    read(), write(), and ioctl() functions
    */
    
    return (int) fdInfo;
    
    /* Set errno used by VxWorks for failed open() */
    
ErrorExit:
    errnoSet (ELOOP);
    
    /* de-allocate memory, if needed */
    if (fdInfo)
        WNCDEV_FREE((char*)fdInfo);
    
    /* unlock device */
    semGive(wncDrv->mutex);
    
    return ERROR;
}


/************************************************************************
*
* wncDevIOClose - device close routine
*
* This routine closes the specified CAN device or CAN channel.  In order to
* close a device, all channels on that device must be previously closed.
*
* RETURNS: OK or ERROR
*
* ERRNO: S_ioLib_DEVICE_ERROR
*
*/

STATUS wncDevIOClose
(
 WNCAN_DEVIO_FDINFO*  fdInfo  /* pointer to DevIO file descriptor */
 )
{
    WNCAN_DEVIO_DRVINFO*  wncDrv = NULL;
    WNCAN_DEVICE*         canDev = NULL;
    STATUS                status = ERROR;
    
    if (fdInfo == NULL)
    {
#if DEVIO_DEBUG
        logMsg("wncDevIOClose() ERROR: Null DevIO file descriptor\n", 
            0,0,0,0,0,0);
#endif
        return status;
    }
    
    wncDrv = fdInfo->wnDevIODrv;
    if (wncDrv == NULL)
    {
#if DEVIO_DEBUG
        logMsg("wncDevIOClose() ERROR: Null DevIO driver pointer\n", 
            0,0,0,0,0,0);
#endif
        return status;
    }
    
    canDev = wncDrv->wncDevice;
    if (canDev == NULL)
    {
#if DEVIO_DEBUG
        logMsg("wncDevIOClose() ERROR: Null device pointer\n", 
            0,0,0,0,0,0);
#endif      
        return status;
    }
    
    /* lock device */
    semTake(wncDrv->mutex, WAIT_FOREVER);
    
    /* Close CAN channel */
    if (fdInfo->devType == FD_WNCAN_CHANNEL)
    {
        WNCAN_DEVIO_FDINFO  *pDevInfo = NULL;
        
        /* Call WNCAN API functions to close channel */
        
        status = CAN_DisableChannel (canDev, fdInfo->fdtype.channel.channel);
        if (status == OK)
        {
            status=CAN_FreeChannel (canDev, fdInfo->fdtype.channel.channel);
            if (status == OK)
            {
                /* Delete ring buffers */
                
                if (fdInfo->fdtype.channel.inputBuf)
                    rngDelete (fdInfo->fdtype.channel.inputBuf);
                fdInfo->fdtype.channel.inputBuf = 0;
                if (fdInfo->fdtype.channel.outputBuf)
                    rngDelete (fdInfo->fdtype.channel.outputBuf);
                fdInfo->fdtype.channel.outputBuf = 0;
                
                
                /* remove channel's info from the device's info */
                pDevInfo = WNCDRV_GET_DEVICEINFO(wncDrv);
                pDevInfo->fdtype.device.chnInfo[fdInfo->fdtype.channel.channel] =NULL; 
                
                
                /* Cleanup DevIO file descriptor struct */
                fdInfo->wnDevIODrv = NULL;
                fdInfo->devType = FD_WNCAN_NONE;
                fdInfo->fdtype.channel.enabled = FALSE;
                fdInfo->fdtype.channel.flag = 0;
                fdInfo->fdtype.channel.channel = 0;
                
                
                /* release wake up list */
                selWakeupListTerm(&fdInfo->selWakeupList);
                
                /* Free DevIO file descriptor struct */
                WNCDEV_FREE((char*)fdInfo);
                fdInfo = NULL;
                
                /* Decrement open channel counter */
                wncDrv->numOpenChans--;
            }
#if DEVIO_DEBUG
            else
            {
                logMsg("wncDevIOClose() ERROR: channel free failed on channel num %d\n", 
                    fdInfo->fdtype.channel.channel,0,0,0,0,0);
            }
#endif      
        }
#if DEVIO_DEBUG
        else
        {
            logMsg("wncDevIOClose() ERROR: channel disable failed on channel num %d\n", 
                fdInfo->fdtype.channel.channel,0,0,0,0,0);
        }
#endif      
        
    }
    /* Close CAN device */
    else if (fdInfo->devType == FD_WNCAN_DEVICE)
    {
        /* Ensure that user has closed any open channels */
        
        if (wncDrv->numOpenChans > 0)
        {
#if DEVIO_DEBUG
            logMsg("wncDevIOClose() ERROR: CAN device still has open channels\n", 
                0,0,0,0,0,0);
#endif
            
            errnoSet (S_ioLib_DEVICE_ERROR);
            status = ERROR;
        } 
        else
        {
            /* Call WNCAN API functions for closing device */
            CAN_TxAbort (canDev);
            CAN_Stop (canDev);
            CAN_DisableInt (canDev);
            
            /* Close the device */
            CAN_Close (canDev);
            
            /* free internal struct memory */
            WNCDEV_FREE((char*)fdInfo->fdtype.device.chnInfo);
            
            /* release wake up list */
            selWakeupListTerm(&fdInfo->selWakeupList);
            
            /* Free DevIO file descriptor struct */
            WNCDEV_FREE((char*)fdInfo);
            fdInfo = NULL;
            
            wncDrv->isDeviceOpen = FALSE;
            status = OK;
        }
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -