eclipse-threadx / usbx

Eclipse ThreadX - USBX is a high-performance USB host, device, and on-the-go (OTG) embedded stack, that is fully integrated with Eclipse ThreadX RTOS
https://github.com/eclipse-threadx/rtos-docs/blob/main/rtos-docs/usbx/index.md
MIT License
157 stars 92 forks source link

USBX HOST HID类导致内存踩踏风险 #52

Closed HelloByeAll closed 1 year ago

HelloByeAll commented 2 years ago

USBX HID 设备问题现象:

以鼠标举例, 假设第一个插入的鼠标为1号鼠标, 第二个插入的为2号鼠标,2个鼠标都插入后,将2号鼠标拔出,此时1号鼠标也将不能使用。


更严重的影响:发生内存踩踏

2号鼠标被拔出后,它所使用的内存将被释放,此时1号鼠标动作虽然使用api获取的属性值(x/y坐标、按键值、滚轮值)没有改变,当实际原因是1号鼠标的属性值被更新到2号鼠标原先属性值所在的内存中去了。1号鼠标仍在操作原本已经被释放的2号鼠标的内存。


LOG分析:

鼠标插入:

从LOG上可以看出插入一号鼠标后 一号鼠标的 mouse_instance = 0x2116D830 接着插入2号鼠标 mouse_instance = 0x21174140

从下面这2条LOG可以看出 他们所属的hid客户端是同一个,也就是调用ux_host_class_hid_client_register(_ux_system_host_class_hid_client_mouse_name, ux_host_class_hid_mouse_entry)注册鼠标客户端时malloc的一片内存。

鼠标枚举LOG _ux_host_class_hid_mouse_activate

源码:

从这个.c的源码中也能看出,这里 hid_client -> ux_host_class_hid_client_local_instance = (VOID *) mouse_instance;的操作会覆盖原本的这个值, 即使这个鼠标枚举失败了 hid_client -> ux_host_class_hid_client_local_instance也没有恢复操作,1号原本可以使用的对象就直接丢失了。(这里就不分析这个情况了,看代码就能理解了)

    /* Get some memory for both the HID class instance of this client
       and for the callback.  */
    mouse_instance =  (UX_HOST_CLASS_HID_MOUSE *) _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_HOST_CLASS_HID_MOUSE));

    if(mouse_instance == UX_NULL)
        return(UX_MEMORY_INSUFFICIENT);

    /* Attach the mouse instance to the client instance.  */
    hid_client -> ux_host_class_hid_client_local_instance =  (VOID *) mouse_instance;
    LOG_D("f{%s} hid_client = 0x%X  mouse_instance = 0x%X", __FUNCTION__, hid_client, mouse_instance);

    /* Save the HID instance in the client instance.  */
    mouse_instance -> ux_host_class_hid_mouse_hid =  hid;

LOG:

D/NO_TAG: f{_ux_host_class_hid_mouse_activate} hid_client = 0x21163370  mouse_instance = 0x2116D830
...
...
D/NO_TAG: f{_ux_host_class_hid_mouse_activate} hid_client = 0x21163370  mouse_instance = 0x21174140

2号鼠标拔出:

从LOG中可以很清楚的看到2号鼠标已经被协议栈移除 free hid_client = 0x21163370 instance 0x21174140并且已经释放了0x21174140这个地址的内存。

源码:

    /* Get the HID client pointer.  */
    hid_client =  hid -> ux_host_class_hid_client;

    /* If trace is enabled, insert this event into the trace buffer.  */
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_HID_MOUSE_DEACTIVATE, hid, hid_client -> ux_host_class_hid_client_local_instance, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)

    /* Now free the instance memory.  */
    LOG_D("f{%s} free hid_client = 0x%X  instance 0x%X", __FUNCTION__, hid_client, hid_client->ux_host_class_hid_client_local_instance);
    _ux_utility_memory_free(hid_client -> ux_host_class_hid_client_local_instance);

LOG:

