焦新泉 袁小康 储成群
关键词: USB; 数据存储; ARM?Linux; Libusb库; CY7C68013; 接口函数
中图分类号: TN919?34; TP273 文献标识码: A 文章编号: 1004?373X(2019)06?0006?04
Abstract: The ARM microcontroller carried with the embedded Linux system can be taken as a handheld terminal to complete some complicated interaction functions on the personnel computer. The basic methods of data storage are implemented by driving the USB control chip CY7C68013 based on the Libusb library under the ARM?Linux platform. The direct access to the USB device CY7C68013 in the user space is realized based on the Libusb library under the ARM?Linux platform. The USB device development without any driver under the Linux can be realized by recalling the interface function provided by the Libusb library, during which the development personnel do not need to understand the complex USB protocol and Linux kernel mechanism.
Keywords: USB; data storage; ARM?Linux; Libusb library; CY7C68013; interface function
USB控制器在数据采集系统具有广泛的应用,通常将获取到的数据保存至PC机进行处理。随着嵌入式设备的日趋成熟,应用更加便携、灵活的嵌入式平台代替PC平台接收数据并进行分析成为可能。为此,以USB控制芯片CY7C68013为例,介绍了一种在嵌入式ARM?Linux平台的USB数据存储方法。
一个数据采集系统可以由如图1所示的系统组成。该系统主要是由FPGA和USB 2.0控制器CY7C68013组成,可以根据实际系统的需要,用FPGA实现预定功能,如数据采集卡、控制硬盘读写等[1]。采用嵌入式ARM平台代替PC机,将采集的数据通过USB传递给由ARM构成的上位机系统并显示到触摸屏上,实现数据采集处理与显示功能。本文使用的嵌入式ARM?Linux系统的硬件平台是深圳市英蓓特科技有限公司推出的基于德州仪器(TI)AM1808处理器的评估套件。AM1808处理器拥有丰富的外设资源,也是功耗最低的ARM9处理器之一,同时也是TI首批集成SATA的器件。这些特点使其非常适合在数据采集领域的应用。
CY7C68013是Cypress公司的一种单芯片集成USB 2.0收发器、能串行接口引擎(SIE)和增强型8051微处理器的功能强大的接口芯片,图2是它的结构框图。CY7C68013符合USB 2.0协议规范,可以按照USB设备进行开发。
2.1 USB简介
通用串行总线(Universal Serial Bus,USB)是一种用于规范电脑与外部设备的连接和通信的外部总线标准。USB设备逻辑上划分为设备(device)、配置(config)、接口(interface)和端點(endpoint)四个层次,并具有以下关系:设备可以有一个或多个配置;配置可以有一个或多个接口;接口可以有一个或多个设置;接口可以有一个或多个端点。
USB通信最基本的形式是通过端点(USB端点分中断、批量、等时、控制4种,每种功能不同),主机通过端点与设备进行通信[2]。
2.2 Libusb简介
USB协议是目前使用最广泛的外部总线协议,目前Linux对USB有了比较完善的支持。但由于USB所支持的设备的多样性,一些特殊的USB设备的驱动还需要开发人员自行编写。
在Linux平台,USB驱动开发主要有两种方式:一种是基于Linux内核编译驱动,需要在内核空间完成,通常是参考内核中USB_skeleton修改[3?4];另一种是基于Libusb库在用户空间实现(也称作“免驱”或者“无驱”设计)。本文主要介绍基于Libusb的USB验证性应用设计。
Libusb是一种高级别的API,它封装了低级别的内核与USB模块的交互,并提供了一系列适合在用户空间进行USB驱动开发的函数[5]。基于Libusb库的驱动设计具有与内核版本无关、跨平台的优点,无需对内核重新编译,也不用考虑内核版本兼容性,相对于内核编译大大降低了开发门槛,是一种高效的开发方式。Libusb提供了用户空间的结构体struct Libusb_XXX_descriptor描述设备、配置、接口和端点。可以按照描述根据Libusb_open(),Libusb_XXX_transfer();Libusb_close()等函数编写针对CY7C68013的特定功能的应用程序。
针对数据存取的基本功能,本文实现在ARM?Linux 2.6.33系统下基于Libusb设计CY7C68013驱动。应用针对Cypress官方提供的测试用固件例程bulkloop验证功能如
图3所示。图形用户界面使用Qt实现。整个
工作在图形编程工具Qt 4.5环境完成。
3.1 CY7C68013功能实现
CY7C68013的固件下载通过调用Cypress公司提供的对应Linux平台的函数cyUSB_download_fx2( ) 实现,函数依托于Cypress官网提供的Linux平台的cyUSB库,因此使用前需要将该库交叉编译到ARM?Linux平台编写的应用要先调用USB_init()函数进行初始化,初始化之后才能按照Libusb库进行操作。
Linux的宗旨是一切皆文件,而文件操作首先要打开设备。对USB设备操作也一样,开发人员可以使用Libusb_open(Libusb_device*dev,Libusb_device_handle **
handle);打开由VID/PID指定的USB设备。handle句柄作为对应USB的唯一标识,贯穿于设备的整个操作过程,直至最后调用Libusb_close(handle)关闭指定的USB设备,释放该句柄。
打开设备后通过四个层次的描述符struct Libusb_XXX_descriptor进行描述。USB设备将端点封装到接口,操作端点必须先要声明接口:Libusb_claim_interface(Libusb_device_handle *handle,int interface_number)。其中interface_number是所要聲明的接口号码。Libusb完成的是用户层的操作,操作前必须解除内核对接口的占用:
Libusb_kernel_driver_active(Libusb_device_handle*dev,int interface_number); //该函数判断内核是否占用这个接口
Libusb_detach_kernel_driver(Libusb_device_handle *dev,int interface_number); //该函数解除内核对这个接口的占用
声明接口后利用结构体端点描述符该接口的端点及其他信息:
struct Libusb_endpoint_descriptor {uint8_t bLength;
//端点长度
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
//端点地址,可以用来确定端点传输的方向
uint8_t bmAttributes; //端点类型(四种)
uint16_t wMaxPacketSize; //最大数据尺寸
uint8_t bInterval;
uint8_t bRefresh;
uint8_t bSynchAddress;
};
之后可以根据端点的属性通过操作函数Libusb_
XXX_transfer()结合文件操作函数实现数据传输存储功能。
根据固件功能使用端点块传输函数实现数据回环:
Libusb_bulk_transfer(dev_handle,out_endpoint,data,length,actual_length, timeout);
Libusb_bulk_transfer(dev_handle,in_endpoint,data,length,actual_length, timeout);
之后根据Linux文件操作将数据进行保存:
/*将data缓冲区数据写入句柄fp指向的文件当中,返回写入字节数*/
sum=write(fp, data, actual_length);
完成操作后调用Libusb_close()函数关闭指定的USB设备,释放句柄。
3.2 SATA硬盘存储功能实现
Linux 2.6系统内核已经支持了SATA的读/写,只需在内核编译时勾选即可。Linux 2.6系统对ntfs格式写支持不很完善,把第三方库ntfs?3g交叉编译到ARM?Linux,完善对SATA硬盘的读/写功能。在PC?linux端执行:
# ./configure CC=arm?none?linux?gnueabi?gcc ??host=arm?linux ??prefix=/home/ntfs/ ??exec?prefix=/home/ntfs/target
# make
# make install
把生成的动态库复制到开发板的/usr/local目录下。
3.3 程序移植
把在PC?Linux端编写好的数据传输应用程序以及CY7C68013需要的cyUSB库,触摸屏需要的QT库、tslib库用ARM?none?linux?gnueabi?gcc编译,并把编译生成的库文件复制到ARM?Linux的/usr/local目录下。之后添加环境变量,再修改系统启动时的等级,添加启动后执行的脚本使应用程序开机自启,即完成了专用设备的搭建。
本文用到的硬件有SBC8018开发板、基于CY7C68013和FPGA的读数盒、金士顿60 GB SATA固态硬盘、PC机及硬盘供电电源,如图4所示。
如图5所示,scan按钮实现USB硬件探测功能,设备信息显示在文本框当中;claim_iface按钮实现接口选择功能,USB协议逻辑上支持多接口,所以对于特殊功能的设备提供接口选择是值得的;in_ep,out_ep实现端点选择功能,根据CY7C68013固件,测试选择86端点入,2端点配套;rcv按钮实现数据接收功能,在文本框显示接收的数据及其ASCII码(字符B对应ASCII码值42)。save_as按钮实现将数据保存功能,保存操作如图6所示;reset按钮是硬件复位,两个clear按钮实现清屏功能。
嵌入式设备可以为数据采集系统设计验证带来方便。本文实现了在ARM?Linux平台下基于Libusb 库在用户空间直接访问USB设备CY7C68013。开发人员无需了解复杂的USB协议与Linux内核机制,通过Libusb 库提供的接口函数调用可以实现Linux下USB设备“无驱”开发。本文在AM1808开发平台上实现数据采集显示,为目前主流的嵌入式Linux平台的USB驱动开发提供参考,开发人员可以据此模型开发工程上的特定功能,提高开发效率缩短开发周期。
参考文献
[1] 谭安菊,龚彬.USB 2.0控制器CY7C68013与FPGA接口的Verilog HDL实现[J].电子工程师,2007,33(7):52?55.
TAN Anju, GONG Bin. Implementation of USB2.0 controller CY7C68013 and FPGA′s interface in Verilog HDL [J]. Electronic engineer, 2007, 33(7):52?55.
[2] 薛园园,赵建领.USB 应用开发实例详解[M].北京:人民教育出版社,2009.
XUE Yuanyuan, ZHAO Jianling. Detailed explanation of USB application development examples [M]. Beijing: People′s Education Press, 2009.
[3] 彭定军,陈安,高健华.嵌入式Linux下基于Libusb的USB驱动开发[J].技术与市场,2008(11):4?5.
PENG Dingjun, CHEN An, GAO Jianhua. Development of USB driver based on Libusb under embedded Linux [J]. Technology and market, 2008(11): 4?5.
[4] 杨强,王志斌,李晓,等.Linux中USB设备驱动程序的设计及其应用[J].济南大学学报(自然科学版),2014,28(3):224?229.
YANG Qiang, WANG Zhibin, LI Xiao, et al. Design of USB device driver in Linux and its applications [J]. Journal of University of Jinan (Science and technology), 2014, 28(3): 224?229.
[5] 杜敏杰,马彦恒,刘利民.Linux下基于CY7C68013芯片的USB设备驱动程序开发[J].科学技术与工程,2008,8(21):5933?5937.
DU Minjie, MA Yanheng, LIU Limin. USB device driver development of CY7C68013 chip under Linux [J]. Science technology and engineering, 2008, 8(21): 5933?5937.
[6] XU Z, LIU Z, ZHANG H, et al. Development of Linux based USB device driver for portable spectrometer [C]// Proceedings of 20st Annual International Conference on Chinese Control and Decision Conference. Guilin: IEEE, 2009: 5161?5164.
[7] 马宗骥,李佩玥,章明朝,等.基于FPGA+ARM的数据采集系统设计[J].化工自动化及仪表,2012,39(9):1187?1189.
MA Zongji, LI Peiyue, ZHANG Mingchao, et al.Design of data acquisition system based on FPGA and ARM [J]. Control and instruments in chemical industry, 2012, 39(9): 1187?1189.
[8] QI Guangping, SUN Peng. The embedded system design for military or industry personal data assistant [C]// Proceedings of IEEE International Conference on Computer Science and Automation Engineering. Zhangjiajie: IEEE, 2012: 521?525.
[9] 曾希强.Linux下基于Libusb的USB设备驱动程序设计与实现[J].信息与电脑,2009(7):101.
ZENG Xiqiang. Design and implementation of USB device driver in Linux based on Libusb [J]. China computer & communication, 2009(7): 101.
[10] 朱恩亮,赵腊才,茹伟,等.Linux环境下USB设备驱动程序设计[J].电子科技,2016,29(1):108?110.
ZHU Enliang, ZHAO Lacai, RU Wei, et al. Development of USB device drivers of Linux [J]. Electronic science and technology, 2016, 29(1): 108?110.