3 基于VxWorks 的CAN 接口驱动程序设计
3.1 基于VxWorks 的嵌入系统的工作原理
本网关所采用的嵌入式操作系统 VxWorks是美国“风河”(Wind River)公司 开发研制的一种嵌入式实时操作系统(RTOS)。在众多的嵌入式操作系统中, VxWorks以良好的可靠性和卓越的实时性, 在军事、航空航海、通信、医疗等高科技技 术领域都有着广泛的应用与发展,在嵌入式 领域中占有极其重要的地位。VxWorks具有 小巧的内核、可被裁剪、广泛的硬件支持和 第三方软件开发商支持等优点,极大地提高 了程序员的开发效率[4]。
加电后,TC700首先启动VxWorks操作 系统,包括了两个映像的启动过程。一是 BootRom 映像; 另一是VxWorks 映像。 BootRom映像是一个最小化、专用的系统映 像,又称为启动映像,它保存在固定位置(如 FlashROM或ROM),主要负责加载和运行 最终使用的VxWorks映像。即在VxWorks操作系统正式启动之前,首先需要定制和建立 BootRom,然后通过它下载配置可加载的 VxWorks映像到RAM中运行。VxWorks映像 加载完毕后,系统就启动内核创建根任务 usrRoot,通过调用iosInit()函数初始化I/O 文件系统,初始化各个串口并安装驱动程 序。初始化工作完成之后,VxWorks操作系 统正式加载,网关开始工作。
3.2 SPI 接口驱动程序的开发
SPI接口驱动程序是为了完成TC700协 议转换器的CAN通信而设计的,在本系统 中,笔者通过移植u-boot中的spi.c文件使该 驱动能够在VxWorks操作系统下顺利运行。 在SPI接口的驱动程序spi.c中有三个主要的 功能函数:sysSpiHwInit()、spi_write()和 spi_read()。
(1) sysSpiHwInit(),使SPI能够正常工 作;初始化参数RAM;设置参数RAM和双 口RAM的基址等。
(2) spi_write(),该函数为SPI接口的写 函数,定义接收缓冲区和发送缓冲区指针变 量,并为其分配存储空间;写入写数据使能 控制字。
(3) spi_read(),该函数为SPI接口的读函 数,同样也需定义接收、发送缓冲区的指针 变量和分配存储空间;并写入读数据使能控 制字。
4 CAN 接口驱动程序流程
VxWorks 操作系统中的I/O 系统中有 两种基本设备类型[5]:字符设备和块存取设 备,本文中所研究的CAN 口设备属于字符 设备。I/O 系统为所有的字符设备提供统一 的访问接口[6],其基本作用就是,把用户请 求分配到与设备对应的驱动例程中去。
在 CAN 接口驱动程序的开发过程中,我们对VxWorks 的虚拟设备ttyDrv 进行封 装,使其向上将TTY 设备安装到标准的I/O 系统中去,从而完成上层程序对硬件设备的 操作;向下为实际的硬件设备提供底层的设 备驱动程序。
4.1 CAN 设备初始化过程
①网关设备加电后,操作系统启动, 创建根任务UsrRoot,并通过该任务调用iosInit ( )函数对VxWorks 的I/O系统进行初 始化;
②调用设备驱动初始化函数ttyDrv( ), 该函数先初始化CAN设备驱动程序,然后调 用iosLib 库中的函数iosDrvInstall( ),为该设 备的相关I/O驱动程序分配一个驱动号 (ttyDrvNum = iosDrvInstall (ttyOpen, (FUNCPTR) NULL, ttyOpen, ttyClose, tyRead, tyWrite, ttyIoctl);),并将其对应的 函数入口地址增加到驱动程序表中(drvTable);
③ttyDevCreate ( )函数用来创建设备 驱动。首先将已经定义并初始化的结构体 TYCO_DEV传递给ttyDevCreate ( )函数,然 后调用iosDevAdd ( )将设备名(该设备名称 为tyCo/4)和驱动号(ttyDrvNum)加入设 备链表(iosDvList)中。
CAN设备驱动的初始化工作主要包括 为读写缓冲区分配存储空间、创建读写同步 信号量和互斥信号量以及初始化等待任务 列表等。
4.2 CAN 设备驱动程序的访问过程
系统在对设备进行初始化完毕之后, 应用程序可以通过I/O系统对设备进行访 问。但在VxWorks中,应用程序是通过打开 命名文件来访问I/O设备的。对每个设备的访问都会看成是对一个文件的操作,每个被 打开的文件都会作为一个条目存储在文件 描述符表(fdTable)中[2]。
①调用open()函数打开要访问的设备 tyCo/4;
②I/O系统根据设备名(tyCo/4)在设 备链表(iosDvList)中进行查找匹配,返回 设备数据结构指针( TYCO_DEV * pTyCoDev);
③被打开的设备作为文件设备在文件 描述符表中被分配到一个空的文件条目 ( FD_ENTRY); ④I/O系统根据查找到的设备驱动号 (ttyDrvNum)在设备驱动程序表(drvTable) 中查找该设备对应的ttyOpen (TYCO_DEVpTyCoDev, char * name, int flags, intmode)驱动例程。如果成功,则通过该驱动例程将设备驱动描述符指针
(pTyCoDev)、设备文件名和驱动返回值存放在空的文件条目中,并返回一个文件描 述符(fd);
⑤应用程序通过调用ioLib中的read或 write函数对设备文件进行访问。首先,这两 个函数通过文件描述符(fd)找到对应的设 备描述符。然后根据设备描述符找到对应的 drvTable表,在DRVTABLE表中调用TTY设 备的例程函数tyWrite ()、tyRead (),通过这 两个例程函数调用驱动程序spi.c 中的 spi_write和spi_read函数与实际的CAN接口 硬件设备进行数据传输,从而实现CAN报文 的发送和接收。
5 结束语
本文的创新点是作者将UNIX系统下 的SPI接口程序移植到VxWorks系统下,使 其能在VxWorks系统下正常运行,从而完成 了TC700网关的CAN驱动程序的开发。另 外,本文提出的TC700CAN接口驱动程序的 设计,是VxWorks的驱动机制在X86平台上 的实现,其开发思路也能够为基于其他平台 的CAN接口驱动开发提供一些经验。传统的硬件驱动程序开发,需要开发人员使用汇编 语言编写软件程序。而在嵌入式系统中, TC700的驱动开发过程是在上层进行的,即 软件驱动程序的开发,通过高级语言进行程 序编写即可。实践调试结果表明:本文所设 计的网关实现了CAN接口驱动的功能,能可 靠的运行并能与CAN总线上的设备进行正 常的数据交换,充分体现了CAN总线高性 能、高可靠性的特点。
3 基于VxWorks 的CAN 接口驱动程序设计
3.1 基于VxWorks 的嵌入系统的工作原理
本网关所采用的嵌入式操作系统 VxWorks是美国“风河”(Wind River)公司 开发研制的一种嵌入式实时操作系统(RTOS)。在众多的嵌入式操作系统中, VxWorks以良好的可靠性和卓越的实时性, 在军事、航空航海、通信、医疗等高科技技 术领域都有着广泛的应用与发展,在嵌入式 领域中占有极其重要的地位。VxWorks具有 小巧的内核、可被裁剪、广泛的硬件支持和 第三方软件开发商支持等优点,极大地提高 了程序员的开发效率[4]。
加电后,TC700首先启动VxWorks操作 系统,包括了两个映像的启动过程。一是 BootRom 映像; 另一是VxWorks 映像。 BootRom映像是一个最小化、专用的系统映 像,又称为启动映像,它保存在固定位置(如 FlashROM或ROM),主要负责加载和运行 最终使用的VxWorks映像。即在VxWorks操作系统正式启动之前,首先需要定制和建立 BootRom,然后通过它下载配置可加载的 VxWorks映像到RAM中运行。VxWorks映像 加载完毕后,系统就启动内核创建根任务 usrRoot,通过调用iosInit()函数初始化I/O 文件系统,初始化各个串口并安装驱动程 序。初始化工作完成之后,VxWorks操作系 统正式加载,网关开始工作。
3.2 SPI 接口驱动程序的开发
SPI接口驱动程序是为了完成TC700协 议转换器的CAN通信而设计的,在本系统 中,笔者通过移植u-boot中的spi.c文件使该 驱动能够在VxWorks操作系统下顺利运行。 在SPI接口的驱动程序spi.c中有三个主要的 功能函数:sysSpiHwInit()、spi_write()和 spi_read()。
(1) sysSpiHwInit(),使SPI能够正常工 作;初始化参数RAM;设置参数RAM和双 口RAM的基址等。
(2) spi_write(),该函数为SPI接口的写 函数,定义接收缓冲区和发送缓冲区指针变 量,并为其分配存储空间;写入写数据使能 控制字。
(3) spi_read(),该函数为SPI接口的读函 数,同样也需定义接收、发送缓冲区的指针 变量和分配存储空间;并写入读数据使能控 制字。
4 CAN 接口驱动程序流程
VxWorks 操作系统中的I/O 系统中有 两种基本设备类型[5]:字符设备和块存取设 备,本文中所研究的CAN 口设备属于字符 设备。I/O 系统为所有的字符设备提供统一 的访问接口[6],其基本作用就是,把用户请 求分配到与设备对应的驱动例程中去。
在 CAN 接口驱动程序的开发过程中,我们对VxWorks 的虚拟设备ttyDrv 进行封 装,使其向上将TTY 设备安装到标准的I/O 系统中去,从而完成上层程序对硬件设备的 操作;向下为实际的硬件设备提供底层的设 备驱动程序。
4.1 CAN 设备初始化过程
①网关设备加电后,操作系统启动, 创建根任务UsrRoot,并通过该任务调用iosInit ( )函数对VxWorks 的I/O系统进行初 始化;
②调用设备驱动初始化函数ttyDrv( ), 该函数先初始化CAN设备驱动程序,然后调 用iosLib 库中的函数iosDrvInstall( ),为该设 备的相关I/O驱动程序分配一个驱动号 (ttyDrvNum = iosDrvInstall (ttyOpen, (FUNCPTR) NULL, ttyOpen, ttyClose, tyRead, tyWrite, ttyIoctl);),并将其对应的 函数入口地址增加到驱动程序表中(drvTable);
③ttyDevCreate ( )函数用来创建设备 驱动。首先将已经定义并初始化的结构体 TYCO_DEV传递给ttyDevCreate ( )函数,然 后调用iosDevAdd ( )将设备名(该设备名称 为tyCo/4)和驱动号(ttyDrvNum)加入设 备链表(iosDvList)中。
CAN设备驱动的初始化工作主要包括 为读写缓冲区分配存储空间、创建读写同步 信号量和互斥信号量以及初始化等待任务 列表等。
4.2 CAN 设备驱动程序的访问过程
系统在对设备进行初始化完毕之后, 应用程序可以通过I/O系统对设备进行访 问。但在VxWorks中,应用程序是通过打开 命名文件来访问I/O设备的。对每个设备的访问都会看成是对一个文件的操作,每个被 打开的文件都会作为一个条目存储在文件 描述符表(fdTable)中[2]。
①调用open()函数打开要访问的设备 tyCo/4;
②I/O系统根据设备名(tyCo/4)在设 备链表(iosDvList)中进行查找匹配,返回 设备数据结构指针( TYCO_DEV * pTyCoDev);
③被打开的设备作为文件设备在文件 描述符表中被分配到一个空的文件条目 ( FD_ENTRY); ④I/O系统根据查找到的设备驱动号 (ttyDrvNum)在设备驱动程序表(drvTable) 中查找该设备对应的ttyOpen (TYCO_DEVpTyCoDev, char * name, int flags, intmode)驱动例程。如果成功,则通过该驱动例程将设备驱动描述符指针
(pTyCoDev)、设备文件名和驱动返回值存放在空的文件条目中,并返回一个文件描 述符(fd);
⑤应用程序通过调用ioLib中的read或 write函数对设备文件进行访问。首先,这两 个函数通过文件描述符(fd)找到对应的设 备描述符。然后根据设备描述符找到对应的 drvTable表,在DRVTABLE表中调用TTY设 备的例程函数tyWrite ()、tyRead (),通过这 两个例程函数调用驱动程序spi.c 中的 spi_write和spi_read函数与实际的CAN接口 硬件设备进行数据传输,从而实现CAN报文 的发送和接收。
5 结束语
本文的创新点是作者将UNIX系统下 的SPI接口程序移植到VxWorks系统下,使 其能在VxWorks系统下正常运行,从而完成 了TC700网关的CAN驱动程序的开发。另 外,本文提出的TC700CAN接口驱动程序的 设计,是VxWorks的驱动机制在X86平台上 的实现,其开发思路也能够为基于其他平台 的CAN接口驱动开发提供一些经验。传统的硬件驱动程序开发,需要开发人员使用汇编 语言编写软件程序。而在嵌入式系统中, TC700的驱动开发过程是在上层进行的,即 软件驱动程序的开发,通过高级语言进行程 序编写即可。实践调试结果表明:本文所设 计的网关实现了CAN接口驱动的功能,能可 靠的运行并能与CAN总线上的设备进行正 常的数据交换,充分体现了CAN总线高性 能、高可靠性的特点。
举报