Vector XL设备驱动库使用事例

       本章将介绍Vector XL设备驱动库DLL的使用,XL设备驱动库可以驱动Vector旗下的任何一种CAN设备,我们可以利用该设备驱动实现CAN总线上报文的收发,其官方驱动库的下载地址如下所示:

https://www.vector.com/int/en/products/products-a-z/libraries-drivers/xl-driver-library/#c75493

 

本文对XL驱动库例程中的xlCANdemo的代码进行了一层抽象,其头文件为VectorXLDriver.h,其内容如下所示:

#ifndef __VECTORXLDRIVER_H
#define __VECTORXLDRIVER_H

#define DYNAMIC_XLDRIVER_DLL
#define DO_NOT_DEFINE_EXTERN_DECLARATION
#include "vxlapi.h"

#define RECEIVE_EVENT_SIZE 1                // DO NOT EDIT! Currently 1 is supported only
#define RX_QUEUE_SIZE      4096             // internal driver queue size in CAN events

typedef struct
{
    uint8_t channelIndex;
    uint64_t channelMask;
    char name[31];
    uint32_t channelBusCapabilities;
    uint32_t channelCapabilities;
}VectorDriverChannel;
typedef struct
{
    VectorDriverChannel channel[31];
    int channelNum;
}VectorDriverChannelManage;
extern uint32_t uiSelectChannelConfigIndex;
extern uint32_t uiCanBaudrate;//1M
extern VectorDriverChannelManage vectorDriverChannelConfig;

int VectorXLDriverDllLoad(void);
int VectorXLDriverDllUnLoad(void);
int VectorDeviceInit(void);
int VectorDeviceUnInit(void);
int VectorDeviceChannelConfig(void);
int VectorDeviceRx(int *externFrame,int *id,int *dataLen,uint8_t *data);
int VectorDeviceTx(int externFrame,int id,int dataLen,uint8_t *data);

#endif

其VectorXLDriver.c代码如下所示:

#include <windows.h>  
#include <ansi_c.h>
#include <utility.h>
#include "VectorXLDriver.h"

HMODULE vxlDllHandle = 0;
XLOPENDRIVER xlOpenDriver;
XLCLOSEDRIVER xlCloseDriver; 
XLOPENPORT xlOpenPort; 
XLCLOSEPORT xlClosePort;
XLGETDRIVERCONFIG xlGetDriverConfig;
XLACTIVATECHANNEL xlActivateChannel;
XLDEACTIVATECHANNEL xlDeactivateChannel;
XLCANRECEIVE xlCanReceive;  
XLRECEIVE xlReceive;
XLCANTRANSMIT xlCanTransmit; 
XLCANTRANSMITEX xlCanTransmitEx;
XLCANFDSETCONFIGURATION xlCanFdSetConfiguration; 
XLCANSETCHANNELPARAMS xlCanSetChannelBitrate;  
XLGETERRORSTRING xlGetErrorString;
XLCANGETEVENTSTRING xlCanGetEventString; 
XLGETEVENTSTRING xlGetEventString;
XLSETNOTIFICATION xlSetNotification;

uint32_t openDriverFlag = 0;
uint32_t channelActiveFlag = 0;
uint32_t openPortFlag = 0;

//UI config value
uint32_t uiSelectChannelConfigIndex = 0;
uint32_t uiCanBaudrate = 1000000;//1M

char            g_AppName[XL_MAX_LENGTH+1]  = "xlCANdemo";            //!< Application name which is displayed in VHWconf
XLportHandle    g_xlPortHandle              = XL_INVALID_PORTHANDLE;  //!< Global porthandle (we use only one!)
XLdriverConfig  g_xlDrvConfig;                                        //!< Contains the actual hardware configuration
XLaccess        g_xlChannelMask             = 0;                      //!< Global channelmask (includes all founded channels)
XLaccess        g_xlPermissionMask          = 0;                      //!< Global permissionmask (includes all founded channels)
unsigned int    g_canFdSupport              = 0;                      //!< Global CAN FD support flag

VectorDriverChannelManage vectorDriverChannelConfig;

