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];    
    }
    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。

### 如何为Vector设备安装或获取正确的驱动程序 为了确保Vector设备能够正常工作,必须正确识别该设备并加载相应的驱动程序。以下是关于如何为Vector设备安装或获取正确驱动程序的关键点: #### 1. 设备枚举与唯一ID分配 当Vector设备通过USB接口连接到计算机时,操作系统会自动执行设备枚举操作。在此过程中,系统将为设备分配一个唯一的设备ID[^1]。此ID通常由Vendor ID(供应商ID)和Product ID(产品ID)组成。 #### 2. 获取设备描述符 操作系统随后会读取设备的描述符信息,这些信息包含了设备的具体参数,例如: - **Vendor ID (VID)**:标识制造商。 - **Product ID (PID)**:区分具体的产品型号。 - **Device Class 和 Subclass**:定义设备的功能类别。 对于Vector设备而言,可以通过工具如`lsusb`命令查看其具体的Vendor ID和Product ID。例如,在Linux环境下运行以下命令可以列举所有已连接的USB设备及其属性: ```bash lsusb -v ``` #### 3. 驱动程序匹配 一旦获得了设备的描述符信息,操作系统便会尝试将其与预装的驱动程序列表进行匹配。这一步骤依赖于PCI配置空间中的Vendor ID和Device ID来定位适合的驱动程序[^2]。如果内置驱动无法满足需求,则需手动下载并安装厂商提供的专用驱动程序。 #### 4. 手动安装第三方驱动程序 假如默认的操作系统未能提供兼容的驱动支持,可以从Vector官方或其他可信来源获取最新的驱动包。以CAN适配器为例,常见的Vector系列可能包括VN16xx家族成员(VN1610, VN1611等)[^3]。针对这类硬件,应访问官方网站或者查阅相关文档资料确认适用版本,并按照说明完成安装步骤。 #### 5. 中断机制的应用(可选) 部分复杂功能的外设可能会涉及到中断处理逻辑的设计。比如某些按键输入场景下就需要利用请求(`request_irq`)和服务释放(`free_irq`)函数实现事件响应管理[^4]。虽然不是每种Vector设备都需要如此高级别的定制化编程,但对于特定用途来说了解这部分原理也是有益无害的。 ### 总结 综上所述,要成功部署Vector设备所需的驱动软件,首先要保证物理层面上的成功接入;其次借助标准协议提取必要的身份特征数据;最后依据实际情况决定采用现成解决方案还是自行编译调试专属方案。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值