| ÂÛ̳ע²á| ¼ÓÈëÊÕ²Ø | ÉèΪÊ×Ò³| RSS
Google
Äúµ±Ç°µÄλÖãºÊ×Ò³ > LinuxƵµÀ > Linux¿ª·¢Çø > Èí¼þ¿ª·¢

Linux»·¾³ÏÂÈçºÎÉèÖÃUSBÇý¶¯³ÌÐò

ʱ¼ä£º2007-09-20 15:42:09  À´Ô´£º±±¾©ÖпƺìÆìÈí¼þ¼¼ÊõÓÐÏÞ¹«Ë¾  ×÷ÕߣºÁº¹ú¾ü

Ëæ×ÅÉú»îˮƽµÄÌá¸ß£¬ÈËÃǶÔUSBÉ豸µÄʹÓÃÒ²Ô½À´Ô½¶à£¬¼øÓÚLinuxÔÚÓ²¼þÅäÖÃÉÏÉв»ÄÜÈ«²¿¼´²å¼´Óã¬Òò´Ë¹ØÓÚLinuxÈçºÎÅäÖúÍʹÓ㬳ÉΪÀ§ÈÅÎÒÃǵÄÒ»´óÎÊÌâ¡£

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

ʲôÊÇUSB£¿

eq7LinuxÁªÃË

USBÊÇÓ¢ÎÄUniversal Serial BusµÄËõд£¬ÒâΪͨÓô®ÐÐ×ÜÏß¡£USB×î³õÊÇΪÁËÌæ´úÐí¶à²»Í¬µÄµÍËÙ×ÜÏߣ¨°üÀ¨²¢ÐС¢´®ÐкͼüÅÌÁ¬½Ó£©¶øÉè¼ÆµÄ£¬ËüÒÔµ¥Ò»ÀàÐ͵Ä×ÜÏßÁ¬½Ó¸÷ÖÖ²»Í¬µÄÀàÐ͵ÄÉ豸¡£USBµÄ·¢Õ¹ÒѾ­³¬Ô½ÁËÕâЩµÍËÙµÄÁ¬½Ó·½Ê½£¬ËüÏÖÔÚ¿ÉÒÔÖ§³Ö¼¸ºõËùÓпÉÒÔÁ¬½Óµ½PCÉϵÄÉ豸¡£×îеÄUSB¹æ·¶ÐÞ¶©ÁËÀíÂÛÉϸߴï480MbpsµÄ¸ßËÙÁ¬½Ó¡£LinuxÄÚºËÖ§³ÖÁ½ÖÖÖ÷ÒªÀàÐ͵ÄUSBÇý¶¯³ÌÐò£ºËÞÖ÷ϵͳÉϵÄÇý¶¯³ÌÐòºÍÉ豸ÉϵÄÇý¶¯³ÌÐò£¬´ÓËÞÖ÷µÄ¹ÛµãÀ´¿´£¨Ò»¸öÆÕͨµÄËÞÖ÷Ò²¾ÍÊÇÒ»¸öPC»ú£©£¬ËÞÖ÷ϵͳµÄUSBÉ豸Çý¶¯³ÌÐò¿ØÖƲåÈëÆäÖеÄUSBÉ豸£¬¶øUSBÉ豸µÄÇý¶¯³ÌÐò¿ØÖƸÃÉ豸ÈçºÎ×÷Ϊһ¸öUSBÉ豸ºÍÖ÷»úͨÐÅ¡£

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

USBµÄ¾ßÌå¹¹³É

eq7LinuxÁªÃË

ÔÚ¶¯ÊÖдUSBÇý¶¯³ÌÐòÕâǰ£¬ÈÃÎÒÃÇÏÈ¿´¿´Ð´µÄUSBÇý¶¯³ÌÐòÔÚÄÚºËÖеĽṹ£¬ÈçÏÂͼ£º

eq7LinuxÁªÃË

eq7LinuxÁªÃË

eq7LinuxÁªÃË

253ff109d13dd3be33ab484f4bd7f53a.gifeq7LinuxÁªÃË

eq7LinuxÁªÃË

USBÇý¶¯³ÌÐò´æÔÚÓÚ²»Í¬µÄÄÚºË×ÓϵͳºÍUSBÓ²¼þ¿ØÖÆÆ÷Ö®¼ä£¬USBºËÐÄΪUSBÇý¶¯³ÌÐòÌṩÁËÒ»¸öÓÃÓÚ·ÃÎʺͿØÖÆUSBÓ²¼þµÄ½Ó¿Ú£¬¶ø²»±Ø¿¼ÂÇϵͳµ±Ç°´æÔڵĸ÷ÖÖ²»Í¬ÀàÐ͵ÄUSBÓ²¼þ¿ØÖÆÆ÷¡£USBÊÇÒ»¸ö·Ç³£¸´ÔÓµÄÉ豸£¬linuxÄÚºËΪÎÒÃÇÌṩÁËÒ»¸ö³ÆÎªUSBµÄºËÐĵÄ×ÓϵͳÀ´´¦Àí´ó²¿·ÖµÄ¸´ÔÓÐÔ£¬USBÉ豸°üÀ¨ÅäÖÃ(configuration)¡¢½Ó¿Ú£¨interface£©ºÍ¶Ëµã(endpoint)£¬USBÉ豸°ó¶¨µ½½Ó¿ÚÉÏ£¬¶ø²»ÊÇÕû¸öUSBÉ豸¡£ÈçÏÂͼËùʾ£º

eq7LinuxÁªÃË

eq7LinuxÁªÃË

eq7LinuxÁªÃË

