使用Gadget 做usb鼠標鍵盤設備


感謝TI社區提供的好幫助啊!http://e2e.ti.com/support/arm/sitara_arm/f/791/p/571771/2103409?pi316653=2
雖然海思平台和TI平台不一樣 ,但也大同小異。

具體的步驟如下:
轉到內核目錄:
//加載配置文件

cp xxx .config 
修改配置 
make xxxx menuconfig 
-> Device Drivers -> USB support -> USB Gadget Support 添加gadget, HID Gadget 
進到: 
-> Device Drivers -> USB support > USB Gadget Support-> USB Peripheral Controller 
->Device Drivers ->USB support > USB Gadget Support -> USB Peripheral Controller -> Hisilicon USB2.0 Device Controller SUPPORT 
+ [*] Hisilicon USB2.0 Device auto switch

打開自動切換!!!!
需要注意的是gadget子項的驅動依賴於udc模塊和composite模塊,而composite模塊又依賴於udc模塊,udc是硬件接口模塊,直接操作USB寄存器等。composite為上層驅動提供操作UDC。

所以加載順序必要是udc-hisi.ko 、libcomposite.ko 、g_hid.ko
加載發現出現問題,某些函數不能用,經過研究要打開

File systems > Pseudo filesystems 
+ {*} Userspace-driven configuration filesystem 

即可,加載g_hid.ko后出現: 
insmod: can’t insert ‘g_hid.ko’: No such device 
原因在於沒有注冊設備報告描述符!!!修改hid.c文件 
頭文件:

+#include <linux/usb/g_hid.h>
+static struct hidg_func_descriptor keyboard_report_data =
+{
+   .subclass       = 0, /* No subclass */  
+   .protocol       = 1, /* Keyboard */
+   .report_length      = 8,
+   .report_desc_length = 63,
+   .report_desc        = {
+   0x05, 0x01, /* USAGE_PAGE (Generic Desktop)           */
+       0x09, 0x06, /* USAGE (Keyboard)                       */
+       0xa1, 0x01, /* COLLECTION (Application)               */
+       0x05, 0x07, /*   USAGE_PAGE (Keyboard)                */
+       0x19, 0xe0, /*   USAGE_MINIMUM (Keyboard LeftControl) */
+       0x29, 0xe7, /*   USAGE_MAXIMUM (Keyboard Right GUI)   */
+       0x15, 0x00, /*   LOGICAL_MINIMUM (0)                  */
+       0x25, 0x01, /*   LOGICAL_MAXIMUM (1)                  */
+       0x75, 0x01, /*   REPORT_SIZE (1)                      */
+       0x95, 0x08, /*   REPORT_COUNT (8)                     */
+       0x81, 0x02, /*   INPUT (Data,Var,Abs)                 */
    +   0x95, 0x01, /*   REPORT_COUNT (1)                     */
    +   0x75, 0x08, /*   REPORT_SIZE (8)                      */
    +   0x81, 0x03, /*   INPUT (Cnst,Var,Abs)                 */
    +   0x95, 0x05, /*   REPORT_COUNT (5)                     */
    +   0x75, 0x01, /*   REPORT_SIZE (1)                      */
    +   0x05, 0x08, /*   USAGE_PAGE (LEDs)                    */
    +   0x19, 0x01, /*   USAGE_MINIMUM (Num Lock)             */
    +   0x29, 0x05, /*   USAGE_MAXIMUM (Kana)                 */
    +   0x91, 0x02, /*   OUTPUT (Data,Var,Abs)                */
    +   0x95, 0x01, /*   REPORT_COUNT (1)                     */
    +   0x75, 0x03, /*   REPORT_SIZE (3)                      */
    +   0x91, 0x03, /*   OUTPUT (Cnst,Var,Abs)                */
    +   0x95, 0x06, /*   REPORT_COUNT (6)                     */
    +   0x75, 0x08, /*   REPORT_SIZE (8)                      */
    +   0x15, 0x00, /*   LOGICAL_MINIMUM (0)                  */
    +   0x25, 0x65, /*   LOGICAL_MAXIMUM (101)                */
    +   0x05, 0x07, /*   USAGE_PAGE (Keyboard)                */
    +   0x19, 0x00, /*   USAGE_MINIMUM (Reserved)             */
    +   0x29, 0x65, /*   USAGE_MAXIMUM (Keyboard Application) */
    +   0x81, 0x00, /*   INPUT (Data,Ary,Abs)                 */
    +   0xc0        /* END_COLLECTION                         */  
+};

定義鍵盤設備:
+static struct platform_device keyboard_device = {  
+   .name           = "hidg",  
+   .id         = 0,  
+   .num_resources      = 0,  
+   .resource       = 0,  
+   .dev.platform_data  = &keyboard_report_data,  
+};  

 

在static int __init hidg_init(void)函數開始處注冊鍵盤設備

+status = platform_device_register(&keyboard_device);  
+   if (status < 0) {
+       printk("____ reg failed\n");
+       platform_device_unregister(&keyboard_device);
+       return status;  
+   }   

在驅動卸載處釋放鍵盤設備

platform_driver_unregister(&hidg_plat_driver); 
+platform_device_unregister(&keyboard_device); 
usb_composite_unregister(&hidg_driver);
添加后即可識別為鍵盤設別如下圖所示:



單個鍵盤和鼠標沒有任何問題,然而同時設置鼠標和鍵盤加載后出現如下錯誤:
------------[ cut here ]------------
WARNING: CPU: 1 PID: 139 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x60/0x70()
sysfs: cannot create duplicate filename '/devices/platform/hidg.0'
Modules linked in: g_hid(+) libcomposite udc_hisi [last unloaded: g_hid]
CPU: 1 PID: 139 Comm: insmod Tainted: G        W      3.18.20 #14
[<c001487c>] (unwind_backtrace) from [<c0011964>] (show_stack+0x10/0x14)
[<c0011964>] (show_stack) from [<c041e220>] (dump_stack+0x88/0x98)
[<c041e220>] (dump_stack) from [<c001e2d0>] (warn_slowpath_common+0x6c/0x88)
[<c001e2d0>] (warn_slowpath_common) from [<c001e31c>] (warn_slowpath_fmt+0x30/0x40)
[<c001e31c>] (warn_slowpath_fmt) from [<c012b4b8>] (sysfs_warn_dup+0x60/0x70)
[<c012b4b8>] (sysfs_warn_dup) from [<c012b550>] (sysfs_create_dir_ns+0x88/0x98)
[<c012b550>] (sysfs_create_dir_ns) from [<c01f94b0>] (kobject_add_internal+0xb0/0x300)
[<c01f94b0>] (kobject_add_internal) from [<c01f98bc>] (kobject_add+0x48/0x94)
[<c01f98bc>] (kobject_add) from [<c024eac4>] (device_add+0xd8/0x53c)
[<c024eac4>] (device_add) from [<c0252924>] (platform_device_add+0xb4/0x21c)
[<c0252924>] (platform_device_add) from [<bf0625bc>] (hidg_init+0x38/0xc8 [g_hid])
[<bf0625bc>] (hidg_init [g_hid]) from [<c00088d0>] (do_one_initcall+0x8c/0x1c8)
[<c00088d0>] (do_one_initcall) from [<c0085298>] (load_module+0x1740/0x1e88)
[<c0085298>] (load_module) from [<c0085ab8>] (SyS_init_module+0xd8/0xec)
[<c0085ab8>] (SyS_init_module) from [<c000e4a0>] (ret_fast_syscall+0x0/0x38)
---[ end trace c7b2846a724052eb ]---
static struct platform_device mouse_device = {  
   .name           = "hidg",  
   .id         = 0,  
   .num_resources      = 0,  
   .resource       = 0,  
   .dev.platform_data  = &mouse_report_desc,  
};

id和keyboard的id相同了沖突了!!
經過這樣子做,鼠標鍵盤在dev對應的是hidg0(鍵盤id 0) hidg1(鼠標id 1),只要打開這兩個設備,往這兩個設備發送鍵盤和鼠標報告就可以了

經過如此的配置只要按照順序加載udc-hisi.ko、libcomposite.ko、以及g_hid.ko即可使用gadget鼠標鍵盤設備了,卸載這些驅動后,host又可以正常使用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM