使用Gadget 做usb鼠标键盘设备

使用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 -> <M> USB Gadget Drivers -> <M> 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
[] (unwind_backtrace) from [] (show_stack+0x10/0x14)
[] (show_stack) from [] (dump_stack+0x88/0x98)
[] (dump_stack) from [] (warn_slowpath_common+0x6c/0x88)
[] (warn_slowpath_common) from [] (warn_slowpath_fmt+0x30/0x40)
[] (warn_slowpath_fmt) from [] (sysfs_warn_dup+0x60/0x70)
[] (sysfs_warn_dup) from [] (sysfs_create_dir_ns+0x88/0x98)
[] (sysfs_create_dir_ns) from [] (kobject_add_internal+0xb0/0x300)
[] (kobject_add_internal) from [] (kobject_add+0x48/0x94)
[] (kobject_add) from [] (device_add+0xd8/0x53c)
[] (device_add) from [] (platform_device_add+0xb4/0x21c)
[] (platform_device_add) from [] (hidg_init+0x38/0xc8 [g_hid])
[] (hidg_init [g_hid]) from [] (do_one_initcall+0x8c/0x1c8)
[] (do_one_initcall) from [] (load_module+0x1740/0x1e88)
[] (load_module) from [] (SyS_init_module+0xd8/0xec)
[] (SyS_init_module) from [] (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为0和keyboard的id也是0相同了冲突了!! 经过这样子做,鼠标键盘在dev对应的是hidg0(键盘id 0) hidg1(鼠标id 1),只要打开这两个设备,往这两个设备发送键盘和鼠标报告就可以了

经过如此的配置只要按照顺序加载udc-hisi.ko、libcomposite.ko、以及g_hid.ko即可使用gadget鼠标键盘设备了,卸载这些驱动后,host又可以正常使用。

posted @ 2018-12-04 15:21  liqinghan  Views(810)  Comments(1)    收藏  举报