eq7LinuxÁªÃË

2c9606c4cc81f652f6018a4c561da2e2.gifeq7LinuxÁªÃË

eq7LinuxÁªÃË

USBͨÐÅ×î»ù±¾µÄÐÎʽÊÇͨ¹ý¶Ëµã£¨USB¶Ëµã·ÖÖжϡ¢ÅúÁ¿¡¢µÈʱ¡¢¿ØÖÆËÄÖÖ£¬Ã¿ÖÖÓÃ;²»Í¬£©£¬USB¶ËµãÖ»ÄÜÍùÒ»¸ö·½Ïò´«ËÍÊý¾Ý£¬´ÓÖ÷»úµ½É豸»òÕß´ÓÉ豸µ½Ö÷»ú£¬¶Ëµã¿ÉÒÔ¿´×÷Êǵ¥ÏòµÄ¹ÜµÀ£¨pipe£©¡£ËùÒÔÎÒÃÇ¿ÉÒÔÕâÑùÈÏΪ£ºÉ豸ͨ³£¾ßÓÐÒ»¸ö»òÕ߸ü¶àµÄÅäÖã¬ÅäÖþ­³£¾ßÓÐÒ»¸ö»òÕ߸ü¶àµÄ½Ó¿Ú£¬½Ó¿Úͨ³£¾ßÓÐÒ»¸ö»òÕ߸ü¶àµÄÉèÖ㬽ӿÚûÓлò¾ßÓÐÒ»¸öÒÔÉϵĶ˵㡣Çý¶¯³ÌÐò°ÑÇý¶¯³ÌÐò¶ÔÏó×¢²áµ½USB×ÓϵͳÖУ¬ÉÔºóÔÙʹÓÃÖÆÔìÉ̺ÍÉ豸±êʶÀ´ÅжÏÊÇ·ñÒѾ­°²×°ÁËÓ²¼þ¡£USBºËÐÄʹÓÃÒ»¸öÁÐ±í£¨ÊÇÒ»¸ö°üº¬ÖÆÔìÉÌIDºÍÉ豸ºÅIDµÄÒ»¸ö½á¹¹Ì壩À´Åж϶ÔÓÚÒ»¸öÉ豸¸ÃʹÓÃÄÄÒ»¸öÇý¶¯³ÌÐò£¬ÈȲ岦½Å±¾Ê¹ÓÃËüÀ´È·¶¨µ±Ò»¸öÌØ¶¨µÄÉ豸²åÈ뵽ϵͳʱ¸Ã×Ô¶¯×°ÔØÄÄÒ»¸öÇý¶¯³ÌÐò¡£

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

ÉÏÃæÎÒÃǼòҪ˵Ã÷ÁËÇý¶¯³ÌÐòµÄ»ù±¾ÀíÂÛ£¬ÔÚдһ¸öÉ豸Çý¶¯³ÌÐò֮ǰ£¬ÎÒÃÇ»¹ÒªÁ˽âÒÔÏÂÁ½¸ö¸ÅÄģ¿éºÍÉ豸Îļþ¡£

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

Ä£¿é£ºÊÇÔÚÄں˿ռäÔËÐеijÌÐò£¬Êµ¼ÊÉÏÊÇÒ»ÖÖÄ¿±ê¶ÔÏóÎļþ£¬Ã»ÓÐÁ´½Ó£¬²»ÄܶÀÁ¢ÔËÐУ¬µ«ÊÇ¿ÉÒÔ×°ÔØµ½ÏµÍ³ÖÐ×÷ΪÄں˵ÄÒ»²¿·ÖÔËÐУ¬´Ó¶ø¿ÉÒÔ¶¯Ì¬À©³äÄں˵ŦÄÜ¡£Ä£¿é×îÖ÷ÒªµÄÓô¦¾ÍÊÇÓÃÀ´ÊµÏÖÉ豸Çý¶¯³ÌÐò¡£Linux϶ÔÓÚÒ»¸öÓ²¼þµÄÇý¶¯£¬¿ÉÒÔÓÐÁ½ÖÖ·½Ê½£ºÖ±½Ó¼ÓÔØµ½Äں˴úÂëÖУ¬Æô¶¯ÄÚºËʱ¾Í»áÇý¶¯´ËÓ²¼þÉ豸¡£ÁíÒ»ÖÖ¾ÍÊÇÒÔÄ£¿é·½Ê½£¬±àÒëÉú³ÉÒ»¸ö.koÎļþ(ÔÚ2.4ÒÔÏÂÄÚºËÖÐÊÇÓÃ.o×÷Ä£¿éÎļþ£¬ÎÒÃÇÒÔ2.6µÄÄÚºËΪ׼£¬ÒÔÏÂͬ)¡£µ±Ó¦ÓóÌÐòÐèҪʱÔÙ¼ÓÔØµ½Äں˿ռäÔËÐС£ËùÒÔÎÒÃÇËù˵µÄÒ»¸öÓ²¼þµÄÇý¶¯³ÌÐò£¬Í¨³£Ö¸µÄ¾ÍÊÇÒ»¸öÇý¶¯Ä£¿é¡£

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

