作者:尹加豹 , 朱涛 , 崔凯华

摘要:

为在VxWorks系统下实现龙芯3A3000主板的控制器局域网(CAN)总线通信,采用SJA1000T设计基于PCI总线的8通道CAN通信板,并提出相应的驱动设计和优化方案。对龙芯3A3000处理器的驱动进行优化,在发送数据时禁用CAN而使用查询方式发送,在接收数据时中断服务程序对所有通道进行遍历查询,以提高中断利用率,在创建设备函数时根据PCI总线信息识别每个CAN通信板,以确保系统中不同CAN通道拥有唯一的通道号。实验结果表明,该驱动方案运行稳定,数据传输安全可靠,经优化后能够有效降低CAN通信板的中断次数,提高CAN总线的通信速率,避免多板环境下故障板卡干扰正常板卡,提高了系统的健壮性。

关键词:

VxWorks系统 控制器局域网总线 SJA1000T控制器 龙芯3A 驱动设计

0 概述

控制器局域网(Controller Area Network, CAN)总线是一种多主机半双工异步串行通信总线, 具有实时性好、抗干扰性强、数据传输率高和成本低等优点, 是应用最广泛的现场总线之一[1]。VxWorks系统在众多嵌入式实时操作系统中具有强大的竞争力和非常重要的地位, 在通信、航空航天、军工等领域具有广泛应用[2]。VxWorks系统下的CAN总线通信应用于各行各业, 在多种硬件平台上都有成熟的设计方案。文献[3]介绍了基于SPARC V8架构的S698系列处理器内CAN模块的驱动设计方法, 文献[4-5]给出ARM及X86平台独立CAN控制器驱动的设计及优化方法, 上述CAN驱动都是基于国外先进处理器设计, 且CAN通道路数在两路以内。由于在国内一些关键领域, 需要使用自主可控的硬件方案, 在一些特殊领域, 甚至需要使用多达数十路CAN通道, 因此现有的驱动设计方案无法满足应用要求。

本文在龙芯3A3000主板上研究开发CAN总线驱动程序, 龙芯系列处理器是自主化程度最高的国产处理器, 其中, 3A3000/3B3000采用28 nm工艺制造, 配置为单节点4核, 工作主频为1.2 GHz~1.5 GHz[6]。在MIPS平台上, 基于VxWorks系统的CAN驱动研究成果甚少, 在龙芯3A3000主板上进行多板多通道CAN通信时, CAN驱动程序的中断频率过高、运行效率较低, 且CAN板之间未进行故障隔离。针对上述问题, 本文在发送、接收及设备创建等环节进行了一系列优化设计, 以提高系统的运行效率和健壮性。

1 硬件设计

CAN通信板共有8路独立的CAN总线接口, 其硬件结构主要由6个部分构成, 分别为CPCI总线接口单元、PCI桥接单元、FPGA可编程逻辑单元、电平转换单元、CAN总线单元以及供电单元, 其组成及原理框图如图 1所示。

Composition and functional block diagram of CAN communication board

图 1 CAN通信板组成及原理框图

Fig. 1 Composition and functional block diagram of CAN communication board

由图 1可知, CAN总线单元主要由CAN总线控制器、高速光隔离器、CAN总线收发器构成。CAN总线控制器选用SJA1000T, 该芯片具有BasicCAN和PeliCAN两种工作模式[7], 其中, PeliCAN模式支持CAN2.0B协议, 本文使用PeliCAN模式[8]。

2 VxWorks驱动程序接口

驱动程序用于控制某个硬件完成其固有功能, 它直接与硬件设备交互, 主要操作就是配置硬件相关寄存器, 驱动程序作为接口层, 对上要匹配操作系统提供的一套规范接口, 对下要驱动硬件设备完成工作[9]。

在VxWorks操作系统中, 大部分设备使用文件方式进行管理, 应用程序通过I/O请求访问设备文件, 进而操作对应的硬件设备, 系统将应用程序的I/O请求传递给设备专用的I/O函数, 而驱动程序的主要作用就是为这些设备提供专用的I/O函数[10]。具体的过程依靠3张表, 即文件描述表、设备列表与驱动程序列表实现。

VxWorks操作系统的所有驱动程序的入口函数地址均由驱动程序列表负责维护, 驱动程序列表中的每一行对应一个设备驱动程序, 每行包含7列, 对应7个函数指针, 这些函数就是要实现的设备驱动程序, 当设备执行creat、delete、open、close、read、write和ioctl函数时, 需回调对应的驱动函数。VxWorks系统通过iosDrvInstall函数将驱动程序的函数入口地址注册到驱动程序列表中, iosDrvInstall函数定义如下:


int iosDrvInstall(FUNCPTR create, FUNCPTR remove, FUNCPTR open, FUNCPTR close, FUNCPTR read, FUNCPTR write, FUNCPTR ioctl)。

在驱动程序中, 每一个设备都有一个数据结构, 被称为设备描述符, 用于存储相关数据。每个设备的设备描述符都有一个结构相同的起始部分, 即设备头数据结构, I/O系统通过设备头将所有设备描述符链接在一起构成设备列表。驱动程序通过iosDevAdd函数创建设备, 并在设备列表中新建节点, iosDevAdd函数定义如下:


int iosDevAdd(DEV_HDR * p_hdr, const char * dev_name, int drv_num)。

以打开设备为例, 驱动程序的工作流程如图 2所示[11]。

Workflow of the driver

图 2 驱动程序的工作流程

Fig. 2 Workflow of the driver

3 CAN驱动程序设计

VxWorks下CAN驱动的设计工作主要包括I/O接口函数设计、中断处理函数设计、驱动初始化函数设计和设备创建函数[12]设计。

3.1 I/O接口函数

I/O接口函数需要实现can_open、can_close、can_read、can_write和can_ioctl 5个函数。创建CAN设备结构体, 针对SJA1000T控制器设计的结构体如下:


typedef struct {

DEV_HDR can_hdr; /*设备头*/

BOOL opened; /*打开标识*/

MSG_Q_ID msg_id; /*消息队列*/

unsigned char index; /*通道序号*/

unsigned char mode; /*滤波方式*/

unsigned long baudrate; /*波特率*/

unsigned long acc_code; /*接收代码值*/

unsigned long acc_mask; /*接收屏蔽值*/

}CAN_DEV;

I/O接口函数设计包括以下5个部分:

1) can_open函数设计

函数原型为int can_open (DEV_HDR *dev, int option, int flags), 主要用于配置CAN控制器为工作模式, 并执行一些配置操作, 最后返回设备结构体指针[13]。

2) can_close函数设计

函数原型为int can_close (DEV_HDR *dev), 主要用于配置CAN控制器为复位模式, 并清除一些状态参数。

3) can_read函数设计

函数原型为int can_read (int dev_id, char *pBuf, int nBytes), 主要用于接收总线上的CAN数据帧, SJA1000T收到CAN帧后会提起中断, 中断处理程序接收CAN帧并发送到消息队列, can_read则直接读取消息队列, 若消息队列中有数据则读取至缓冲区, 若无数据则进行阻塞。

4) can_write函数设计

函数原型为int can_write (int dev_id, char *pBuf, int nBytes), 主要用于向总线发送CAN数据帧, 为降低通信板提起的中断频率, SJA1000T的发送中断被禁用, 改用查询方式, 发送先前查询SJA1000T状态寄存器的发送缓冲器状态, 若为释放状态则立即发送CAN帧, 若为锁定状态则循环判断状态, 直至超时返回。具体发送流程如图 3所示。

Procedure of sending function

图 3 函数的发送流程

Fig. 3 Procedure of sending function

5) can_ioctl函数设计

函数原型为int can_ioctl(int dev_id, int cmd, int arg), 主要用于配置CAN通道参数, 如波特率、滤波方式及参数等。

3.2 中断处理函数

VxWorks作为一个嵌入式实时操作系统, 采用中断的方式来满足系统实时性要求, 中断服务程序的高效执行至关重要[14]。SJA1000T有多种中断类型, 包括发送中断、接收中断、错误报警中断、数据溢出中断、总线错误中断等[15]。中断处理函数首先判断中断状态再进行相应处理, CAN通信板的8个SJA1000T芯片共享一个中断号, 中断方式为低电平中断。对于接收中断, 在释放完SJA1000T接收缓冲器中的CAN帧后会自动清除中断。

龙芯3A3000主板的板级支持包在设计时将所有外部中断都路由到一个CPU, 其外部中断过多, 导致系统运行效率降低[16]。为降低CAN通信板的中断频率, 禁用发送中断, 仅使用错误报警中断和接收中断并对中断处理函数进行优化。当接收到数据后, 中断处理函数对CAN通信板的8个SJA1000T芯片的状态寄存器进行遍历查询, 若发现接收缓冲区有数据则接收这些数据, 优化后的处理流程如图 4所示。

Optimized interrupt handling procedure

图 4 优化后的中断处理流程

Fig. 4 Optimized interrupt handling procedure

3.3 驱动初始化函数

驱动初始化函数的主要工作是调用iosDrvInstall函数, 将can_open、can_close、can_read、can_write和can_ioctl函数注册到驱动程序列表中[17]。在此之前, 要先确定系统正常工作时每一块CAN通信板的PCI总线信息, 并为其分配通道号, 本文系统共有3块CAN通信板、24路CAN通道, PCI总线信息和通道分配如表 1所示。

PCI bus information and channel allocation of CAN bus board

表 1 CAN通信板PCI总线信息及通道分配

Table 1 PCI bus information and channel allocation of CAN bus board

驱动初始化函数, 通过pciFindDevice函数查找所有的CAN通信板[18], 并将其PCI总线信息与表 1信息进行对比, 以确定每个通信板的状态, 具体代码如下:



STATUS can_drv (void)
{

int i, j;

if (can_drv_num>0)/*驱动程序已安装*/

return OK;

/*查找CAN板*/

for(i=0;(OK == pciFindDevice(VENDER_ID, DEVICE_ID, i, &bus, &slot, &func)) &&(i < 3);i++)

{

for(j=0;j < 3;j++)

{/*查找该CAN板对应的板号并进行标记*/

if((pci_bus_info[i].bus == bus) &&\\

(pci_bus_info[i].slot == slot) &&\\

(pci_bus_info[i].func == func))

can_board_found[i] = TRUE;

}

}

/*将驱动程序添加到驱动程序描述表中*/

if((can_drv_num = iosDrvInstall(can_open, (FUNCPTR)NULL, can_open, can_close, can_read, can_write, can_ioctl)) == ERROR)

return ERROR;

return OK;

}

3.4 设备创建函数

CAN驱动的设备创建函数的输入参数为设备名和通道号。该函数首先要判断该通道号对应的CAN通信板是否存在, 若存在则初始化该CAN通道并调用iosDevAdd函数, 将CAN设备添加到设备列表中[19], 具体代码如下:


STATUS can_dev_create(char * name, int i)
{

if((name==NULL) || (i < 0) || (i > 23) || (can_dev_created[i]==TRUE))

return ERROR;

/*判断该通道号对应的CAN通信板是否存在*/

if(can_board_found[i/8] == FALSE)

return ERROR;

p_can_dev[i] = (CAN_DEV*)malloc (sizeof(CAN_DEV));

…

/*初始化SJA1000T, 并将其添加到设备列表*/

if((SJA1000T_init(p_can_dev[i], i) == ERROR) || \\

(iosDevAdd(& p_can_dev[i]->can_hdr, name, can_drv_num) == NULL))

{

free((char*)p_can_dev[i]);

return ERROR;

}

can_dev_created[i] = TRUE;

return OK;

}

4 测试与分析

本文在龙芯3A3000主板上对CAN通信板进行测试, 测试内容包括CAN总线并行工作时CAN帧的传输效率和驱动程序的健壮性。

传输效率主要通过CAN帧的收发速度和中断的提起频率进行衡量。计算机系统运行期间, 各个模块均占用系统资源, 若各模块中断频率过高, 会使系统性能下降, 甚至造成系统“假死机”[20]。通过优化, 在高速通信时, CAN通信板的中断频率显著下降, 具体结果见表 2。

Comparison of transmission efficiency of CAN communication board

表 2 CAN通信板传输效率对比

Table 2 Comparison of transmission efficiency of CAN communication board

驱动程序健壮性主要是测试部分CAN板异常时系统的运行情况, 具体方法是任意拔下1~2块CAN通信板, 造成CAN通信板异常。以第1号CAN通信板异常为例, 驱动程序优化前后的通道号分配如表 3所示。优化前, 第1号板卡异常, 使得第2号板卡的CAN通道号变为8~15, 在使用过程中可能会造成严重后果; 优化后, 第1号板卡异常不可用, 但第0号和第2号板卡可正常使用, 异常板卡被成功隔离。

