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

📄 wncandevio.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
/* wncanDevIO.c - implementation of WIND NET CAN Device I/O Interface */

/* Copyright 2002-2003 Wind River Systems, Inc. */

/*
modification history
--------------------
01d,11may05,lsg   Fix in macro checks for malloc definition 
01c,21apr04,bjn   Added WNCAN_REG_SET and WNCAN_REG_GET.
01b,21feb03,rgp   finished
01a,19dec02,emcw  created

*/

/*
DESCRIPTION
This file contains the functions that implement the DevIO interface defined 
in the wncanDevIO.h header file.
*/

/* log message debugging */
#define DEVIO_DEBUG  0


/* includes */

#include <vxWorks.h>
#include <stdlib.h>
#include <errnoLib.h>
#include <string.h>
#include <stdio.h>
#include <CAN/wnCAN.h>
#include <CAN/wncanDevIO.h>
#include <intLib.h>

#ifndef _WRS_VXWORKS_5_X
#include <memLib.h>
#include <memPartLib.h>
#endif

#if DEVIO_DEBUG
#include <logLib.h>
#include <private/selectLibP.h>
#endif

/* global variables */

/* local variables */

LOCAL int wncDevIODrvNum = 0;     /* driver number assigned to this driver */
LOCAL int wncDevDrvInstance = 0;  /* # times wncDevIODevCreate() called */

/* local prototypes */
LOCAL int wncUtilCalcRingBufSize(int numCanMsgs);
LOCAL STATUS wncUtilIoctlFioCmds(WNCAN_DEVIO_FDINFO*,int,int);
LOCAL STATUS wncUtilIoctlDeviceFioCmds(WNCAN_DEVIO_FDINFO*,int,int);
LOCAL STATUS wncUtilIoctlChannelCmds(WNCAN_DEVIO_FDINFO*,int,int);
LOCAL STATUS wncUtilIoctlCtlrCmds(WNCAN_DEVIO_FDINFO*,int,int);
LOCAL STATUS wncUtilIoctlDeviceCmds(WNCAN_DEVIO_FDINFO*,int,int);
LOCAL void wncDevIOIsrHandler(struct WNCAN_Device*,WNCAN_IntType,UCHAR);

/* memory allocation for 5.5 and AE are different */
#ifdef _WRS_KERNEL 
#define WNCDEV_MALLOC(s)  malloc(s)
#define WNCDEV_FREE(s)    free(s)
#endif

#ifndef _WRS_KERNEL

#ifdef _WRS_VXWORKS_5_X
#define WNCDEV_MALLOC(s)  malloc(s)
#define WNCDEV_FREE(s)    free(s)
#else
#define WNCDEV_MALLOC(s)  KHEAP_ALIGNED_ALLOC(s, 4)
#define WNCDEV_FREE(s)    KHEAP_FREE(s)
#endif

#endif

/* define helper macros to access the device's info struct
** which we store within the WNC's device structure
**/
#define WNCDEV_PUT_DEVICEINFO(pDev, pInfo) \
(pDev)->userData = (void*)pInfo
#define WNCDEV_GET_DEVICEINFO(pDev) \
((WNCAN_DEVIO_FDINFO*)((pDev)->userData))
#define WNCDRV_PUT_DEVICEINFO(pDrv, pInfo) \
WNCDEV_PUT_DEVICEINFO(pDrv->wncDevice, pInfo)
#define WNCDRV_GET_DEVICEINFO(pDrv) \
WNCDEV_GET_DEVICEINFO(pDrv->wncDevice)


/************************************************************************
*
* wncDevIODrvInstall - install the DevIO interface driver 
*
* This routine installs the DevIO interface driver into the VxWorks I/O system.
*
* This routine should be called exactly once, before any reads, writes, or calls 
* to wncDevIODevCreate().  Normally, it is called by usrRoot() in usrConfig.c.
*
* RETURNS: OK or ERROR if the driver cannot be installed
*
* ERRNO: N/A
*
*/

STATUS wncDevIODrvInstall(void)
{
    /* Check whether driver is already installed */
    
    if (wncDevIODrvNum > 0)
    {
#if DEVIO_DEBUG
        logMsg("wncDevIODrvInstall() OK: DevIO driver already installed\n", 
            0,0,0,0,0,0);
#endif
        
        return OK;
    }
    
    /* 
    VxWorks startup code takes care of creation, and VxWorks shutdown
    code takes care of destruction.  Don't need creat() and delete()
    functions here.
    */
    
#if DEVIO_DEBUG
    wncDevIODrvNum = iosDrvInstall (wncDevIOCreate, wncDevIODelete, wncDevIOOpen, 
        wncDevIOClose, wncDevIOReadBuf, wncDevIOWriteBuf, 
        wncDevIOIoctl);
#else
    wncDevIODrvNum = iosDrvInstall ((FUNCPTR) NULL, (FUNCPTR) NULL, wncDevIOOpen, 
        wncDevIOClose, wncDevIOReadBuf, wncDevIOWriteBuf, 
        wncDevIOIoctl);
#endif
    
    return (wncDevIODrvNum == ERROR ? ERROR : OK);
}