É豸Îļþ£º¶ÔÓÚÒ»¸öÉ豸£¬Ëü¿ÉÒÔÔÚ/devÏÂÃæ´æÔÚÒ»¸ö¶ÔÓ¦µÄÂß¼­É豸½Úµã£¬Õâ¸ö½ÚµãÒÔÎļþµÄÐÎʽ´æÔÚ£¬µ«Ëü²»ÊÇÆÕͨÒâÒåÉϵÄÎļþ£¬ËüÊÇÉ豸Îļþ£¬¸üÈ·ÇеÄ˵£¬ËüÊÇÉ豸½Úµã¡£Õâ¸ö½ÚµãÊÇͨ¹ýmknodÃüÁÁ¢µÄ£¬ÆäÖÐÖ¸¶¨ÁËÖ÷É豸ºÅºÍ´ÎÉ豸ºÅ¡£Ö÷É豸ºÅ±íÃ÷ÁËijһÀàÉ豸£¬Ò»°ã¶ÔÓ¦×ÅÈ·¶¨µÄÇý¶¯³ÌÐò£»´ÎÉ豸ºÅÒ»°ãÊÇÇø·Ö²»Í¬ÊôÐÔ£¬ÀýÈ粻ͬµÄʹÓ÷½·¨£¬²»Í¬µÄλÖ㬲»Í¬µÄ²Ù×÷¡£Õâ¸öÉ豸ºÅÊÇ´Ó/proc/devicesÎļþÖлñµÃµÄ£¬ËùÒÔÒ»°ãÊÇÏÈÓÐÇý¶¯³ÌÐòÔÚÄÚºËÖУ¬²ÅÓÐÉ豸½ÚµãÔÚĿ¼ÖС£Õâ¸öÉ豸ºÅ£¨ÌØÖ¸Ö÷É豸ºÅ£©µÄÖ÷Òª×÷Ó㬾ÍÊÇÉùÃ÷É豸ËùʹÓõÄÇý¶¯³ÌÐò¡£Çý¶¯³ÌÐòºÍÉ豸ºÅÊÇÒ»Ò»¶ÔÓ¦µÄ£¬µ±Äã´ò¿ªÒ»¸öÉ豸Îļþʱ£¬²Ù×÷ϵͳ¾ÍÒѾ­ÖªµÀÕâ¸öÉ豸Ëù¶ÔÓ¦µÄÇý¶¯³ÌÐò¡£¶ÔÓÚÒ»¸öÓ²¼þ£¬LinuxÊÇÕâÑùÀ´½øÐÐÇý¶¯µÄ£ºÊ×ÏÈ£¬ÎÒÃDZØÐëÌṩһ¸ö.koµÄÇý¶¯Ä£¿éÎļþ¡£ÎÒÃÇҪʹÓÃÕâ¸öÇý¶¯³ÌÐò£¬Ê×ÏÈÒª¼ÓÔØËü£¬ÎÒÃÇ¿ÉÒÔÓÃinsmod xxx.ko£¬ÕâÑùÇý¶¯¾Í»á¸ù¾Ý×Ô¼ºµÄÀàÐÍ£¨×Ö·ûÉ豸ÀàÐÍ»ò¿éÉ豸ÀàÐÍ£¬ÀýÈçÊó±ê¾ÍÊÇ×Ö·ûÉ豸¶øÓ²Å̾ÍÊÇ¿éÉ豸£©Ïòϵͳע²á£¬×¢²á³É¹¦ÏµÍ³»á·´À¡Ò»¸öÖ÷É豸ºÅ£¬Õâ¸öÖ÷É豸ºÅ¾ÍÊÇϵͳ¶ÔËüµÄΨһ±êʶ¡£Çý¶¯¾ÍÊǸù¾Ý´ËÖ÷É豸ºÅÀ´´´½¨Ò»¸öÒ»°ã·ÅÖÃÔÚ/devĿ¼ÏµÄÉ豸Îļþ¡£ÔÚÎÒÃÇÒª·ÃÎÊ´ËÓ²¼þʱ£¬¾Í¿ÉÒÔ¶ÔÉ豸Îļþͨ¹ýopen¡¢read¡¢write¡¢closeµÈÃüÁî½øÐС£¶øÇý¶¯¾Í»á½ÓÊÕµ½ÏàÓ¦µÄread¡¢write²Ù×÷¶ø¸ù¾Ý×Ô¼ºµÄÄ£¿éÖеÄÏàÓ¦º¯Êý½øÐвÙ×÷ÁË¡£

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

USBÇý¶¯³ÌÐòÈçºÎÓ¦ÓÃ

eq7LinuxÁªÃË

Á˽âÁËÉÏÊöÀíÂÛºó£¬ÎÒÃǾͿÉÒÔ¶¯ÊÖдÇý¶¯³ÌÐò£¬Èç¹ûÄã»ù±¾¹¦ºÃ£¬¶øÇÒд¹ýlinuxϵÄÓ²¼þÇý¶¯£¬USBµÄÓ²¼þÇý¶¯ºÍpci_driverºÜÀàËÆ£¬ÄÇôдUSBµÄÇý¶¯¾Í±È½Ï¼òµ¥ÁË£¬Èç¹ûÄãÖ»ÊÇ´óÌåÁ˽âÁËlinuxµÄÓ²¼þÇý¶¯£¬ÄÇÒ²²»Òª½ô£¬ÒòΪÔÚlinuxµÄÄÚºËÔ´ÂëÖÐÓÐÒ»¸ö¿ò¼Ü³ÌÐò¿ÉÒÔÄÃÀ´½èÓÃһϣ¬Õâ¸ö¿ò¼Ü³ÌÐòÔÚ/usr/src/~£¨ÄãµÄÄں˰汾£¬ÒÔÏÂͬ£©/drivers/usbÏ£¬ÎļþÃûΪusb-skeleton.c¡£Ð´Ò»¸öUSBµÄÇý¶¯³ÌÐò×î»ù±¾µÄÒª×öËļþÊ£ºÇý¶¯³ÌÐòÒªÖ§³ÖµÄÉ豸¡¢×¢²áUSBÇý¶¯³ÌÐò¡¢Ì½²âºÍ¶Ï¿ª¡¢Ìá½»ºÍ¿ØÖÆurb£¨USBÇëÇó¿é£©£¨µ±È»Ò²¿ÉÒÔ²»ÓÃurbÀ´´«ÊäÊý¾Ý£¬ÏÂÎÄÎÒÃÇ»á˵µ½£©¡£

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

