LinuxUSBgadget设备驱动解析.docx
- 文档编号:8287379
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:32
- 大小:234.67KB
LinuxUSBgadget设备驱动解析.docx
《LinuxUSBgadget设备驱动解析.docx》由会员分享,可在线阅读,更多相关《LinuxUSBgadget设备驱动解析.docx(32页珍藏版)》请在冰豆网上搜索。
LinuxUSBgadget设备驱动解析
LinuxUSBgadget设备驱动解析
(1)“功效体验”
利用LinuxUSBgadget设备驱动可以实现一些比力有意思的功效,举两个例子:
1、一个嵌入式产物中的某个存储设备,或是一个存储设备的某个分区,可以作为一个U盘被PC设别,从而非常方便的完成文件交互,这个功效被遍及的应用于手机、数码相机等产物中。
2、一个嵌入式设备通过USB连接到你的PC后,在你的PC端会出现一个新的网络连接,在嵌入式设备上也会有一个网卡设备,你可以配置它们的IP地点,并进行网络通讯,俗称USBNET。
所有USB通讯的设备端都有usbdevice步伐,通常称它们为usb固件。
在一些功效简朴的设备里,用一些专用的可编程USB控制器就可以了。
而在一些运行了类似linux操纵系统的庞大的嵌入式系统中,要完成usbdevice步伐,就会要求你不但熟悉usbdevice控制器的操纵,还要熟悉操纵系统的驱动架构。
我想通过“功效体验”、“驱动调试”、“gadget驱动结构阐发”、“编写一个自己的gadget驱动”这4个方面解析linuxusbgadget设备驱动的编写要领。
一、linux模拟U盘功效的实现
在硬件情况为华清远见的fs2410平台,软件情况为linux-2.6.26的linux系统上,实现模拟U盘的功效。
向内核添加代码
#include
#include
#include
修改arch/arm/mach-s3c2410/mach-smdk2410.c
/*USBdevice上拉电阻处置惩罚*/
staticvoidsmdk2410_udc_pullup(enums3c2410_udc_cmd_ecmd)
{
u8*s3c2410_pullup_info[]={
"",
"Pull-upenable",
"Pull-updisable",
"UDCreset,incaseof"
};
printk("smdk2410_udc:
%s\\n",s3c2410_pullup_info[cmd]);
s3c2410_gpio_cfgpin(S3C2410_GPG9,S3C2410_GPG9_OUTP);
switch(cmd)
{
caseS3C2410_UDC_P_ENABLE:
s3c2410_gpio_setpin(S3C2410_GPG9,1);//setgpg9outputHIGH
break;
caseS3C2410_UDC_P_DISABLE:
s3c2410_gpio_setpin(S3C2410_GPG9,0);//setgpg9outputLOW
break;
caseS3C2410_UDC_P_RESET:
//FIXME!
!
!
break;
default:
break;
}
}
staticstructs3c2410_udc_mach_infosmdk2410_udc_cfg__initdata={
.udc_command=smdk2410_udc_pullup,
};
staticstructplatform_device*smdk2410_devices[]__initdata={
…,
&s3c_device_usbgadget,/*USBgadgetdevice设备登记*/
};
staticvoid__initsdmk2410_init(void)
{
u32upll_value;
set_s3c2410fb_info(&smdk2410_lcdcfg);
s3c24xx_udc_set_platdata(&smdk2410_udc_cfg);/*初始化*/
s3c_device_sdi.dev.platform_data=&smdk2410_mmc_cfg;
/*TurnoffsuspendonbothUSBports,andswitchthe
*selectableUSBporttoUSBdevicemode.*/
s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST|
S3C2410_MISCCR_USBSUSPND0|
S3C2410_MISCCR_USBSUSPND1,0x0);
/*设置USB时钟*/
upll_value=(
0x78< |(0x02< |(0x03< while(upll_value! =readl(S3C2410_UPLLCON)){ writel(upll_value,S3C2410_UPLLCON); udelay(20); } } 修改drivers/usb/gadget/ staticvoidstart_transfer(structfsg_dev*fsg,structusb_ep*ep, structusb_request*req,int*pbusy, enumfsg_buffer_state*state) { intrc; udelay(800); …… } 配置内核支持U盘模拟 <*>USBGadgetSupport---> USBPeripheralController(S3C2410USBDeviceController)---> S3C2410USBDeviceController [*]S3C2410udcdebugmessages 3、编译内核 #makezImage #makemodules 在目录drivers/usb/gadget下生成g_ 加载驱动,测试功效 利用前面的生成的内核,启动系统后,加载g_ #insmodg_ #insmodg_stall=0removable=1 0.03USB: usb_gadget_register_driver()\'g_\' 0.04USB: bindinggadgetdriver\'g_\' 0.05USB: s3c2410_set_selfpowered() g_gadget: StorageGadget,version: 20October2004 g_gadget: NumberofLUNs=1 g_gadget-lun0: ro=0,file: /dev/mtdblock3 0.06USB: udc_enablecalled smdk2410_udc: Pull-upenable 连接设备到windows,windows系统会自动设备到一个新的U盘参加。 格式化U盘,存入文件。 卸载U盘后,在目标板上执行如下操纵: #mkdir/mnt/gadget #mount-tvfat/dev/mtdblock2/mnt/gadget/ #ls 可以看到windows存入U盘的文件。 二、usbnet功效的实现 配置内核支持usbnet <*>USBGadgetSupport---> USBPeripheralController(S3C2410USBDeviceController)---> S3C2410USBDeviceController [*]S3C2410udcdebugmessages [*]RNDISsupport 2、编译内核 #makezImage #makemodules 在目录drivers/usb/gadget下生成g_ether.ko 3、加载驱动,测试功效 利用前面的生成的内核,启动系统后,加载g_ether.ko #insmodg_ether.ko #ifconfigusb0192.168.1.120 …… usb0Linkencap: EthernetHWaddr5E: C5: F6: D4: 2B: 91 inetaddr: 192.168.1.120Bcast: 192.168.1.255Mask: 255.255.255.0 UPBROADCASTRUNNINGMULTICASTMTU: 1500Metric: 1 RXpackets: 253errors: 0dropped: 0overruns: 0frame: 0 TXpackets: 43errors: 0dropped: 0overruns: 0carrier: 0 collisions: 0txqueuelen: 1000 RXbytes: 35277(34.4KiB)TXbytes: 10152(9.9KiB) 连接设备到windows,windows系统会提示安装驱动,凭据提示安装上RNDIS驱动。 这个驱动可以在网络上找到。 此时windows会新生成一个网络连接,配置它的ip地点等信息。 然后就可以和目标系统通过USB实现网络通讯了。 LinuxUSBgadget设备驱动解析 (2)---驱动调试 作者: 刘洪涛,华清远见嵌入式学院金牌讲师。 这一节主要把在实现“linux模拟U盘功效”历程中的一些调试历程记载下来,并加以解析。 一、配景知识 1、USBMassStorage类范例概述 USB组织在universalSerialBusMassStorageClassSpaceification1.1版本中界说了海量存储设备类(MassStorageClass)的范例,这个类范例包罗四个独立的子类范例,即: 1.USBMassStorageClassControl/Bulk/Interrupt(CBI)Transport 2.USBMassStorageClassBulk-OnlyTransport 3.USBMassStorageClassATACommandBlock 4.USBMassStorageClassUFICommandSpecification 前两个子范例界说了数据/命令/状态在USB上的传输要领。 Bulk-Only传输范例仅仅使用Bulk端点传送数据/命令/状态,CBI传输范例则使用Control/Bulk/Interrupt三种类型的端点进行数据/命令/状态传送。 后两个子范例则界说了存储介质的操纵命令。 ATA命令范例用于硬盘,UFI命令范例是针对USB移动存储。 MicrosoftWindows中提供对MassStorage协议的支持,因此USB移动设备只需要遵循MassStorage协议来组织数据和处置惩罚命令,即可实现与PC机互换数据。 而Flash的存储单位组织形式接纳FAT16文件系统,这样,就可以直接在Windows的浏览器中通过可移动磁盘来互换数据了,Windows卖力对FAT16文件系统的治理,USB设备不需要干涉FAT16文件系统操纵的具体细节。 USB(Host)唯一通过描述符了解设备的有关信息,凭据这些信息,创建起通信,在这些描述符中,划定了设备所使用的协议、端点情况等。 因此,正确地提供描述符,是USB设备正常事情的先决条件。 Linux-2.6.26内核中在利用USBgadget驱动实现模拟U盘时主要涉及到、s3c2410_udc.c等驱动文件(这些文件的具体结构,将在下一篇文章中描述)。 此时我们想先从这些代码中找到USB描述描述符,从中确定使用的存储类范例,从而确定协议。 确定通讯协议是我们调试的底子。 存储类范例是由接口描述符决定的。 接口描述符各项的界说义如下: 其中,bInterfaceClass、bInterfaceSubClass、bInterfaceProtocol可以判断出设备是否是存储类,以及属于哪种存储子类和存储介质的操纵命令。 在文件中, /*USBprotocolvalue=thetransportmethod*/ #defineUSB_PR_CBI0x00//Control/Bulk/Interrupt #defineUSB_PR_CB0x01//Control/Bulkw/ointerrupt #defineUSB_PR_BULK0x50//Bulk-only /*USBsubclassvalue=theprotocolencapsulation*/ #defineUSB_SC_RBC0x01//ReducedBlockCommands(flash) #defineUSB_SC_80200x02//SFF-8020i,MMC-2,ATAPI(CD-ROM) #defineUSB_SC_QIC0x03//QIC-157(tape) #defineUSB_SC_UFI0x04//UFI(floppy) #defineUSB_SC_80700x05//SFF-8070i(removable) #defineUSB_SC_SCSI0x06//TransparentSCSI 默认的情况是: mod_data={//Defaultvalues .transport_parm="BBB", .protocol_parm="SCSI", …… 默认的赋值如下: bInterfaceClass=08表现: 存储类 bInterfaceSubClass=0x06表现: 透明的SCSI指令 bInterfaceProtocol=0x50表现: bulk-only传输 2、Bulk-Only传输协议 下面看看Bulk-Only传输协议: (详细的范例请阅读《UniversalSerialBusMassStorageClassBulk-OnlyTransport》) 设备插入到USB后,USB即对设备进行搜索,并要求设备提供相应的描述符。 在USBHost得到上述描述符后,即完成了设备的配置,识别出为Bulk-Only的MassStorage设备,然后即进入Bulk-Only传输方法。 在此方法下,USB与设备间的所有数据均通过Bulk-In和Bulk-Out来进行传输,不再通过控制端点传输任何数据。 在这种传输方法下,有三种类型的数据在USB和设备之间传送,CBW、CSW和普通数据。 CBW(CommandBlockWrapper,即命令块包)是从USBHost发送到设备的命令,命令格式遵从接口中的bInterfaceSubClass所指定的命令块,这里为SCSI传输命令集。 USB设备需要将SCSI命令从CBW中提取出来,执行相应的命令,完成以后,向Host发出反应当前命令执行状态的CSW(CommandStatusWrapper),Host凭据CSW来决定是否继承发送下一个CBW或是数据。 Host要求USB设备执行的命令可能为发送数据,则此时需要将特定命据传送出去,完毕后发出CSW,以使Host进行下一步的操纵。 USB设备所执行的操纵可用下图描述: CBW的格式如下: dCBWSignature: CBW的标识,牢固值: 43425355h(littleendian)。 dCBWTag: 主机发送的一个命令块标识,设备需要原样作为dCSWTag(CSW中的一部门)再发送给Host;主要用于关联CSW到对应的CBW。 dCBWDataTransferLength: 本次CBW命令要求在命令与回应之间传输的字节数。 如果为0,则不传输数据。 bmCBWFlags: 反应数据传输的偏向,0表现来自Host,1表现发至Host; bCBWLUN: 对付有多个LUN逻辑单位的设备,用来选择具体目标。 如果没有多个LUN,则写0。 bCBWCBLength: 命令的长度,范畴在0~16. CBWCB: 传输的具体命令,切合bInterfaceSubClass.中界说的命令范例,此处是SCSI CSW命令格式如下: dCSWSignature: CSW的标识,牢固值: 53425355h(littleendian) dCSWTag: 设置这个标识和CBW中的dCBWTag一致,参照上面关于dCBWTag的解释 dCSWDataResidue: 还需要传送的数据,此数据凭据dCBWDataTransferLength-本次已经传送的数据得到 bCSWStatus: 指示命令的执行状态。 如果命令正确执行,bCSWStatus返回0即可。 3、SCSI指令集 Bulk-Only的CBW中的CBWCB中的内容即为如下格式的命令块描述符(CommandBlockDescriptor)。 SCSI-2有三种字长的命令,6字节、10字节和12字节,MicrosoftWindows情况下支持12字节长的命令。 OperationCode: 操纵代码,表现特定的命令。 高3位为GroupCode,共有8种组合, 即8个组,低5五位为CommandCode,可以有32种命令。 LogicolunitNumber: 为了兼容SCSI-1而设的,此处可以不必体贴。 Logicalblockaddress: 为高位在前,低位在后的逻辑块地点,即扇区地点。 第2位为高位,第3、4、5依次为低位。 Transferlength: 为需要从逻辑块地点处开始传输的扇区数(好比在Write命令中)。 Parameterlistlength: 为需要传输的数据长度(好比在ModeSense命令中); Allocationlength: 为初始步伐为返回数据所分派的最大字节数,此值可以为零,表现不需要传送数据。 SCSI指令集的DirectAccesss类型存储介质的传输命令有许多,MassStorage协议只用到了其中的一些。 更多的SCSI指令拜见: 指令代码指令名称说明 04hFormatUnit格式化存储单位 12hInquiry索取器件信息 1BhStart/Stopload/unload 55hModeselect允许Host对外部设备设置参数。 5AhModeSense向host传输参数 EhPrevent/AllowMediumRemoval写掩护 >28hRead(10)Host读存储介质中的二进制数据 A8hRead(12)同上,不外比力详细一点 25hReadCapacity要求设备返回当前容量 23hReadFormatCapacity查询当前容量及可用空间 03hRequestSense请求设备向主机返回执行结果,及状态数据 01hRexeroUnit返回零轨道 2BhSeek(10)为设备分派到特定地点 1DhSendDiagnostic执行固件复位并执行诊断 00hTestUnitReady请求设备陈诉是否处于Ready状态 2FhVerify在存储中验证数据 2AhWrite(10)从主机向介质写二进制数据 AAhWrite(12)同上,不外比力详细 2EhWriteandVerify写二进制数据并验证 对付差别的命令,其命令块描述符略有差别,其要求的返回内容也有所差别,凭据相应的文档,可以对每种请求作出适当的回应。 好比,下面是INQUIRY请求的命令块描述符和其返回内容的数据格式: 如: INQUIRY 命令描述符: 返回数据格式 Host会依次发出INQUIRY、ReadCapacity、UFIModeSense请求,如果上述请求的返回结果都正确,则Host会发出READ命令,读取文件系统0簇0扇区的MBR数据,进入文件系统识别阶段。 4、利用USBView视察结果 可通过USBView软件检察到USB设置阶段获取到的信息。 二、出现的主要问题 在调试历程中遇到了一个问题。 现象是: 在目标板加载完驱动后,即执行完: #insmodg_stall=0removable=1 后,接好USB线。 此时在windows端设备出有usbstorage设备参加,但出现不了盘符。 下面记载下调试历程。 三、调试历程 凭据范例,当完成SCSI指令会合Inquiry命令时,可以出现盘符。 所以可以通过bushound软件检察通讯历程,找出原因。 下面是利用bushound东西在出现问题时收罗到的数据。 DevPhaseDataInfoTimeCmd.Phase.Ofs ------------------------------------------------------------------- 26CTL80060001-00001200GETDESCRIPTR0us1.1.0 26DI12011001-00000010-2505a5a4-12030102........%.......4.8ms1.2.0 0301..1.2.16 26CTL80060002-00000900GETDESCRIPTR14us2.1.0 26DI09022000-010104c0-01........3.9ms2.2.0 26CTL80060002-00002000GETDESCRIPTR16us3.1.0 26DI09022000-010104c0-01090400-
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- LinuxUSBgadget 设备 驱动 解析