int VectorXLDriverDllLoad(void)
{
    vxlDllHandle = LoadLibrary(".\\vxlapi.dll");
    if(vxlDllHandle != NULL)
    {
        printf("LoadLibrary Successful\r\n");
        xlOpenDriver = GetProcAddress(vxlDllHandle,"xlOpenDriver");
        xlCloseDriver = GetProcAddress(vxlDllHandle,"xlCloseDriver"); 
        xlGetDriverConfig = GetProcAddress(vxlDllHandle,"xlGetDriverConfig"); 
        xlOpenPort = GetProcAddress(vxlDllHandle,"xlOpenPort");
        xlClosePort = GetProcAddress(vxlDllHandle,"xlClosePort");
        xlActivateChannel = GetProcAddress(vxlDllHandle,"xlActivateChannel");
        xlDeactivateChannel = GetProcAddress(vxlDllHandle,"xlDeactivateChannel");
        xlCanTransmit = GetProcAddress(vxlDllHandle,"xlCanTransmit");
        xlCanTransmitEx = GetProcAddress(vxlDllHandle,"xlCanTransmitEx"); 
        xlCanReceive = GetProcAddress(vxlDllHandle,"xlCanReceive");
        xlCanFdSetConfiguration = GetProcAddress(vxlDllHandle,"xlCanFdSetConfiguration"); 
        xlCanSetChannelBitrate = GetProcAddress(vxlDllHandle,"xlCanSetChannelBitrate"); 
        xlSetNotification = GetProcAddress(vxlDllHandle,"xlSetNotification");  
        xlCanGetEventString = GetProcAddress(vxlDllHandle,"xlCanGetEventString");
        xlGetEventString = GetProcAddress(vxlDllHandle,"xlGetEventString");
        xlGetErrorString = GetProcAddress(vxlDllHandle,"xlGetErrorString");
        return 0;
    }
    else
    {
        return -1;
    }
}
int VectorXLDriverDllUnLoad(void)
{
    if(vxlDllHandle != NULL) 
    {
        FreeLibrary(vxlDllHandle);    
    }
    return 0;
}
int VectorDeviceInit(void)
{
    XLstatus    xlStatus;     
    int i,j;
    
    vectorDriverChannelConfig.channelNum = 0;
    xlStatus = xlOpenDriver ();   
    if(XL_SUCCESS != xlStatus) 
    {
        return -1;
    }
    openDriverFlag = 1;
    xlStatus = xlGetDriverConfig(&g_xlDrvConfig);
  
    if(XL_SUCCESS != xlStatus)
    {
        return -1;
    }

    for (i=0,j=0; i < g_xlDrvConfig.channelCount; i++) 
    {
      // we take all hardware we found and supports CAN
        if (g_xlDrvConfig.channel[i].channelBusCapabilities & XL_BUS_ACTIVE_CAP_CAN)
        {         
        //收集CAN可配置通道信息
            vectorDriverChannelConfig.channel[j].channelBusCapabilities = g_xlDrvConfig.channel[i].channelBusCapabilities;
            vectorDriverChannelConfig.channel[j].channelCapabilities = g_xlDrvConfig.channel[i].channelCapabilities;
            vectorDriverChannelConfig.channel[j].channelIndex = g_xlDrvConfig.channel[i].channelIndex;
            vectorDriverChannelConfig.channel[j].channelMask = g_xlDrvConfig.channel[i].channelMask;
            strcpy(vectorDriverChannelConfig.channel[j].name,g_xlDrvConfig.channel[i].name);
            vectorDriverChannelConfig.channelNum = ++j;
          }
    }
    return 0;
}
int VectorDeviceChannelConfig(void)
{
    XLstatus    xlStatus;     
    XLaccess    xlChannelMaskFd = 0;
    int i,j;
    
    if(vectorDriverChannelConfig.channelNum == 0)
        return -1;
    
    if((vectorDriverChannelConfig.channel[uiSelectChannelConfigIndex].channelCapabilities & XL_CHANNEL_FLAG_CANFD_ISO_SUPPORT) > 0)
    {
        g_canFdSupport = 1;
    }
    else
    {
        
    }
    g_xlChannelMask = vectorDriverChannelConfig.channel[uiSelectChannelConfigIndex].channelMask;
    g_xlPermissionMask = g_xlChannelMask;
    
    if (g_canFdSupport) 
    {
      xlStatus = xlOpenPort(&g_xlPortHandle, g_AppName, g_xlChannelMask, &g_xlPermissionMask, 16000, XL_INTERFACE_VERSION_V4, XL_BUS_TYPE_CAN);
    }
    // if not, we make 'normal' CAN
    else 
    {
      xlStatus = xlOpenPort(&g_xlPortHandle, g_AppName, g_xlChannelMask, &g_xlPermissionMask, RX_QUEUE_SIZE, XL_INTERFACE_VERSION, XL_BUS_TYPE_CAN);
    }
    if(XL_SUCCESS != xlStatus)
    {
        return -1;
    }
    openPortFlag = 1;
    
    if(XL_INVALID_PORTHANDLE != g_xlPortHandle)
    {
        if(g_canFdSupport) 
        {
            XLcanFdConf fdParams;
        
            memset(&fdParams, 0, sizeof(fdParams));
        
            // arbitration bitrate
            fdParams.arbitrationBitRate = uiCanBaudrate;
            fdParams.tseg1Abr           = 6;
            fdParams.tseg2Abr           = 3;
            fdParams.sjwAbr             = 2;

            // data bitrate
            fdParams.dataBitRate = fdParams.arbitrationBitRate*2;
            fdParams.tseg1Dbr    = 6;
            fdParams.tseg2Dbr    = 3;
            fdParams.sjwDbr      = 2;

            xlStatus = xlCanFdSetConfiguration(g_xlPortHandle, g_xlChannelMask, &fdParams);
            if(XL_SUCCESS != xlStatus)
            {
                return -1;
            }            
        }
        else 
        {
            xlStatus = xlCanSetChannelBitrate(g_xlPortHandle, g_xlChannelMask, uiCanBaudrate);
            if(XL_SUCCESS != xlStatus)
            {
                return -1;
            }
        }
    }
    xlStatus = xlActivateChannel(g_xlPortHandle, g_xlChannelMask, XL_BUS_TYPE_CAN, XL_ACTIVATE_RESET_CLOCK);
    if(XL_SUCCESS != xlStatus)
    {
        return -1;
    }
    channelActiveFlag = 1;
    return 0;    
}
int VectorDeviceUnInit(void)
{
    if(channelActiveFlag > 0)
    {
        xlDeactivateChannel(g_xlPortHandle, g_xlChannelMask);
        channelActiveFlag = 0;
    }
    if(openPortFlag > 0)
    {
        xlClosePort(g_xlPortHandle); 
        openPortFlag = 0;
    }
    if(openDriverFlag > 0)
    {
        xlCloseDriver();  
        openDriverFlag = 0;
    }
    return 0;
}
int VectorDeviceRx(int *externFrame,int *id,int *dataLen,uint8_t *data)
{
    XLstatus          xlStatus;
    XLcanRxEvent    xlCanRxEvt; 
    int i,frameDataLen;
    unsigned char *frameData;

    
    xlStatus = xlCanReceive(g_xlPortHandle, &xlCanRxEvt);
    if(xlStatus != XL_ERR_QUEUE_IS_EMPTY ) 
    {
        if(xlCanRxEvt.tag != XL_CAN_EV_TAG_RX_OK)
            return -1;
        
        if((xlCanRxEvt.tagData.canRxOkMsg.canId & XL_CAN_EXT_MSG_ID) > 0)
        {
            *externFrame = 1;
            *id = xlCanRxEvt.tagData.canRxOkMsg.canId & (~XL_CAN_EXT_MSG_ID);
        }
        else
        {
            *externFrame = 0;
            *id = xlCanRxEvt.tagData.canRxOkMsg.canId;
        }
        
        *dataLen = xlCanRxEvt.tagData.canRxOkMsg.dlc;
        frameDataLen = xlCanRxEvt.tagData.canRxOkMsg.dlc;
        frameData = &xlCanRxEvt.tagData.canRxOkMsg.data[0];
        for(i=0;i<frameDataLen;i++)
        {
            data[i] = frameData[i];    
        }
        return 0;
    }
    else
    {
        return -1;        
    }
}
int VectorDeviceTx(int externFrame,int id,int dataLen,uint8_t *data)
{
    XLstatus      xlStatus;
    unsigned int cntSent;
    int i,frameDataLen;
    unsigned char *frameData;
    unsigned int  messageCount = 1;
    
  if(g_canFdSupport) 
  {
    XLcanTxEvent canTxEvt;
    
    memset(&canTxEvt, 0, sizeof(canTxEvt));
    canTxEvt.tag = XL_CAN_EV_TAG_TX_MSG;
    canTxEvt.transId = 0xFFFF;
    if(externFrame > 0)
    {
        canTxEvt.tagData.canMsg.canId = id | XL_CAN_EXT_MSG_ID;
    }
    else
    {
        canTxEvt.tagData.canMsg.canId = id;        
    }
    canTxEvt.tagData.canMsg.msgFlags  = 0;//CAN2.0 

    frameDataLen = dataLen;
    canTxEvt.tagData.canMsg.dlc       = dataLen; 
    frameData = canTxEvt.tagData.canMsg.data;
    for(i=0;i<frameDataLen;i++)
    {
        frameData[i] = data[i];    
    }
    g_xlChannelMask = 1 << (17 - 1);
    xlStatus = xlCanTransmitEx(g_xlPortHandle, g_xlChannelMask, messageCount, &cntSent, &canTxEvt);
  }
  else 
  {
    XLevent       xlEvent;
    memset(&xlEvent, 0, sizeof(xlEvent));

    xlEvent.tag               = XL_TRANSMIT_MSG;
    xlEvent.tagData.msg.id    = id;
    xlEvent.tagData.msg.flags = 0;
    xlEvent.tagData.msg.dlc   = dataLen;
    frameData = xlEvent.tagData.msg.data;
    for(i=0;i<frameDataLen;i++)
    {
        frameData[i] = data[i];    
    }

    xlStatus = xlCanTransmit(g_xlPortHandle, g_xlChannelMask, &messageCount, &xlEvent);
  }
    return 0;    
}

驱动使用:

       在使用本章抽象代码之前,需要先调用VectorXLDriverDllLoad加载vxlapi.dll驱动函数,然后调用VectorDeviceInit获得满足CAN通道的数组vectorDriverChannelConfig,然后通过UI界面选择CAN通道(uiSelectChannelConfigIndex)和CAN波特率(uiCanBaudrate),然后调用VectorDeviceChannelConfig配置CAN通道,最后就可以调用VectorDeviceRx和VectorDeviceTx进行报文的收发。当程序退出时,记得调用VectorDeviceUnInit和VectorXLDriverDllUnLoad。

上一篇:docker


下一篇:js中浅谈this对象(未补充完整)