Çý¶¯³ÌÐòÖ§³ÖµÄÉ豸£ºÓÐÒ»¸ö½á¹¹Ìåstruct usb_device_id£¬Õâ¸ö½á¹¹ÌåÌṩÁËÒ»Áв»Í¬ÀàÐ͵ĸÃÇý¶¯³ÌÐòÖ§³ÖµÄUSBÉ豸£¬¶ÔÓÚÒ»¸öÖ»¿ØÖÆÒ»¸öÌØ¶¨µÄUSBÉ豸µÄÇý¶¯³ÌÐòÀ´Ëµ£¬struct usb_device_id±í±»¶¨ÒåΪ£º

eq7LinuxÁªÃË

/* Çý¶¯³ÌÐòÖ§³ÖµÄÉ豸Áбí */

eq7LinuxÁªÃË

static struct usb_device_id skel_table [] = {

eq7LinuxÁªÃË

       { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },

eq7LinuxÁªÃË

       { }                               /* ÖÕÖ¹Èë¿Ú */

eq7LinuxÁªÃË

};

eq7LinuxÁªÃË

MODULE_DEVICE_TABLE (usb, skel_table);

eq7LinuxÁªÃË

¶ÔÓÚPCÇý¶¯³ÌÐò£¬MODULE_DEVICE_TABLEÊDZØÐèµÄ£¬¶øÇÒusb±ØÐèΪ¸ÃºêµÄµÚÒ»¸öÖµ£¬¶øUSB_SKEL_VENDOR_IDºÍUSB_SKEL_PRODUCT_ID¾ÍÊÇÕâ¸öÌØÊâÉ豸µÄÖÆÔìÉ̺ͲúÆ·µÄIDÁË£¬ÎÒÃÇÔÚ³ÌÐòÖаѶ¨ÒåµÄÖµ¸ÄΪÎÒÃÇÕâ¿îUSBµÄ£¬È磺

eq7LinuxÁªÃË

/* ¶¨ÒåÖÆÔìÉ̺ͲúÆ·µÄIDºÅ */

eq7LinuxÁªÃË

#define USB_SKEL_VENDOR_ID       0x1234

eq7LinuxÁªÃË

#define USB_SKEL_PRODUCT_ID     0x2345

eq7LinuxÁªÃË

ÕâÁ½¸öÖµ¿ÉÒÔͨ¹ýÃüÁîlsusb£¬µ±È»ÄãµÃÏȰÑUSBÉ豸ÏȲ嵽Ö÷»úÉÏÁË¡£»òÕ߲鿴³§É̵ÄUSBÉ豸µÄÊÖ²áÒ²Äܵõ½£¬ÔÚÎÒ»úÆ÷ÉÏÔËÐÐlsusbÊÇÕâÑùµÄ½á¹û£º

eq7LinuxÁªÃË

Bus 004 Device 001: ID 0000:0000 

eq7LinuxÁªÃË

Bus 003 Device 002: ID 1234:2345  Abc  Corp.

eq7LinuxÁªÃË

Bus 002 Device 001: ID 0000:0000 

eq7LinuxÁªÃË

Bus 001 Device 001: ID 0000:0000

eq7LinuxÁªÃË

µÃµ½ÕâÁ½¸öÖµºó°ÑËü¶¨Òåµ½³ÌÐòÀï¾Í¿ÉÒÔÁË¡£

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

×¢²áUSBÇý¶¯³ÌÐò£ºËùÓеÄUSBÇý¶¯³ÌÐò¶¼±ØÐë´´½¨µÄ½á¹¹ÌåÊÇstruct usb_driver¡£Õâ¸ö½á¹¹Ì屨ÐëÓÉUSBÇý¶¯³ÌÐòÀ´Ìîд£¬°üÀ¨Ðí¶à»Øµ÷º¯ÊýºÍ±äÁ¿£¬ËüÃÇÏòUSBºËÐÄ´úÂëÃèÊöUSBÇý¶¯³ÌÐò¡£´´½¨Ò»¸öÓÐЧµÄstruct usb_driver½á¹¹Ì壬ֻÐëÒª³õʼ»¯Îå¸ö×ֶξͿÉÒÔÁË£¬ÔÚ¿ò¼Ü³ÌÐòÖÐÊÇÕâÑùµÄ£º

eq7LinuxÁªÃË

static struct usb_driver skel_driver = {

eq7LinuxÁªÃË

       .owner = THIS_MODULE,

eq7LinuxÁªÃË

       .name =          "skeleton",

eq7LinuxÁªÃË

       .probe =  skel_probe,

eq7LinuxÁªÃË

       .disconnect =  skel_disconnect,

eq7LinuxÁªÃË

       .id_table =      skel_table,

eq7LinuxÁªÃË

};

eq7LinuxÁªÃË