Comparison of channel numbers after the CAN communication board No.1 is damaged

表 3 1号CAN通信板损坏后的通道号对比

Table 3 Comparison of channel numbers after the CAN communication board No.1 is damaged

测试结果表明, 针对CAN接收中断进行优化后, 有效降低了高速通信时系统的中断频率, 提高了系统性能。针对多通信板进行的优化能够有效隔离问题板卡, 提高系统的健壮性, 保证计算机系统稳定可靠运行。

5 结束语

本文以龙芯3A3000主板为硬件平台, 在VxWorks系统下提出一种CAN控制器驱动的设计与优化方案。在初始化时, 使用PCI信息标记各个模块, 在发送环节, 使用查询方式进行发送, 并通过对所有通道进行查询遍历来接收数据。实验结果表明, 该驱动程序工作稳定, 性能可靠。本文主要针对龙芯3A3000主板进行设计和优化, 下一步将把优化方案推广到2K1000等其他龙芯主板上, 拓展其应用范围。

参考文献


[1]	CAO Jianqiu, HU Xiaoji. Design and implementation of anti-harsh environment intelligent CAN communication card based on VxWorks[J]. Computer Measurement and Control, 2013, 21(8): 2241-2245. (in Chinese)
曹建秋, 胡晓吉. 基于VxWorks的抗恶劣环境智能型CAN通讯卡的设计与实现[J]. 计算机测量与控制, 2013, 21(8): 2241-2245. DOI:10.3969/j.issn.1671-4598.2013.08.066
[2]	BARBALACE A, LUCHETTA A, MANDUCHI G, et al. Performance comparison of VxWorks, Linux, RTAI, and Xenomai in a hard real-time application[J]. IEEE Transactions on Nuclear Science, 2008, 55(1): 435-439. DOI:10.1109/TNS.2007.905231
[3]	LUO Jiehua. Application and development of CAN under VxWorks based on the processer of S698[J]. Measurement and Control Technology, 2014, 33(3): 117-120. (in Chinese)
骆杰华. 基于S698的VxWorks操作系统CAN应用与开发[J]. 测控技术, 2014, 33(3): 117-120. DOI:10.3969/j.issn.1000-8829.2014.03.030
[4]	YOU Zhongyu.Design and implementation of vehicle display platform based on ARM cortex application processor and VxWorks operating system[D].Beijing: Beijing University of Posts and Telecommunications, 2018.(in Chinese)
由忠宇.基于ARM Cortex应用处理器和VxWorks操作系统的车载显示平台设计与实现[D].北京: 北京邮电大学, 2018. http://cdmd.cnki.com.cn/Article/CDMD-10013-1018111253.htm
[5]	SHEN Erjian, ZHANG Tao, HUANG Liangwei, et al.A real-time simulation system for satellite based on RTW and VxWorks[C]//Proceedings of 2010 International Symposium on Systems and Control in Aeronautics and Astronautics.Washington D.C., USA: IEEE Press, 2010: 859-864. https://ieeexplore.ieee.org/document/5633094
[6]	Loongson Technology.User's manual of Loongson 3A3000/3B3000 processor[EB/OL].[2019-03-13].https://www.docin.com/p-1997202464.html.(in Chinese)
龙芯中科.龙芯3A3000/3B3000处理器用户手册[EB/OL].[2019-03-13].https://www.docin.com/p-1997202464.html.
[7]	WindRiver.VxWorks programmer's guide 6.9[EB/OL].[2019-03-13].http://www.staroceans.org/kernel-and-driver/vxworks_device_driver_developers_guide_vol3_6.6.pdf.
[8]	ZHANG Yang, YU Yintao. Detailed explanation of VxWorks kernel, device driver and BSP development[M]. Beijing: People's Posts and Telecommunications Press, 2009. (in Chinese)
张杨, 于银涛. VxWorks内核、设备驱动与BSP开发详解[M]. 北京: 人民邮电出版社, 2009.
[9]	LIAO Wenjiang, DONG Nanping, FAN Tongshun.Design of the embedded remote monitor system for building automation system based on the VxWorks[C]//Proceedings of Asia-Pacific Conference on Computational Intelligence and Industrial Applications.Washington D.C., USA: IEEE Press, 2010: 436-438. http://ieeexplore.ieee.org/document/5406396/
[10]	CAO Guiping. Detailed explanation of VxWorks device driver development[M]. Beijing: Electronic Industry Press, 2011. (in Chinese)
曹桂平. VxWorks设备驱动开发详解[M]. 北京: 电子工业出版社, 2011.
[11]	LI Guoyong, YU Da, SHI Gang, et al. Design of datacontrol system based on CAN bus[J]. Instrument Technology, 2010(1): 15-20. (in Chinese)
李国勇, 俞达, 石刚, 等. 基于CAN总线的数据采集系统设计[J]. 仪表技术, 2010(1): 15-20. DOI:10.3969/j.issn.1006-2394.2010.01.006
[12]	LI Yanwei, CHEN Qiangen, ZHU Yi. Evelopment of CAN driver under embedded operation system VxWorks[J]. Industrial Control Computer, 2006, 19(10): 30-32. (in Chinese)
李延伟, 陈欠根, 朱毅. 嵌入式操作系统VxWorks下CAN驱动程序开发[J]. 工业控制计算机, 2006, 19(10): 30-32. DOI:10.3969/j.issn.1001-182X.2006.10.015
[13]	LI Hanbing.Design and implementation of CAN communication card under VxWorks operating system[D].Chengdu: Southwest Jiaotong University, 2013.(in Chinese)
李寒冰.VxWorks操作系统下CAN通讯卡的设计与实现[D].成都: 西南交通大学, 2013. http://d.wanfangdata.com.cn/Thesis/Y2319379
[14]	XU Qian. Research on interrupt control technology of Loongson 3A based on VxWorks[J]. Modern Electronics Technique, 2017, 40(14): 36-39. (in Chinese)
徐骞. VxWorks下龙芯3A中断控制技术的研究[J]. 现代电子技术, 2017, 40(14): 36-39.
[15]	ZHAO Xiangkun. Design of CAN bus driver based on VxWorks[J]. Industrial Control Computer, 2016, 29(6): 1-5. (in Chinese)
赵向坤. VxWorks下CAN总线驱动程序设计[J]. 工业控制计算机, 2016, 29(6): 1-5. DOI:10.3969/j.issn.1001-182X.2016.06.001
[16]	LU Huihui, YUAN Yuxiang. I2C bus driver based on embedded operating system VxWorks[J]. Microcontrollers and Embedded Systems, 2015, 15(8): 34-37. (in Chinese)
卢慧慧, 袁玉湘. 基于嵌入式操作系统VxWorks的I2C总线驱动设计[J]. 单片机与嵌入式系统应用, 2015, 15(8): 34-37.
[17]	WANG Lei, FAN Xiaoya, WANG Danghui. Research and implement of VxWorks porting based on Loongson 3A hardware platform[J]. Microelectronics and Computer, 2012, 29(2): 86-90. (in Chinese)
王雷, 樊晓桠, 王党辉. 龙芯3A平台Vxworks移植的研究和实现[J]. 微电子学与计算机, 2012, 29(2): 86-90.
[18]	HU Mingmin.Driver development based on real-time operating system VxWorks[D].Xi'an: Xidian University, 2012.(in Chinese)
胡明民.基于实时操作系统VxWorks的驱动程序开发[D].西安: 西安电子科技大学, 2012.
[19]	ZHENG Guohui, ZHANG Xiaolin, TIAN Li. Design of independent CAN controller IP core based on AMBA bus[J]. Computer Measurement and Control, 2013, 10(5): 2780-2782. (in Chinese)
郑国辉, 张小林, 田力. 基于AMBA总线的独立CAN控制器IP核设计与实现[J]. 计算机测量与控制, 2013, 10(5): 2780-2782.
[20]	WANG Zijian. Design of multi channel CAN bus with high speed communication based on FPGA FIFO management[J]. Computer Measurement and Control, 2015, 23(2): 558-560. (in Chinese)
王子健. 基于FPGA FIFO处理的多路CAN总线高速通信设计[J]. 计算机测量与控制, 2015, 23(2): 558-560. DOI:10.3969/j.issn.1671-4598.2015.02.067