/************************************************************************
*
* wncDevIODrvRemove - remove the DevIO interface driver 
*
* This routine removes the DevIO interface driver from the VxWorks I/O system.
*
* RETURNS: OK or ERROR 
*
* ERRNO: N/A
*
*/

STATUS wncDevIODrvRemove(void)
{
    STATUS  status;
    
    /* Check whether driver is already removed */
    
    if (wncDevIODrvNum == 0)
    {
#if DEVIO_DEBUG
        logMsg("wncDevIODrvRemove() OK: DevIO driver already removed\n", 
            0,0,0,0,0,0);
#endif
        
        return OK;
    }
    
    /* Check whether other instances of driver need to be removed */
    
    if (wncDevDrvInstance > 0)
    {
#if DEVIO_DEBUG
        logMsg("wncDevIODrvRemove() ERROR: Still have DevIO driver instances in use\n", 
            0,0,0,0,0,0);
#endif
        
        return ERROR;
    }
    
    /* Delete driver entry from VxWorks I/O system */
    
    status = iosDrvRemove (wncDevIODrvNum, TRUE);
    if (status == OK)
        wncDevIODrvNum = 0;
    
    return (status);
}


/************************************************************************
*
* wncDevIODevCreate - device creation routine
*
* This routine creates an instance of the DevIO driver for the specified
* device name and adds it to the VxWorks I/O System
*
* RETURNS: OK or ERROR
*
* ERRNO: S_ioLib_NO_DRIVER
*        S_can_invalid_parameter
*        S_can_out_of_memory        
*/

STATUS wncDevIODevCreate
(
 char                 *name,       /* device name */
 int                   boardtype,  /* WNC board type */
 int                   boardindex, /* board index */
 int                   ctlrindex,  /* controller number */
 WNCAN_DEVIO_DRVINFO **pwncDrv     /* pointer to driver descriptor */
 )
{
    STATUS      status = OK;
    char        ctlrName[WNCAN_LG_BUF_SIZE];
    char       *pCtlrName = ctlrName;
    
    /* Check for errors */
    
    if (wncDevIODrvNum <= 0)
    {
#if DEVIO_DEBUG
        logMsg("wncDevIODevCreate() ERROR: Invalid wncDevIODrvNum\n", 0,0,0,0,0,0);
#endif
        
        errnoSet (S_ioLib_NO_DRIVER);
        return ERROR;
    }
    
    if (name == NULL)
    {
#if DEVIO_DEBUG
        logMsg("wncDevIODevCreate() ERROR: device name not specified\n", 0,0,0,0,0,0);
#endif
        
        errnoSet (S_can_invalid_parameter);
        return ERROR;
    }
    
    
    /* convert to device name  "board/controller" */
    {
        int namelen = strlen(name)+2;  /* add trailing '/' and nul */
        int idx = ctlrindex;
        
        /* account for controller number (one for each digit) 
        ** (i.e. namelen += (log10(ctlrindex)+1) ) 
        */
        for(namelen +=1; idx>=10; idx /= 10, namelen++) ;
        
        if (namelen > WNCAN_LG_BUF_SIZE)
        {
            pCtlrName = (char*)WNCDEV_MALLOC(namelen+1);
            if (pCtlrName == NULL)
            {
                errnoSet (S_can_out_of_memory);
                status = ERROR;
            }
        }
    }
    
    if (status == OK)
    {    
        WNCAN_DEVIO_DRVINFO *wncDrv;
        
        /* create the device name */
        sprintf(pCtlrName, "%s/%d", name, ctlrindex);
        
        /* Initialize DevIO struct */
        
        wncDrv = (WNCAN_DEVIO_DRVINFO *) WNCDEV_MALLOC(sizeof(WNCAN_DEVIO_DRVINFO));
        if (wncDrv == NULL)
        {
            errnoSet (S_can_out_of_memory);
            status = ERROR;
        } 
        else
        {
            wncDrv->boardType    = boardtype;
            wncDrv->boardIdx     = boardindex;
            wncDrv->ctlrIdx      = ctlrindex;
            wncDrv->numOpenChans = 0; 
            wncDrv->isDeviceOpen = FALSE;
            wncDrv->wncDevice    = NULL;
            wncDrv->ctrlSetConfig = NULL;
            wncDrv->ctrlGetConfig = NULL;
            
            /* create device mutex */
            wncDrv->mutex        = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
            if (wncDrv->mutex == NULL)
            {
#if DEVIO_DEBUG
                logMsg("wncDevIODevCreate() ERROR: failed to create semaphore\n", 
                    0,0,0,0,0,0);
#endif
                
                status = ERROR;
            }
            else
            {
                /* Add device to VxWorks I/O System and associate with DevIO driver */
                status = iosDevAdd (&(wncDrv->devHdr), pCtlrName, wncDevIODrvNum);
            }
            
            if (status == OK)
            {
                wncDevDrvInstance++;
                if (pwncDrv)           /* pass back to use the dev pointer */
                    *pwncDrv = wncDrv;
            }
            else
            {  /* error, clean up allocated memory */
                WNCDEV_FREE((char*)wncDrv);
            }
        }
    }
    
    /* clean-up locally allocated memory, if needed */
    if (pCtlrName != ctlrName) 
        WNCDEV_FREE((char*)pCtlrName);
    
    return status;
}