struct module *owner £ºÖ¸Ïò¸ÃÇý¶¯³ÌÐòµÄÄ£¿éËùÓÐÕßµÄÅúÕë¡£USBºËÐÄʹÓÃËüÀ´ÕýÈ·µØ¶Ô¸ÃUSBÇý¶¯³ÌÐò½øÐÐÒýÓüÆÊý£¬Ê¹Ëü²»»áÔÚ²»ºÏÊʵÄʱ¿Ì±»Ð¶Ôصô£¬Õâ¸ö±äÁ¿Ó¦¸Ã±»ÉèÖÃΪTHIS_MODULEºê¡£

eq7LinuxÁªÃË

const char *name£ºÖ¸ÏòÇý¶¯³ÌÐòÃû×ÖµÄÖ¸Õ룬ÔÚÄں˵ÄËùÓÐUSBÇý¶¯³ÌÐòÖÐËü±ØÐëÊÇΨһµÄ£¬Í¨³£±»ÉèÖÃΪºÍÇý¶¯³ÌÐòÄ£¿éÃûÏàͬµÄÃû×Ö¡£

eq7LinuxÁªÃË

int (*probe) (struct usb_interface *intf,const struct usb_device_id *id)£ºÕâ¸öÊÇÖ¸ÏòUSBÇý¶¯³ÌÐòÖеÄ̽²âº¯ÊýµÄÖ¸Õë¡£µ±USBºËÐÄÈÏΪËüÓÐÒ»¸ö½Ó¿Ú£¨usb_interface£©¿ÉÒÔÓɸÃÇý¶¯³ÌÐò´¦Àíʱ£¬Õâ¸öº¯Êý±»µ÷Óá£

eq7LinuxÁªÃË

void (disconnect)(struct usb_interface *intf)£ºÖ¸ÏòUSBÇý¶¯³ÌÐòÖеĶϿªº¯ÊýµÄÖ¸Õ룬µ±Ò»¸öUSB½Ó¿Ú£¨usb_interface£©±»´ÓϵͳÖÐÒÆ³ý»òÕßÇý¶¯³ÌÐòÕýÔÚ´ÓUSBºËÐÄÖÐÐ¶ÔØÊ±£¬USBºËÐĽ«µ÷ÓÃÕâ¸öº¯Êý¡£

eq7LinuxÁªÃË

const struct usb_device_id *id_table£ºÖ¸ÏòIDÉ豸±íµÄÖ¸Õ룬Õâ¸ö±í°üº¬ÁËÒ»ÁиÃÇý¶¯³ÌÐò¿ÉÒÔÖ§³ÖµÄUSBÉ豸£¬Èç¹ûûÓÐÉèÖÃÕâ¸ö±äÁ¿£¬USBÇý¶¯³ÌÐòÖеÄ̽²â»Øµ÷º¯Êý¾Í²»»á±»µ÷Óá£

eq7LinuxÁªÃË

ÔÚÕâ¸ö½á¹¹ÌåÖл¹ÓÐÆäËüµÄ¼¸¸ö»Øµ÷º¯Êý²»ÊǺܳ£Óã¬ÕâÀï¾Í²»Ò»Ò»ËµÃ÷ÁË¡£ÒÔstruct usb_driver Ö¸ÕëΪ²ÎÊýµÄusb_register_driverº¯Êýµ÷ÓðÑstruct usb_driver×¢²áµ½USBºËÐÄ¡£Ò»°ãÊÇÔÚUSBÇý¶¯³ÌÐòµÄÄ£¿é³õʼ»¯´úÂëÖÐÍê³ÉÕâ¸ö¹¤×÷µÄ£º

eq7LinuxÁªÃË

static int __init usb_skel_init(void)

eq7LinuxÁªÃË

{

eq7LinuxÁªÃË

       int result;

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

       /* Çý¶¯³ÌÐò×¢²áµ½USB×ÓϵͳÖÐ*/

eq7LinuxÁªÃË

       result = usb_register(&skel_driver);

eq7LinuxÁªÃË

       if (result)

eq7LinuxÁªÃË

              err("usb_register failed. Error number %d", result);

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

       return result;

eq7LinuxÁªÃË

}

eq7LinuxÁªÃË

µ±USBÇý¶¯³ÌÐò½«Òª±»Ð¶¿ªÊ±£¬ÐèÒª°Ñstruct usb_driver´ÓÄÚºËÖÐ×¢Ïú¡£Í¨¹ýµ÷ÓÃusb_deregister_driverÀ´Íê³ÉÕâ¸ö¹¤×÷£¬µ±µ÷Ó÷¢Éúʱ£¬µ±Ç°°ó¶¨µ½¸ÃÇý¶¯³ÌÐòÉϵÄÈκÎUSB½Ó¿Ú¶¼±»¶Ï¿ª£¬¶Ï¿ªº¯Êý½«±»µ÷Óãº

eq7LinuxÁªÃË

static void __exit usb_skel_exit(void)

eq7LinuxÁªÃË

{

eq7LinuxÁªÃË

       /* ´Ó×ÓϵͳעÏúÇý¶¯³ÌÐò */

eq7LinuxÁªÃË

       usb_deregister(&skel_driver);

eq7LinuxÁªÃË

}

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