I/NO_TAG: port2: ohci_register_port_status = 0x100
I/NO_TAG: f{_ux_host_stack_rh_change_process} line 119
I/NO_TAG: f{_ux_host_stack_rh_change_process} line 172
D/NO_TAG: f{_ux_host_stack_device_remove} device = 0x2115E408
D/NO_TAG: f{_ux_host_stack_device_remove} class_instance = 0x21171E20
D/NO_TAG: f{_ux_host_class_hid_mouse_deactivate} free hid_client = 0x21163370  instance 0x21174140
W/app_usbx_host: ux_host_event_callback event 0x4  Current_class = 0x2115DFE0  Current_instance = 0x21163370
W/app_usbx_host: HID Client Unplugged
W/app_usbx_host: ux_host_event_callback event 0x2  Current_class = 0x2115DFE0  Current_instance = 0x21171E20
I/app_usbx_host: mouse = 0x2116D830
I/app_usbx_host: Check the HID_client if this is a HID mouse device.
W/app_usbx_host: USB Device Removal
D/NO_TAG: f{_ux_host_stack_device_remove} class_instance = 0x211747B0
D/mouse: Pos_x = 11 Pos_y= 0
W/app_usbx_host: ux_host_event_callback event 0x2  Current_class = 0x2115DFE0  Current_instance = 0x211747B0
W/app_usbx_host: ux_host_event_callback event 0x82  Current_class = 0x0  Current_instance = 0x2115E408

2号鼠标拔出后移动1号鼠标:

从下面日志可以看到 mouse_instance = 0x21174140这个地址正是已经被释放了的2号鼠标所拥有的 0x21174140 而不是1号本身的 0x2116D830 源码中野可以看到,他下面直接对这个地址里的属性值做了修改,此时就发生了内存踩踏

源码:

VOID  _ux_host_class_hid_mouse_callback(UX_HOST_CLASS_HID_REPORT_CALLBACK* callback)
{

UX_HOST_CLASS_HID_CLIENT    *hid_client;
UX_HOST_CLASS_HID_MOUSE     *mouse_instance;

    /* Get the HID client instance that issued the callback.  */
    hid_client =  callback -> ux_host_class_hid_report_callback_client;

    /* Get the mouse local instance */
    mouse_instance =  (UX_HOST_CLASS_HID_MOUSE *) hid_client -> ux_host_class_hid_client_local_instance;

    LOG_D("f{%s}, mouse_instance  0x%X  usage 0x%X  value 0x%X", __FUNCTION__, mouse_instance, callback->ux_host_class_hid_report_callback_usage,
        callback->ux_host_class_hid_report_callback_value);
    /* Analyze the usage we have received.  */
    switch (callback -> ux_host_class_hid_report_callback_usage)
    {

        /* X/Y Axis movement.  */
        case    UX_HOST_CLASS_HID_MOUSE_AXIS_X      :

            /* Add the deplacement to the position.  */
            mouse_instance -> ux_host_class_hid_mouse_x_position += (SCHAR) callback -> ux_host_class_hid_report_callback_value;

            break;

LOG:

D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90001  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90002  value 0x1
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90003  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90004  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90005  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90006  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90007  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90008  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90009  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000A  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000B  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000C  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000D  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000E  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000F  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90010  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10030  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10031  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10038  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0xC0238  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90001  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90002  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90003  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90004  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90005  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90006  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90007  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90008  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90009  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000A  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000B  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000C  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000D  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000E  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000F  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90010  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10030  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10031  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10038  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0xC0238  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90001  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90002  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90003  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90004  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90005  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90006  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90007  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90008  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90009  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000A  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000B  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000C  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000D  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000E  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000F  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90010  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10030  value 0x1
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10031  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10038  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0xC0238  value 0x0

hid客户端注册 ux_host_class_hid_client_register

    /* From the class container, we get the client pointer which has the list of
       HID clients. If the pointer is NULL, the client list was not assigned.  */
    if (class -> ux_host_class_client == UX_NULL)
    {

        /* Allocate memory for the class client.
         * Allocate size overflow static checked outside the function.
         */
        class -> ux_host_class_client =  _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY,
                                            sizeof(UX_HOST_CLASS_HID_CLIENT)*UX_HOST_CLASS_HID_MAX_CLIENTS);

        /* Check for successful allocation.  */
        if (class -> ux_host_class_client == UX_NULL)
            return(UX_MEMORY_INSUFFICIENT);
    }

完整日志:

W/app_usbx_host: hid_client addr 0x211633C8
I/app_usbx_host: keyboard = 0x21169C70
I/app_usbx_host: Check the HID_client if this is a HID keyboard device.
D/app_usbx_host: HID_Keyboard_Device
D/app_usbx_host: PID: 0xc53f
D/app_usbx_host: VID: 0x46d
D/app_usbx_host: USB HID Host Keyboard App...
D/app_usbx_host: keyboard is ready...

D/NO_TAG: f{_ux_host_class_hid_client_search} item_global_usage_page  = 0x1   item_local_usage = 0x2
I/NO_TAG: f{_ux_host_class_hid_client_search} status = 0x0
I/NO_TAG: f{_ux_host_class_hid_client_search} activate ux_host_class_hid_client_mouse
D/NO_TAG: f{_ux_host_class_hid_mouse_activate} hid_client = 0x21163370  mouse_instance = 0x2116D830
I/NO_TAG: f{_ux_host_class_hid_mouse_activate} line 168  mouse_callback = 0x802A3DD8
W/app_usbx_host: ux_host_event_callback event 0x3  Current_class = 0x2115DFE0  Current_instance = 0x21163370
W/app_usbx_host: HID Client Plugged
W/app_usbx_host: ux_host_event_callback event 0x1  Current_class = 0x2115DFE0  Current_instance = 0x2116B540
W/app_usbx_host: hid_client addr 0x21163370
I/app_usbx_host: mouse = 0x2116D830
I/app_usbx_host: Check the HID_client if this is a HID mouse device.
D/app_usbx_host: HID_Mouse_Device
D/app_usbx_host: PID: 0xc53f
D/app_usbx_host: VID: 0x46d
D/app_usbx_host: USB HID Host Mouse App...
D/app_usbx_host: Mouse is ready...

D/NO_TAG: f{_ux_host_class_hid_client_search} item_global_usage_page  = 0xFF00   item_local_usage = 0x1
I/NO_TAG: f{_ux_host_class_hid_client_search} status = 0x57
I/NO_TAG: f{_ux_host_class_hid_client_search} status = 0x57
E/app_usbx_host: ux_host_error_callback  level 2,  context 7,  error_code 0x7B
W/app_usbx_host: ux_host_event_callback event 0x1  Current_class = 0x2115DFE0  Current_instance = 0x2116E540
W/app_usbx_host: hid_client addr 0x0
W/NO_TAG: _ux_host_stack_new_device_create [288]: status = 0
W/NO_TAG: _ux_host_stack_new_device_create 295 status = 0
W/app_usbx_host: ux_host_event_callback event 0x81  Current_class = 0x0  Current_instance = 0x2115E150
I/NO_TAG: port_index 2  ux_hcd_root_hub_signal 0

D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90001  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90002  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90003  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90004  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90005  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90006  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90007  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90008  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90009  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x9000A  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x9000B  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x9000C  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x9000D  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x9000E  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x9000F  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90010  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x10030  value 0x1
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x10031  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x10038  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0xC0238  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90001  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90002  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90003  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90004  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90005  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90006  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90007  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90008  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90009  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x9000A  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x9000B  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x9000C  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x9000D  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x9000E  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x9000F  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x90010  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x10030  value 0x9
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x10031  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0x10038  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x2116D830  usage 0xC0238  value 0x0
D/mouse: Pos_x = 11 Pos_y= 0

I/NO_TAG: port_index 0  ux_hcd_root_hub_signal 0
I/NO_TAG: port_index 1  ux_hcd_root_hub_signal 0
I/NO_TAG: port_index 2  ux_hcd_root_hub_signal 2
I/NO_TAG: port2: ohci_register_port_status = 0x101
I/NO_TAG: f{_ux_host_stack_rh_change_process} line 119
I/NO_TAG: f{_ux_host_stack_rh_change_process} line 128
I/NO_TAG: f{_ux_host_stack_rh_change_process} line 133
I/NO_TAG: ohci_port_enable  2
I/NO_TAG: port2: ohci_register_port_status = 0x103
D/NO_TAG: f{_ux_host_stack_new_device_create} new device = 0x2115E408

W/NO_TAG: Get the configuration descriptor
D/NO_TAG: vid = 0x46D  pid = 0xC084  class = 0x0 subclass = 0x0
W/NO_TAG: _ux_host_stack_new_device_create [282]: status = 57
D/NO_TAG: f{_ux_host_class_hid_client_search} item_global_usage_page  = 0x1   item_local_usage = 0x2
I/NO_TAG: f{_ux_host_class_hid_client_search} status = 0x0
I/NO_TAG: f{_ux_host_class_hid_client_search} activate ux_host_class_hid_client_mouse
D/NO_TAG: f{_ux_host_class_hid_mouse_activate} hid_client = 0x21163370  mouse_instance = 0x21174140
I/NO_TAG: f{_ux_host_class_hid_mouse_activate} line 168  mouse_callback = 0x802A3DD8
W/app_usbx_host: ux_host_event_callback event 0x3  Current_class = 0x2115DFE0  Current_instance = 0x21163370
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90001  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90002  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90003  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90004  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90005  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90006  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90007  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90008  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90009  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000A  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000B  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000C  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000D  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000E  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000F  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90010  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10030  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10031  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10038  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0xC0238  value 0x0
W/app_usbx_host: HID Client Plugged
W/app_usbx_host: ux_host_event_callback event 0x1  Current_class = 0x2115DFE0  Current_instance = 0x21171E20
W/app_usbx_host: hid_client addr 0x21163370
I/app_usbx_host: mouse = 0x21174140
I/app_usbx_host: Check the HID_client if this is a HID mouse device.
D/app_usbx_host: HID_Mouse_Device
D/app_usbx_host: PID: 0xc084
D/app_usbx_host: VID: 0x46d
D/app_usbx_host: USB HID Host Mouse App...
D/app_usbx_host: Mouse is ready...

D/mouse: Pos_x = 0 Pos_y= 0
D/NO_TAG: f{_ux_host_class_hid_client_search} item_global_usage_page  = 0x1   item_local_usage = 0x6
I/NO_TAG: f{_ux_host_class_hid_client_search} status = 0x57
I/NO_TAG: f{_ux_host_class_hid_client_search} status = 0x0
I/NO_TAG: f{_ux_host_class_hid_client_search} activate ux_host_class_hid_client_keyboard
I/NO_TAG: f{_ux_host_class_hid_keyboard_activate} hid = 0x211747B0
I/NO_TAG: f{_ux_host_class_hid_keyboard_activate} activate ux_host_class_hid_client_keyboard
I/NO_TAG: f{_ux_host_class_hid_keyboard_activate} hid_client = 0x211633C8   keyboard_instance = 0x21177CB0
W/app_usbx_host: ux_host_event_callback event 0x1  Current_class = 0x2115DFE0  Current_instance = 0x211747B0
W/app_usbx_host: hid_client addr 0x0
W/NO_TAG: _ux_host_stack_new_device_create [288]: status = 0
W/NO_TAG: _ux_host_stack_new_device_create 295 status = 0
W/app_usbx_host: ux_host_event_callback event 0x81  Current_class = 0x0  Current_instance = 0x2115E408
I/NO_TAG: port_index 0  ux_hcd_root_hub_signal 0
I/NO_TAG: port_index 1  ux_hcd_root_hub_signal 0
I/NO_TAG: port_index 2  ux_hcd_root_hub_signal 1
I/NO_TAG: port2: ohci_register_port_status = 0x103
I/NO_TAG: f{_ux_host_stack_rh_change_process} line 119
I/NO_TAG: f{_ux_host_stack_rh_change_process} line 128

D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90001  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90002  value 0x1
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90003  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90004  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90005  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90006  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90007  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90008  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90009  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000A  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000B  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000C  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000D  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000E  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000F  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90010  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10030  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10031  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10038  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0xC0238  value 0x0
D/mouse: Right Button Pressed
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90001  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90002  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90003  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90004  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90005  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90006  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90007  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90008  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90009  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000A  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000B  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000C  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000D  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000E  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000F  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90010  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10030  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10031  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10038  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0xC0238  value 0x0

I/NO_TAG: port_index 0  ux_hcd_root_hub_signal 0
I/NO_TAG: port_index 1  ux_hcd_root_hub_signal 0
I/NO_TAG: port_index 2  ux_hcd_root_hub_signal 1
I/NO_TAG: port2: ohci_register_port_status = 0x100
I/NO_TAG: f{_ux_host_stack_rh_change_process} line 119
I/NO_TAG: f{_ux_host_stack_rh_change_process} line 172
D/NO_TAG: f{_ux_host_stack_device_remove} device = 0x2115E408
D/NO_TAG: f{_ux_host_stack_device_remove} class_instance = 0x21171E20
D/NO_TAG: f{_ux_host_class_hid_mouse_deactivate} free hid_client = 0x21163370  instance 0x21174140
W/app_usbx_host: ux_host_event_callback event 0x4  Current_class = 0x2115DFE0  Current_instance = 0x21163370
W/app_usbx_host: HID Client Unplugged
W/app_usbx_host: ux_host_event_callback event 0x2  Current_class = 0x2115DFE0  Current_instance = 0x21171E20
I/app_usbx_host: mouse = 0x2116D830
I/app_usbx_host: Check the HID_client if this is a HID mouse device.
W/app_usbx_host: USB Device Removal
D/NO_TAG: f{_ux_host_stack_device_remove} class_instance = 0x211747B0
D/mouse: Pos_x = 11 Pos_y= 0
W/app_usbx_host: ux_host_event_callback event 0x2  Current_class = 0x2115DFE0  Current_instance = 0x211747B0
W/app_usbx_host: ux_host_event_callback event 0x82  Current_class = 0x0  Current_instance = 0x2115E408

D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90001  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90002  value 0x1
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90003  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90004  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90005  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90006  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90007  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90008  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90009  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000A  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000B  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000C  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000D  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000E  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000F  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90010  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10030  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10031  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10038  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0xC0238  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90001  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90002  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90003  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90004  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90005  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90006  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90007  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90008  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90009  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000A  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000B  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000C  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000D  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000E  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000F  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90010  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10030  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10031  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10038  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0xC0238  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90001  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90002  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90003  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90004  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90005  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90006  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90007  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90008  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90009  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000A  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000B  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000C  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000D  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000E  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x9000F  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x90010  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10030  value 0x1
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10031  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0x10038  value 0x0
D/NO_TAG: f{_ux_host_class_hid_mouse_callback}, mouse_instance  0x21174140  usage 0xC0238  value 0x0
xiaocq2001 commented 2 years ago

Thanks for the feedback.

The issue should be in _ux_host_class_hid_client_search, where linked client should not be used for new hid client. Please try following modification:

ux_host_class_hid_client_search.c, L110:

        /* Check if this HID client is registered and not locally used. */
        if ((hid_client -> ux_host_class_hid_client_status == UX_USED) &&
            (hid_client -> ux_host_class_hid_client_local_instance != UX_NULL))
HelloByeAll commented 2 years ago

感谢,稍后我会尝试一下这个修改,另外还有一些关于OHCI控制器的问题在 https://github.com/azure-rtos/usbx/issues/51

HelloByeAll commented 2 years ago

Thanks for the feedback.

The issue should be in _ux_host_class_hid_client_search, where linked client should not be used for new hid client. Please try following modification:

ux_host_class_hid_client_search.c, L110:

        /* Check if this HID client is registered and not locally used. */
        if ((hid_client -> ux_host_class_hid_client_status == UX_USED) &&
            (hid_client -> ux_host_class_hid_client_local_instance != UX_NULL))

这里的改法应该是

        /* Check if this HID client is registered and not locally used. */
        if ((hid_client -> ux_host_class_hid_client_status == UX_USED) &&
            (hid_client -> ux_host_class_hid_client_local_instance == UX_NULL))

否则将枚举不成功设备。

另外这并是不一个好的解决方法,有些鼠标本身是鼠标+键盘的复合设备,一旦插入这个鼠标那么新插入的键盘将不会再被成功枚举。 我理解的是这里应该建立一个ux_host_class_hid_client_local_instance 的链表,我们并不阻止相同的设备插入,我们应该让他们共存

xiaocq2001 commented 2 years ago

没错上文改法有笔误。

另外对于local instance在这个文件需要重置为空:ux_host_class_hid_deactivate.c

    /* Call the HID client with a deactivate command if there was a client registered.  */
    if (hid -> ux_host_class_hid_client != UX_NULL)
    {
        hid -> ux_host_class_hid_client -> ux_host_class_hid_client_handler(&hid_client_command);
        hid -> ux_host_class_hid_client -> ux_host_class_hid_client_local_instance = UX_NULL;
    }

这样弹出的hid可以释放hid client 的 local instance并重复利用。

关于复合设备,是不同的interface作为不同的hid存在么?那种对现在的实现是没有问题的,现在的实现每个interface对应一个hid instance,和一个hid client,键盘鼠标会枚举得到两个hid client。

如果同一个interface中包括多种hid client这个实现的确有问题,因为目前每个interface不能关联多个client。但这个实现相对修改会比较大,如果有切实的需求可作为新功能进行开发。

HelloByeAll commented 2 years ago

没错上文改法有笔误。

另外对于local instance在这个文件需要重置为空:ux_host_class_hid_deactivate.c

    /* Call the HID client with a deactivate command if there was a client registered.  */
    if (hid -> ux_host_class_hid_client != UX_NULL)
    {
        hid -> ux_host_class_hid_client -> ux_host_class_hid_client_handler(&hid_client_command);
        hid -> ux_host_class_hid_client -> ux_host_class_hid_client_local_instance = UX_NULL;
    }

这样弹出的hid可以释放hid client 的 local instance并重复利用。

关于复合设备,是不同的interface作为不同的hid存在么?那种对现在的实现是没有问题的,现在的实现每个interface对应一个hid instance,和一个hid client,键盘鼠标会枚举得到两个hid client。

如果同一个interface中包括多种hid client这个实现的确有问题,因为目前每个interface不能关联多个client。但这个实现相对修改会比较大,如果有切实的需求可作为新功能进行开发。

不是,就目前的代码来看,鼠标或者键盘只能各自拥有一个hid instance, 如果插入2个鼠标的话, 第二个鼠标会因为 hid instance != UX_NULL导致枚举不上,我认为的改进方法是在这个结构体中维护一个链表 struct UX_HOST_CLASS_HID_CLIENT_STRUCT *ux_host_class_hid_client_next; 在第二个鼠标插入时这个新的 hid instance应从原来的 hid instance中继承 name、ux_host_class_hid_client_functionux_host_class_hid_client_handler参数,同时加入ux_host_class_hid_client_nb参数用来表明当前类型的客户端中hid instance链表的长度。

typedef struct UX_HOST_CLASS_HID_CLIENT_STRUCT
{

    ULONG           ux_host_class_hid_client_status;
#if defined(UX_NAME_REFERENCED_BY_POINTER)
    UCHAR           *ux_host_class_hid_client_name;
#else
    UCHAR           ux_host_class_hid_client_name[UX_HOST_CLASS_HID_MAX_CLIENT_NAME_LENGTH + 1]; /* "+1" for string null-terminator */
#endif
    UINT            (*ux_host_class_hid_client_handler) (struct UX_HOST_CLASS_HID_CLIENT_COMMAND_STRUCT *);
    VOID            *ux_host_class_hid_client_local_instance;
#if defined(UX_HOST_STANDALONE)
    VOID            (*ux_host_class_hid_client_function)(struct UX_HOST_CLASS_HID_CLIENT_STRUCT *);
#endif
} UX_HOST_CLASS_HID_CLIENT;
typedef struct UX_HOST_CLASS_HID_CLIENT_STRUCT
{
    ULONG           ux_host_class_hid_client_nb;
    ULONG           ux_host_class_hid_client_status;
#if defined(UX_NAME_REFERENCED_BY_POINTER)
    UCHAR           *ux_host_class_hid_client_name;
#else
    UCHAR           ux_host_class_hid_client_name[UX_HOST_CLASS_HID_MAX_CLIENT_NAME_LENGTH + 1]; /* "+1" for string null-terminator */
#endif
    UINT            (*ux_host_class_hid_client_handler) (struct UX_HOST_CLASS_HID_CLIENT_COMMAND_STRUCT *);
    VOID            *ux_host_class_hid_client_local_instance;
    struct UX_HOST_CLASS_HID_CLIENT_STRUCT *ux_host_class_hid_client_next;
#if defined(UX_HOST_STANDALONE)
    VOID            (*ux_host_class_hid_client_function)(struct UX_HOST_CLASS_HID_CLIENT_STRUCT *);
#endif
} UX_HOST_CLASS_HID_CLIENT;
xiaocq2001 commented 2 years ago

发现问题了,现在hid会链接注册的client,注册的client再链接到client instance,这样如果要支持多个鼠标得注册多个鼠标client,而目前只能注册一个同类型的client……

修改应该可以保持和interface - class处理方式一致,在把注册的client里的local instance移到hid里,hid直接链接到根据注册的client创建的instance,这样注册的client就不会限制到底有多少client instance了

xiaocq2001 commented 2 years ago

上文的改动可能会影响原有HID API的使用(至少之前的hid report callback结构就得改,不然没法定位到具体的client instance),考虑到兼容性,可能的修改方式是不改变结构的情况下,以原注册的client为模板,在创建instance的同时创建一份拷贝以实际使用,这样在增加不多的运存使用的情况下可以兼顾之前的使用方式。

E.g., mouse modifications:

common/usbx_host_classes/inc/ux_host_class_hid_mouse.h

typedef struct UX_HOST_CLASS_HID_CLIENT_MOUSE_STRUCT
{
    UX_HOST_CLASS_HID_MOUSE     ux_host_class_hid_client_mouse_mouse;
    UX_HOST_CLASS_HID_CLIENT    ux_host_class_hid_client_mouse_client;
} UX_HOST_CLASS_HID_CLIENT_MOUSE;

common/usbx_host_classes/src/ux_host_class_hid_mouse_activate.c

UX_HOST_CLASS_HID_CLIENT_MOUSE          *client_mouse;
    /* Get some memory for both the HID class instance and copy of this client
       and for the callback.  */
    client_mouse =  (UX_HOST_CLASS_HID_CLIENT_MOUSE *)
                    _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, 
                                        sizeof(UX_HOST_CLASS_HID_CLIENT_MOUSE));
    if(client_mouse == UX_NULL)
        return(UX_MEMORY_INSUFFICIENT);

    /* Get client and mouse instance.  */
    mouse_instance = &client_mouse -> ux_host_class_hid_client_mouse_mouse;
    hid_client = &client_mouse -> ux_host_class_hid_client_mouse_client;
    _ux_utility_memory_copy(hid_client, hid -> ux_host_class_hid_client, sizeof(UX_HOST_CLASS_HID_CLIENT));
        if (status == UX_SUCCESS)
        {

            /* Use our copy of client.  */
            hid -> ux_host_class_hid_client = hid_client;

            /* If all is fine and the device is mounted, we may need to inform the application
               if a function has been programmed in the system structure.  */
            if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
            {

                /* Call system change function.  */
                _ux_system_host ->  ux_system_host_change_function(UX_HID_CLIENT_INSERTION, hid -> ux_host_class_hid_class, (VOID *) hid_client);
            }

            /* If trace is enabled, insert this event into the trace buffer.  */
            UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_HID_MOUSE_ACTIVATE, hid, mouse_instance, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)

            /* Return completion status.  */
            return(status);
        }
xiaocq2001 commented 1 year ago

Fix is done.