基于CAN 驱动库的CAN 虚拟设备
2019-04-26吴效威唐怀栋乔海强张臻李茁
文/吴效威 唐怀栋 乔海强 张臻 李茁
通常在CAN 通信程序开发过程中,开发人员经常需要对程序进行仿真及调试。一般情况下,开发人员通常会采用硬件USB 转CAN板卡来进行CAN 通信程序的仿真或调试工作。USB 转CAN 板卡一般具备2 个CAN 口供开发人员使用,若通过在Windows 环境下编译的CAN 通信应用程序打开USB 转CAN 的0或者1 通道,此时若需通过CANTest 应用终端监听CAN 通信设备之间的报文,则会出现CANTest 应用无法正常打开USB 转CAN 设备的1 或0 通道现象出现,该现象即应用程序对USB 转CAN 设备操作的独占性,仿真或调试过程中由此现象导致硬件资源出现浪费的现象时有发生 。
通常情况下,上述问题可通过2 块USB转CAN 设备并联方案解决,但是对硬件资源产生了巨大的需求及浪费,经济性较差。理论上若应用程序在使用CAN0 的同时使用CAN1充当CAN Test 软件,二者之间进行报文交互,即可模拟应用程序CAN 通信测试功能,但是在应用程序中内置CAN Test 软件的功能,会造成应用程序架构的冗余,对程序的稳定性和可靠性都会产生影响。
针对上述问题,本文提出了一种基于CAN 虚拟设备的方法,通过对CAN 虚拟设备制作及多CAN 设备及其通道自由连接方法的分析及研究,将虚拟CAN 接口函数和VC 界面相结合,开发了一种CAN 虚拟设备。在无USB 转CAN 条件下,通过CAN 虚拟设备即可完成即可实现在编写应用程序的过程中对程序CAN 通信功能的测试,有效降低了测试环境搭建所需硬件资源及所需投入成本。
1 CAN虚拟设备设计方案
CAN 虚拟设备主要由操作界面部分和接口函数两部分组成。
1.1 操作界面
为了实现对多个CAN 设备及其通道进行自由连接,需对CAN 虚拟设备操作界面进行详细设计。
如图1所示,该操作界面共包含8 个CAN 设备,在操作界面的第一行表示,设备索引号从左到右依次是0 到7;每个CAN 设备均有2 个CAN 通道,从左到右的通道号分别是0 和1。其中黑框框起来的CAN 设备表示该设备已经被其他程序打开,CAN 通道变成黄色表示该通道已经完成比特率和滤波等参数设置,白色表示未设置。CAN 通道下面延伸出的黑色、灰色的竖线,表示CAN 通道的状态。如图所示,索引0 的通道0,以及索引1 的通道0,下部均延伸出双黑线,表示0 通道已经正常打开,可以进行正常发送和接收;索引2 的通道0,下面延伸出单黑线,表示该通道设置为“只听”模式,可以进行接收,但无法进行发送,也无法对收到的报文进行回应;其他通道都是双灰线,表示无应用程序使用。
界面的主体有大量的彩色、黑色的双横线,以及处在横竖线交叉点上的指示块,指示块的颜色与所在的双横线颜色保持一致。彩色的双横线共8 条,若各通道对应的指示块均落在同一根彩线上,表示的上述通道是相连的,并且该条线上所有指示块之间的连线为了单条粗实线表示;黑色的双横线共1 条,各通道对应的指示块若落在黑色双横线上时表示通道为锁死状态(既不能自发自收,也不和其他通道相连)。另外,若出现一条彩线上只有1 个指示块的时,表示与该指示块对应的通道是孤立的(可以自发自收,但与其他通道不相连)[3]。
根据上述界面可知,共提供了8 个CAN虚拟设备,共计16 个CAN 通道,每个CAN网络至少需要2 个CAN 通道,所以我们通过上述8 条双横线上各通道对应指示块的组合即可实现这16 个CAN 通道进行任意的连接组合,针对需要孤立的通道,可通过将其对应的指示块与黑色双横线连接即可。
针对调试过程中出现主动停止调试,或者程序崩溃等现象,均可导致设备被永久占用,界面设计时提供一个解锁功能,通过鼠标点击界面的第一行任何一个设备,即可以解除占用。上述操作界面只允许出现一个,因此检测到新程序后,旧程序自动退出。完成操作界面之后,生成的程序命名为
“connect_can.exe”。
1.2 接口函数设计
为了实现报文收发,需要编写动态库,并提供接口库函数,共计14 个,其中大部分函数作用均为实现对CAN 设备的控制,譬如开关状态的转换、比特率设置和滤波设置等,仅需对参数合法性验证简单处理即可。VCI_Transmit 为核心库函数,该函数发出的报文可由VCI_GetReceiveNum,VCI_ClearBuffer,VCI_Receive 来处理。每个通道均具有相对应的接收缓冲区,从而实现将报文从其中一个CAN 通道传递至其他CAN 通道。虚拟CAN的各个函数,不仅需支持进程内部的多线程操作,而且需要支持跨越多个进程之间的操作。为了便于操作,可采用进程间共享内存的方式,对缓冲区进行操作。发送函数需获得与之相连接的设备及其设置参数方可实现发送功能。操作界面和动态库之间需通过内存共享来实现数据共享。不论多线程或者单线程,为了确保线程安全,对缓冲区的操作前需进行加锁设置,操作完成后解锁,防止出现多个线程同时对同一个缓冲区操作导致的非法状态,可采用标准库中的标准原子操作实现加锁操作。
针对发送函数,主要需作如下处理:
(1)必须对参数进行验证,任何一个参数无效均返回0,表示失败。
(2)确定设备是否已经打开、通道是否已经挂在彩色的双横线上、通道是否已经初始化、通道是否工作于非只听模式、通道是否已经打开,其中任何一个不满足,均返回0。鉴于函数均有返回值,在通过上述验证工作后,通过变量(初始值为0)对成功发送的报文数量进行计数,对所有CAN 通道进行遍历,并对每个CAN 通道进行相应处理。对于每一条报文,都要定义一个发送成功标志,这个标志初始值为假,然后遍历各个目标通道。遍历目标通道时,首先对发送方和遍历目标进行比较:对于不是“自发自收”类型的报文,发送方和遍历目标不同,才能通过;反过来,对于是“自发自收”类型的报文,只有发送方和遍历目标一致,才能通过。对遍历目标继续判断:它所在的设备必须已经打开;通道必须已经初始化并打开;必须挂在和发送方相同颜色的双横线上;它的比特率必须与发送方的一致。接下来要讨论目标的运行模式,是正常模式还是只听模式。不论是什么模式,都只是影响发送成功标志,而不会影响对方的接收。对正常模式,将发送成功标置为真。然后不论是正常模式还是只听模式,都可以进行后续处理。
图1:CAN 虚拟设备操作界面
图2:默认连接方式
(3)进行接收方的验收滤波处理。验收通过后数据存入目标的缓冲区,验收不通过放弃数据。不论验收是否通过,对之前的发送成功标志均无影响。对缓冲区的操作前需进行加锁处理,完成后进行解锁。一般情况下,缓冲区的容量均有限,若在缓冲区存储已满下仍继续接受报文,则易产生数据丢帧现象。可采用报文最新收到的数据,丢弃历史数据的处理方法进行处理。当全部目标遍历完成后,即可对报文的发送成功标志位进行置位:若标志位为假,程序直接终止后续处理,直接返回发送成功报文数量;若标志位为真,报文发送成功数量自加1。
该程序的核心是对报文传递的验证操作,在实现上述14 个接口函数后,生成动态库“virtual_can.dll”。
2 虚拟设备使用方法
当使用虚拟CAN 时,将动态库“virtual_can.dll”重新命名为“controlcan.dll”,并放置在与应用程序相同的路径下,替换掉原来的同名文件。在Debug 模式下使用虚拟CAN,在Release 模式下使用USBCAN,仅需设置好各自的工作目录即可,同时将“virtual_can.dll”改名为“controlcan.dll”的动态库放置在Debug 模式的工作目录中,将“usbcan.dll”改名为“controlcan.dll”的动态库放置在Release模式的工作目录中。完成上述操作即可实现“VCI_USBCAN2”在应用程序中的设备类型中的统一使用。
对于CAN Test 工具,则需要对工具下的配置文件进行修改处理。如上所述,首先为工具的安装路径下的“cfg.ini”文件,该文件会影响界面的菜单。改完之后保存;然后打开安装路径下的“kerneldlls”目录,将制作好的“virtual_can.dll”动态库复制到该目录下;最后修改这个目录下的“kerneldll.ini”文件,修改完成后保存。
将“connect_can.exe”文件放置在任意路径中即可,打开这个文件即可显示操作界面。为了使用者方便,该界面默认状态下的连接方式如图2所示。
打开CAN Test 软件,点击“选择设备”按钮,即可看到虚拟CAN 的菜单项了,打开之后即可进行正常使用。
另外,根据图2所示默认连接方式,用户也可通过直接打开应用程序和CAN Test 软件方式来使用虚拟CAN 设备。用户可以随时打开操作界面,对连接方式进行修改,也可以随时关闭操作界面,以节省打开窗口的数量。与虚拟CAN 有关的所有进程,包括操作界面、使用到虚拟CAN 的应用程序、使用到虚拟CAN 的CAN Test 软件,全部关闭之后,共享内存会由操作系统释放,因此连接方式的配置会消失,重新打开后会恢复默认连接方式。
3 实验结果与分析
打开4 个CAN Test 软件界面,每个界面下打开2 块虚拟CAN,每个虚拟CAN 的两个通道都打开,然后在操作界面 将全部的16 个通道连接在一起,每个通道连续发送10 万条报文,同时发送不会丢帧,每个通道都收到了150 万条报文。
4 结论
本文针对Windows 操作系统环境下采用USB 转CAN 设备进行应用程序CAN 通信测试存在的一些问题,提出了一种CAN 虚拟设备设计及测试方法。通过CAN 虚拟设备,在无需USB 转CAN 辅助硬件设备条件下即可实现对Windows 操作系统环境下编译的应用程序CAN 通信功能测试,实验结果再次表明了该方法的有效性和可行性。该方法减少了搭建硬件测试环境工作量,有效降低了测试所需的硬件成本,具备较好的经济性。