̽²âºÍ¶Ï¿ª£ºµ±Ò»¸öÉ豸±»°²×°¶øUSBºËÐÄÈÏΪ¸ÃÇý¶¯³ÌÐòÓ¦¸Ã´¦Àíʱ£¬Ì½²âº¯Êý±»µ÷Óã¬Ì½²âº¯Êý¼ì²é´«µÝ¸øËüµÄÉ豸ÐÅÏ¢£¬È·¶¨Çý¶¯³ÌÐòÊÇ·ñÕæµÄÊʺϸÃÉ豸¡£µ±Çý¶¯³ÌÐòÒòΪijÖÖÔ­Òò²»Ó¦¸Ã¿ØÖÆÉ豸ʱ£¬¶Ï¿ªº¯Êý±»µ÷Óã¬Ëü¿ÉÒÔ×öһЩÇåÀí¹¤×÷¡£Ì½²â»Øµ÷º¯ÊýÖУ¬USBÇý¶¯³ÌÐò³õʼ»¯ÈκοÉÄÜÓÃÓÚ¿ØÖÆUSBÉ豸µÄ¾Ö²¿½á¹¹Ì壬Ëü»¹°ÑËùÐèµÄÈκÎÉ豸Ïà¹ØÐÅÏ¢±£´æµ½Ò»¸ö¾Ö²¿½á¹¹ÌåÖУ¬ÏÂÃæÊÇ̽²âº¯ÊýµÄ²¿·ÖÔ´Â룬ÎÒÃǼÓÒÔ·ÖÎö¡£

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

       /* ÉèÖö˵ãÐÅÏ¢ */

eq7LinuxÁªÃË

       /* ֻʹÓõÚÒ»¸öÅúÁ¿INºÍÅúÁ¿OUT¶Ëµã */

eq7LinuxÁªÃË

       iface_desc = interface->cur_altsetting;

eq7LinuxÁªÃË

       for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {

eq7LinuxÁªÃË

              endpoint = &iface_desc->endpoint[i].desc;

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

              if (!dev->bulk_in_endpointAddr &&

eq7LinuxÁªÃË

                  (endpoint->bEndpointAddress & USB_DIR_IN) &&

eq7LinuxÁªÃË

                  ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)

eq7LinuxÁªÃË

                                   == USB_ENDPOINT_XFER_BULK)) {

eq7LinuxÁªÃË

                     /* ÕÒµ½Ò»¸öÅúÁ¿IN¶Ëµã */

eq7LinuxÁªÃË

                     buffer_size = endpoint->wMaxPacketSize;

eq7LinuxÁªÃË

                     dev->bulk_in_size = buffer_size;

eq7LinuxÁªÃË

                     dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;

eq7LinuxÁªÃË

                     dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);

eq7LinuxÁªÃË

                     if (!dev->bulk_in_buffer) {

eq7LinuxÁªÃË

                            err("Could not allocate bulk_in_buffer");

eq7LinuxÁªÃË

                            goto error;

eq7LinuxÁªÃË

                     }

eq7LinuxÁªÃË

              }

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

              if (!dev->bulk_out_endpointAddr &&

eq7LinuxÁªÃË

                  !(endpoint->bEndpointAddress & USB_DIR_IN) &&

eq7LinuxÁªÃË

                  ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)

eq7LinuxÁªÃË

                                   == USB_ENDPOINT_XFER_BULK)) {

eq7LinuxÁªÃË

                     /* ÕÒµ½Ò»¸öÅúÁ¿OUT¶Ëµã */

eq7LinuxÁªÃË

                     dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;

eq7LinuxÁªÃË

              }

eq7LinuxÁªÃË

       }

eq7LinuxÁªÃË

       if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {

eq7LinuxÁªÃË

              err("Could not find both bulk-in and bulk-out endpoints");

eq7LinuxÁªÃË

              goto error;

eq7LinuxÁªÃË

       }

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

ÔÚ̽²âº¯ÊýÀÕâ¸öÑ­»·Ê×ÏÈ·ÃÎʸýӿÚÖдæÔÚµÄÿһ¸ö¶Ëµã£¬¸ø¸Ã¶ËµãÒ»¸ö¾Ö²¿Ö¸ÕëÒÔ±ãÒÔºó·ÃÎÊ£º

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {

eq7LinuxÁªÃË

              endpoint = &iface_desc->endpoint[i].desc;

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

ÔÚÒ»ÂÖ̽²â¹ýºó£¬ÎÒÃǾÍÓÐÁËÒ»¸ö¶Ëµã£¬ÔÚ»¹Ã»Óз¢ÏÖÅúÁ¿INÀàÐ͵Ķ˵ãʱ£¬Ì½²â¸Ã¶Ëµã·½ÏòÊÇ·ñΪIN£¬Õâ¿ÉÒÔͨ¹ý¼ì²éUSB_DIR_INÊÇ·ñ°üº¬ÔÚbEndpointAddress¶Ëµã±äÁ¿ÓÐÈ·¶¨£¬Èç¹ûÊǵϰ£¬ÎÒÃÇÔÚ̽²â¸Ã¶ËµãÀàÐÍÊÇ·ñΪÅúÁ¿£¬ÏÈÓÃUSB_ENDPOINT_XFERTYPE_MASKλÑÚÀ´È¡bmAttributes±äÁ¿µÄÖµ£¬È»ºó̽²âËüÊÇ·ñºÍUSB_ENDPOINT_XFER_BULKֵƥÅ䣺

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

              if (!dev->bulk_out_endpointAddr &&

eq7LinuxÁªÃË

                  !(endpoint->bEndpointAddress & USB_DIR_IN) &&

eq7LinuxÁªÃË

                  ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)

eq7LinuxÁªÃË

                                   == USB_ENDPOINT_XFER_BULK))

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

Èç¹ûËùÓÐÕâЩ̽²â¶¼Í¨¹ýÁË£¬Çý¶¯³ÌÐò¾ÍÖªµÀËüÒѾ­·¢ÏÖÁËÕýÈ·µÄ¶ËµãÀàÐÍ£¬¿ÉÒ԰Ѹö˵ãµÄÏà¹ØÐÅÏ¢±£´æµ½Ò»¸ö¾Ö²¿½á¹¹ÌåÖÐÒÔ±ãÉÔºóÓÃËüÀ´ºÍ¶Ëµã½øÐÐͨÐÅ£º

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

                     /* ÕÒµ½Ò»¸öÅúÁ¿INÀàÐ͵Ķ˵ã */