/************************************************************************
*
* wncDevIODevDestroy - device destroy routine
*
* This routine destroys an instance of the DevIO driver for the specified
* driver descriptor and removes it from the VxWorks I/O System.  The user
* must ensure that any open channels and the CAN device must be closed before
* calling this routine.
*
* RETURNS: OK or ERROR
*
* ERRNO: S_ioLib_NO_DRIVER, S_ioLib_DEVICE_ERROR, S_iosLib_DEVICE_NOT_FOUND
*
*/

STATUS wncDevIODevDestroy
(
 WNCAN_DEVIO_DRVINFO*  wncDrv  /* pointer to driver descriptor */
 )
{
    /* Check for installed DevIO driver */
    
    if (wncDevIODrvNum <= 0)
    {
#if DEVIO_DEBUG
        logMsg("wncDevIODevDestroy() ERROR: Invalid wncDevIODrvNum\n", 0,0,0,0,0,0);
#endif
        
        errnoSet (S_ioLib_NO_DRIVER);
        return ERROR;
    }
    
    /* Check if at least one instance of the driver is installed */
    
    if (wncDevDrvInstance == 0)
    {
        errnoSet (S_iosLib_DEVICE_NOT_FOUND);
        return ERROR;
    }
    
    /* Ensure that all CAN channels are closed */
    
    if (wncDrv->numOpenChans > 0)
    {
#if DEVIO_DEBUG
        logMsg("wncDevIODevDestroy() ERROR: CAN device still has open channels\n", 
            0,0,0,0,0,0);
#endif
        
        errnoSet (S_ioLib_DEVICE_ERROR);
        return ERROR;
    }
    
    /* Ensure that the CAN device is closed */
    
    if (wncDrv->isDeviceOpen)
    {
#if DEVIO_DEBUG
        logMsg("wncDevIODevDestroy() ERROR: CAN device still open\n", 
            0,0,0,0,0,0);
#endif
        
        errnoSet (S_ioLib_DEVICE_ERROR);
        return ERROR;
    }
    
    /* Delete DevIO driver from I/O System */
    
    iosDevDelete (&wncDrv->devHdr);
    
    /* Free DevIO driver struct resources */
    
    wncDrv->boardType = 0;
    wncDrv->boardIdx = 0;
    wncDrv->ctlrIdx = 0;
    semDelete(wncDrv->mutex);
    wncDrv->wncDevice = NULL;
    
    WNCDEV_FREE((char*)wncDrv);
    wncDrv = NULL;
    
    wncDevDrvInstance--;
    
    return OK;
}


#if DEVIO_DEBUG
/************************************************************************
*
* wncDevIOCreate - device create routine
*
* This routine is only for debugging purposes to test the VxWorks I/O System
*
* RETURNS: OK or ERROR
*
* ERRNO: N/A
*
*/

int wncDevIOCreate
(
 WNCAN_DEVIO_DRVINFO*  wncDev,  /* pointer to device descriptor */
 char*                 name,    /* device or channel name */
 int                   mode     /* not used */
 )
{
    /* Debugging only */
    logMsg("wncDevIOCreate() called\n", 0,0,0,0,0,0);
    return OK;

⌨️ 快捷键说明

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