您好,  [请登录] [QQ登录]  [支付宝登录[免费注册]

商品分类

分享到: 百度搜藏 搜狐微博 新浪微博 腾讯微博 QQ收藏 人人网 Facebook Twitter

三种支持基于Linux的USB配置的不同方法

发布日期:2011-05-26

linux 配置ip linux网络配置 linux dns配置 linux ftp配置 linux apache 配置 linux 网卡配置 linux 查看配置 linux 配置文件 linux配置jdk linux 配置   小序

  通用串行总线(USB)是一种快速而机动地连接配件与谋略机变乱站的接口,其应用非常广泛。Linux中除了包括对USB主机控制器的驱动,还含有USB配置控制器,尤其是集成在StrongARM SA1110处理惩罚处罚器上的控制器的驱动。这些控制器驱动通过利用USB可使基于Linux的嵌入式体系与主机 (运行的可以是Linux,或不是)举行通讯。这里提供三种要领给运行Linux利用体系的嵌入式体系增长USB支持,可采取此中一种与USB主机展开通讯。

  第一种,最巨大的配置采取专门编写的内核模块阐发标准USB总线上通畅的错综巨大的高层协议;相应的USB主机定制驱动和应用步调来完成连接。第二种,有些基于Linux的配置把总线当作一种大抵的运行在主机上的点对点串行连接利用;主机应用步调采取主机利用体系提供的USB编程界面,而其外在表现则宛如是在通过一种典范的串行端口举行通讯。第三种,另有一些配置把USB看作一种以太网络,它们用主机作网关,把USB配置与办公LAN或 Internet相连接。通常的做法是利用专门的主机驱动实现它。

  最佳方案的选择取决于研发所需时间,以及针对细致嵌入式应用,要把USB接口作成什么样。以下对这三种要领如安在基于Linux的USB配置上的应用逐一举行形貌。本文是关于如安在基于Linux的照相机和PDA之类的USB配置上利用Linux的叙述,在此,USB是指由方形连接器而非扁平矩形连接器构成的USB配置。

  
内核模块

  把USB加到基于Linux的配置上的第一种要领是编写一个定制的Linux内核模块。这种要领通常恳求相应开辟主机利用体系(Windows、Linux以及别的OS)的驱动。

  借助定制内核模块在配置中的摆设,可以举行文件体系仿真等,使嵌入式应用将其USB主机当作长途存储配置对待。这一要领的另一埋伏用途是构成一种存储转发字符配置,从嵌入式应用步调中缓冲数据流,直到USB主机连接完成创建为止。

  敷衍基于StrongARM的Linux配置,其USB应用内核模块调用sa1100_usb_open(),对办理芯片的板上USB配置控制器外设的内核代码举行初始化。然后该模块调用sa1100_usb_get_descriptor_ptr()和 sa1100_usb_set_string_descriptor(),通过摆列进程对USB主机的给定USB形貌符举行设置。这些形貌符包括配置供货商及产品的数字标识符、正笔墨符串等主机可用来对配置举行辨认的信息。以致有一个序列号域,以便主机唯一地辨认配置或对USB上雷同配置的多个实例加以区分。

  内核模块必须在开始USB通讯前完成USB形貌符的创建,这是由于摆列进程由USB配置控制器驱动,一旦USB主机连上后会主动实行。齐备准备就绪后,USB配置模块便调用sa1100_usb_start(),报告内核承继来自主机的USB连接恳求。要是模块在USB主机连上前调用 sa1100_set_configured_ callback(),那么内核将会在摆列进程结束时调用所提供的回调函数。回调函数能很好地对配置完成连接状态举行可视化指示。

  要是USB通讯不再须要,那么配置的内核模块便调用sa1100_usb_stop(),然后是 sa1100_usb_close(),封闭SA1100的USB控制器。

  StrongARM USB控制器支持数据传输作业的bulk-in 和bulk-out。在从USB主机汲取数据包时,内核模块调用sa1100_usb_recv(),把数据缓冲区和回调函数地点转达给它。然后内核的底层USB配置控制代码对来自主机的bulk-out包举行检索,把内容放于缓冲区中,并调用回调函数。

  回调函数必须从汲取缓冲区提取数据并生存于别的位置大概把缓冲区空间加到一个行列步队中,为下一个数据包的汲取分派新的缓冲区。而后回调函数二次调用sa1100_usb_recv(),在须要时举行下一个数据包的汲取。进程与对USB主机的数据传输相雷同。在聚集起一帧的数据量后,内核模块将数据的地点、长度和回调地点转达给 sa1100_usb_send()。传输完成时,内核调用回调函数。

  主机端USB驱动的几个例子在主流的Linux版本以及 Linux内核文件布局分派的原始内核源中都有提供。用于Handspring Visor(drivers/usb/serial/visor.c)的模块是编写较为简便易懂的模块之一,作为USB主机端模块的模板 (drivers/usb/usb-skeleton.c)利用。

 
 高速串行

  敷衍大多数实际应用来说, 可以把USB总线当作一种高速串行端口思量。云云在某些典范的嵌入式配置和应用中对它举行原型仿照是存心义的。StrongARM处理惩罚处罚器的Linux内核提供现成的USB配置驱动专工于此,称作usb-char。

  在渴望与USB主机通讯时,Linux USB配置应用步调只是打开对其usb-char配置节点(字符型,最大10,最小240)的连接,然后开始读写数据即可。Read()和 write()利用将不绝返回错误值直到USB主机连上为止。一旦连接创建和摆列完成,便开始通讯,就像USB是一种点对点串行端口一样。

  由于这种USB数据转达要领非常直接且实用,因此usb-char配置得到高效利用。它还为别的USB通讯要领的实现提供了告急的参照基准。Usb-char的实际办法从usbc_open()结果开始,部分内容示于列表1中。

    static int usbc_open(struct inode *pInode, struct file *pFile)
    {
    int retval = 0;
    /* start usb core */
    sa1100_usb_open(_sb-char?;
    /* allocate memory for in-transit USB packets */
    tx_buf = (char*) kmalloc(TX_PACKET_SIZE, GFP_KERNEL | GFP_DMA);
    packet_buffer = (char*) kmalloc(RX_PACKET_SIZE, GFP_KERNEL | GFP_DMA);
    /* allocate memory for the receive buffer; the contents of this
    buffer are provided during read() */
    rx_ring.buf = (char*) kmalloc(RBUF_SIZE, GFP_KERNEL);
    /* set up USB descriptors */
    twiddle_descriptors();
    /* enable USB i/o */
    sa1100_usb_start();
    /* set up to receive a packet */
    kick_start_rx();
    return 0;

  twiddle_descriptors ()结果创建起配置的USB形貌符。在形貌符全部建起后,准备从USB主机摆列并汲取一个数据帧。Kick_start_rx()所需的代码大多数环境下只是一种对sa1100_usb_recv() 的调用以创建回调罢了。当USB主机发送数据包时,配置的内核通过回调调用rx_done_callback_packet_buffer()函数,把数据包的内容移入usb-char 配置点上由read()返回的FIFO行列步队。

  
主机

  敷衍运行Linux的USB主机,usb-char相应的USB主机模块称为usbserial模块。大多数Linux版本都包括Usbserial模块,只管通常不是主动装入。在USB与配置的连接创建之前,usbserial 由modprobe 或 insmod加载。

  一旦USB配置开始摆列,主机上的应用步调便用usbserial配置点(字符型,最大188,最小0以上)之一与配置举行通讯。这些节点通常定名为/dev/ttyUSBn。Usbserial模块在内核报文日记记录中报告它把哪个节点指定给USB配置利用:

  usbserial.c: 通用转换器删除;

  usbserial.c: 通用转换器当前连到ttyUSB0上。连接创建后,USB主机上的应用步调便通过读写指定的节点与USB配置举行通讯。

  Linux主机上usbserial模块的一种调换选择是一种称作libusb(libusb.sourceforge.net)的库。这种库利用低层内核体系调用举行USB数据传输,而不是通过usbserial模块,在某种程度上跨Linux内核版本创建和利用时更方便。Libusb库还提供大量有效的调试结果,这一点在对运行在USB链路上的巨大通讯协议举行除错时有资助。用libusb与采取usb-char的USB配置举行通讯时,Linux主机应用步调利用usb_open()函数创建与该配置的连接。然后应用步调利用usb_bulk_read()和usb_bulk_write()与配置互换数据。

 
 USB上的以太网

  另一种选择是把USB作为一种以太网络来对待。Linux具有在主机和配置端均可实现这种结果的模块。由于iPAQ硬件既没有可接入的串行端口也没有一种专用的网络接口,因此,iPAQ 的Linux内核专门采取这种通讯战略,在StrongARM的Linux内核中,usb-eth模块(arch/arm/mach- sa1100/usb-eth.c)对用USB作物理媒介的假造以太网配置举行仿真。一旦创建后,这一网络界面便被指定一个IP地点,不然作为通常的以太网硬件对待。一旦USB主机连上后,usb-eth模块便能使USB配置“看到” Internet(要是存在Internet的话),ping测别的IP地点,以致“批评辩论”DHCP, HTTP, NFS, telnet, 和e-mail。简言之,任安在实际的以太网界面上运行的应用将不折不扣地在usb-eth接口上得到实现,由于它们不克不及辨别出其正在利用的不是着实的以太网硬件。

  在Linux主机上,相应的Ethernet-over-USB内核模块称为usbnet。当usbnet模块得到摆设且配置的USB连接创建完成时,usbnet模块便针对主机端内核及用户应用创建一个与实际硬件酷似的假造以太网界面,主机端应用步调通过运行配置IP地点ping测,可以查抄USB配置的存在。要是ping测告成,配置便加上了。

 
 结语

  Linux不再只是USB主机利用,当今它也是USB配置的切合选择,Linux下的USB通讯好坏常机动和易用的。