eq7LinuxÁªÃË

                     buffer_size = endpoint->wMaxPacketSize;

eq7LinuxÁªÃË

                     dev->bulk_in_size = buffer_size;

eq7LinuxÁªÃË

                     dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;

eq7LinuxÁªÃË

                     dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);

eq7LinuxÁªÃË

                     if (!dev->bulk_in_buffer) {

eq7LinuxÁªÃË

                            err("Could not allocate bulk_in_buffer");

eq7LinuxÁªÃË

                            goto error;

eq7LinuxÁªÃË

                     }

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

ÒòΪUSBÇý¶¯³ÌÐòÒªÔÚÉ豸µÄÉúÃüÖÜÆÚµÄÉÔºóʱ¼ä»ñÈ¡ºÍ½Ó¿ÚÏà¹ØÁªµÄ¾Ö²¿Êý¾Ý½á¹¹Ì壬ËùÒÔµ÷ÓÃÁËusb_set_intfdataº¯Êý£¬°ÑËü±£´æµ½struct usb_interface½á¹¹ÌåÖÐÒÔ±ãºóÃæµÄ·ÃÎÊ

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

       /* °ÑÊý¾ÝÖ¸Õë±£´æµ½Õâ¸ö½Ó¿ÚÉ豸ÖÐ */

eq7LinuxÁªÃË

       usb_set_intfdata(interface, dev);

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

ÎÒÃÇÒÔºóµ÷ÓÃusb_set_intfdataº¯ÊýÀ´»ñÈ¡Êý¾Ý¡£µ±ÕâÒ»Çж¼Íê³Éºó£¬USBÇý¶¯³ÌÐò±ØÐëÔÚ̽²âº¯ÊýÖе÷ÓÃusb_register_devº¯ÊýÀ´°Ñ¸ÃÉ豸ע²áµ½USBºËÐÄÀ

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

       /* ×¢²áÉ豸µ½USBºËÐÄ */

eq7LinuxÁªÃË

       retval = usb_register_dev(interface, &skel_class);

eq7LinuxÁªÃË

       if (retval) {

eq7LinuxÁªÃË

              /* ÓÐЩÇé¿öÏÂÊDz»ÔÊÐí×¢²áÇý¶¯³ÌÐòµÄ */

eq7LinuxÁªÃË

              err("Not able to get a minor for this device.");

eq7LinuxÁªÃË

              usb_set_intfdata(interface, NULL);

eq7LinuxÁªÃË

              goto error;

eq7LinuxÁªÃË

       }

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

µ±Ò»¸öUSBÉ豸±»¶Ï¿ªÊ±£¬ºÍ¸ÃÉ豸Ïà¹ØÁªµÄËùÓÐ×ÊÔ´¶¼Ó¦¸Ã±»¾¡¿ÉÄܵÄÇåÀíµô£¬ÔÚ´Ëʱ£¬Èç¹ûÒÑÔÚÔÚ̽²âº¯ÊýÖе÷ÓÃÁË×¢²áº¯ÊýÀ´Îª¸ÃUSBÉ豸·ÖÅäÁËÒ»¸ö´ÎÉ豸ºÅ»°£¬±ØÐëµ÷ÓÃusb_deregister_devº¯ÊýÀ´°Ñ´ÎÉ豸ºÅ½»»¹¸øUSBºËÐÄ¡£ÔÚ¶Ï¿ªº¯ÊýÖУ¬´Ó½Ó¿Ú»ñȡ֮ǰµ÷ÓÃusb_set_intfdataÉèÖõÄÈκÎÊý¾ÝÒ²ÊǺÜÖØÒªµÄ¡£È»ºóÉèÖÃstruct usb_interface½á¹¹ÌåÖеÄÊý¾ÝÖ¸ÕëΪNULL£¬ÒÔ·ÀÈκβ»Êʵ±µÄ¶Ô¸ÃÊý¾ÝµÄ´íÎó·ÃÎÊ¡£

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

ÔÚ̽²âº¯ÊýÖлá¶Ôÿһ¸ö½Ó¿Ú½øÐÐÒ»´Î̽²â£¬ËùÒÔÎÒÃÇÔÚдUSBÇý¶¯³ÌÐòµÄʱºò£¬Ö»Òª×öºÃµÚÒ»¸ö¶Ëµã£¬ÆäËüµÄ¶Ëµã¾Í»á×Ô¶¯Íê³É̽²â¡£ÔÚ̽²âº¯ÊýÖÐÎÒÃÇҪעÒâµÄÊÇÔÚÄÚºËÖÐÓýṹÌåstruct usb_host_endpointÀ´ÃèÊöUSB¶Ëµã£¬Õâ¸ö½á¹¹ÌåÔÚÁíÒ»¸öÃûΪstruct usb_endpoint_descriptorµÄ½á¹¹ÌåÖаüº¬ÁËÕæÕýµÄ¶ËµãÐÅÏ¢£¬struct usb_endpoint_descriptor½á¹¹Ìå°üº¬ÁËËùÓеÄUSBÌØ¶¨µÄÊý¾Ý£¬¸Ã½á¹¹ÌåÖÐÎÒÃÇÒª¹ØÐĵö×Ö¶ÎÊÇ£º

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

bEndpointAddress£ºÕâ¸öÊÇÌØ¶¨µÄUSBµØÖ·£¬¿ÉÒÔ½áºÏUSB_DIR_INºÍUSB_DIR_OUTÀ´Ê¹Óã¬ÒÔÈ·¶¨¸Ã¶ËµãµÄÊý¾ÝÊÇ´«ÏòÉ豸»¹ÊÇÖ÷»ú¡£

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

bmAttributes£ºÕâ¸öÊǶ˵ãµÄÀàÐÍ£¬Õâ¸öÖµ¿ÉÒÔ½áºÏλÑÚÂëUSB_ENDPOINT_XFERTYPE_MASKÀ´Ê¹Óã¬ÒÔÈ·¶¨´Ë¶ËµãµÄÀàÐÍÊÇUSB_ENDPOINT_XFER_ISOC£¨µÈʱ£©¡¢USB_ENDPOINT_XFER_BULK£¨ÅúÁ¿£©¡¢USB_ENDPOINT_XFER_INTµÄÄÄÒ»ÖÖ¡£

eq7LinuxÁªÃË

wMaxPacketSize£ºÕâ¸öÊǶ˵ãÒ»´Î¿ÉÒÔ´¦ÀíµÄ×î´ó×Ö½ÚÊý£¬Çý¶¯³ÌÐò¿ÉÒÔ·¢ËÍÊýÁ¿´óÓÚ´ËÖµµÄÊý¾Ýµ½¶Ëµã£¬ÔÚʵ¼Ê´«ÊäÖУ¬Êý¾ÝÁ¿Èç¹û´óÓÚ´ËÖµ»á±»·Ö¸î¡£

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

bInterval£ºÕâ¸öÖµÖ»ÓÐÔڶ˵ãÀàÐÍÊÇÖжÏÀàÐÍʱ²ÅÆð×÷Óã¬ËüÊǶ˵ãÖжÏÇëÇóµÄ¼ä¸ôʱ¼ä£¬ÒÔºÁÃëΪµ¥Î»¡£

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

Ìá½»ºÍ¿ØÖÆurb£ºµ±Çý¶¯³ÌÐòÓÐÊý¾ÝÒª·¢Ë͵½USBÉ豸ʱ£¨´ó¶àÊýÇé¿öÊÇÔÚÇý¶¯³ÌÐòµÄдº¯ÊýÖУ©£¬Òª·ÖÅäÒ»¸öurbÀ´°ÑÊý¾Ý´«Ê䏸É豸£º

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

       /* ´´½¨Ò»¸öurb,²¢ÇÒ¸øËü·ÖÅäÒ»¸ö»º´æ*/

eq7LinuxÁªÃË

       urb = usb_alloc_urb(0, GFP_KERNEL);

eq7LinuxÁªÃË

       if (!urb) {

eq7LinuxÁªÃË

              retval = -ENOMEM;

eq7LinuxÁªÃË

              goto error;

eq7LinuxÁªÃË

       }

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

µ±urb±»³É¹¦·ÖÅäºó£¬»¹Òª´´½¨Ò»¸öDMA»º³åÇøÀ´ÒÔ¸ßЧµÄ·½Ê½·¢ËÍÊý¾Ýµ½É豸£¬´«µÝ¸øÇý¶¯³ÌÐòµÄÊý¾ÝÒª¸´ÖƵ½Õâ¿é»º³åÖÐÈ¥£º

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

       buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);

eq7LinuxÁªÃË

       if (!buf) {

eq7LinuxÁªÃË

              retval = -ENOMEM;

eq7LinuxÁªÃË

              goto error;

eq7LinuxÁªÃË

       }

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

       if (copy_from_user(buf, user_buffer, count)) {

eq7LinuxÁªÃË

              retval = -EFAULT;

eq7LinuxÁªÃË

              goto error;

eq7LinuxÁªÃË

       }

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

µ±Êý¾Ý´ÓÓû§¿Õ¼äÕýÈ·¸´ÖƵ½¾Ö²¿»º³åÇøºó£¬urb±ØÐëÔÚ¿ÉÒÔ±»Ìá½»¸øUSBºËÐÄ֮ǰ±»ÕýÈ·³õʼ»¯£º

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

       /* ³õʼ»¯urb */

eq7LinuxÁªÃË

       usb_fill_bulk_urb(urb, dev->udev,

eq7LinuxÁªÃË

                       usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),

eq7LinuxÁªÃË

                       buf, count, skel_write_bulk_callback, dev);

eq7LinuxÁªÃË

       urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

È»ºóurb¾Í¿ÉÒÔ±»Ìá½»¸øUSBºËÐÄÒÔ´«Êäµ½É豸ÁË£º

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

       /* °ÑÊý¾Ý´ÓÅúÁ¿OUT¶Ë¿Ú·¢³ö */

eq7LinuxÁªÃË

       retval = usb_submit_urb(urb, GFP_KERNEL);

eq7LinuxÁªÃË

       if (retval) {

eq7LinuxÁªÃË

              err("%s - failed submitting write urb, error %d", __FUNCTION__, retval);

eq7LinuxÁªÃË

              goto error;

eq7LinuxÁªÃË

       }

eq7LinuxÁªÃË

 

eq7LinuxÁªÃË

µ±urb±»³É¹¦´«Êäµ½USBÉ豸֮ºó£¬urb»Øµ÷º¯Êý½«±»USBºËÐĵ÷Óã¬ÔÚÎÒÃǵÄÀý×ÓÖУ¬ÎÒÃdzõʼ»¯urb£¬Ê¹ËüÖ¸Ïòskel_write_bulk_callbackº¯Êý£