diff options
| author | sakimisu <[email protected]> | 2022-12-11 18:50:33 +0800 |
|---|---|---|
| committer | sakimisu <[email protected]> | 2022-12-11 20:27:18 +0800 |
| commit | 843af28b2bfe4e669aa9f9dc51bdf8bc4f661da7 (patch) | |
| tree | ac9fd901ca9eb5e76ce94f2920305b86e67dbf8c | |
| parent | 9a67853751c3ff42e1ef4b59cdfa6c7596ce82d5 (diff) | |
update hub thread wakeup with queue not sem&list
| -rw-r--r-- | class/hub/usbh_hub.c | 76 | ||||
| -rw-r--r-- | class/hub/usbh_hub.h | 2 | ||||
| -rw-r--r-- | core/usbh_core.h | 1 | ||||
| -rw-r--r-- | osal/usb_osal.h | 6 | ||||
| -rw-r--r-- | osal/usb_osal_freertos.c | 27 | ||||
| -rw-r--r-- | osal/usb_osal_rtthread.c | 27 |
6 files changed, 93 insertions, 46 deletions
diff --git a/class/hub/usbh_hub.c b/class/hub/usbh_hub.c index 15d4fb63..90724544 100644 --- a/class/hub/usbh_hub.c +++ b/class/hub/usbh_hub.c @@ -17,11 +17,10 @@ static uint32_t g_devinuse = 0; USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_buf[32]; -usb_slist_t hub_event_head = USB_SLIST_OBJECT_INIT(hub_event_head); usb_slist_t hub_class_head = USB_SLIST_OBJECT_INIT(hub_class_head); -usb_osal_sem_t hub_event_wait; usb_osal_thread_t hub_thread; +usb_osal_mq_t hub_mq; USB_NOCACHE_RAM_SECTION struct usbh_hub roothub; @@ -31,6 +30,7 @@ USB_NOCACHE_RAM_SECTION struct usbh_hub exthub[CONFIG_USBHOST_MAX_EXTHUBS]; extern int usbh_hport_activate_ep0(struct usbh_hubport *hport); extern int usbh_hport_deactivate_ep0(struct usbh_hubport *hport); extern int usbh_enumerate(struct usbh_hubport *hport); +static void usbh_hub_thread_wakeup(struct usbh_hub *hub); static const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" }; @@ -56,6 +56,17 @@ static void usbh_hub_devno_free(uint8_t devno) g_devinuse &= ~(1 << devno); } } + +static void usbh_hub_register(struct usbh_hub *hub) +{ + usb_slist_add_tail(&hub_class_head, &hub->list); +} + +static void usbh_hub_unregister(struct usbh_hub *hub) +{ + usb_slist_remove(&hub_class_head, &hub->list); +} + #endif static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer) { @@ -226,12 +237,7 @@ static int usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t fe } } -static void usbh_hub_thread_wakeup(struct usbh_hub *hub) -{ - usb_slist_add_tail(&hub_event_head, &hub->hub_event_list); - usb_osal_sem_give(hub_event_wait); -} - +#if CONFIG_USBHOST_MAX_EXTHUBS > 0 static void hub_int_complete_callback(void *arg, int nbytes) { struct usbh_hub *hub = (struct usbh_hub *)arg; @@ -240,7 +246,7 @@ static void hub_int_complete_callback(void *arg, int nbytes) usbh_hub_thread_wakeup(hub); } } -#if CONFIG_USBHOST_MAX_EXTHUBS > 0 + static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf) { struct usb_endpoint_descriptor *ep_desc; @@ -344,18 +350,6 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf) return ret; } #endif -static void usbh_roothub_register(void) -{ - memset(&roothub, 0, sizeof(struct usbh_hub)); - - roothub.connected = true; - roothub.index = 1; - roothub.is_roothub = true; - roothub.parent = NULL; - roothub.hub_addr = 1; - roothub.hub_desc.bNbrPorts = CONFIG_USBHOST_MAX_RHPORTS; - usbh_hub_register(&roothub); -} static void usbh_hub_events(struct usbh_hub *hub) { @@ -526,6 +520,7 @@ static void usbh_hub_events(struct usbh_hub *hub) } } + hub->int_buffer[0] = 0; /* Start next hub int transfer */ if (!hub->is_roothub && hub->connected) { usbh_submit_urb(&hub->intin_urb); @@ -534,48 +529,49 @@ static void usbh_hub_events(struct usbh_hub *hub) static void usbh_hub_thread(void *argument) { - size_t flags; + struct usbh_hub *hub; int ret = 0; usb_hc_init(); while (1) { - ret = usb_osal_sem_take(hub_event_wait, 0xffffffff); + ret = usb_osal_mq_recv(hub_mq, (uint32_t *)&hub, 0xffffffff); if (ret < 0) { continue; } - - while (!usb_slist_isempty(&hub_event_head)) { - struct usbh_hub *hub = usb_slist_first_entry(&hub_event_head, struct usbh_hub, hub_event_list); - flags = usb_osal_enter_critical_section(); - usb_slist_remove(&hub_event_head, &hub->hub_event_list); - usb_osal_leave_critical_section(flags); - usbh_hub_events(hub); - } + usbh_hub_events(hub); } } -void usbh_roothub_thread_wakeup(uint8_t port) +static void usbh_roothub_register(void) { - roothub.int_buffer[0] |= (1 << port); - usbh_hub_thread_wakeup(&roothub); + memset(&roothub, 0, sizeof(struct usbh_hub)); + + roothub.connected = true; + roothub.index = 1; + roothub.is_roothub = true; + roothub.parent = NULL; + roothub.hub_addr = 1; + roothub.hub_desc.bNbrPorts = CONFIG_USBHOST_MAX_RHPORTS; + usbh_hub_register(&roothub); } -void usbh_hub_register(struct usbh_hub *hub) +static void usbh_hub_thread_wakeup(struct usbh_hub *hub) { - usb_slist_add_tail(&hub_class_head, &hub->list); + usb_osal_mq_send(hub_mq, (uint32_t)hub); } -void usbh_hub_unregister(struct usbh_hub *hub) +void usbh_roothub_thread_wakeup(uint8_t port) { - usb_slist_remove(&hub_class_head, &hub->list); + roothub.int_buffer[0] |= (1 << port); + usbh_hub_thread_wakeup(&roothub); } int usbh_hub_initialize(void) { usbh_roothub_register(); - hub_event_wait = usb_osal_sem_create(0); - if (hub_event_wait == NULL) { + hub_mq = usb_osal_mq_create(7); + if (hub_mq == NULL) { return -1; } diff --git a/class/hub/usbh_hub.h b/class/hub/usbh_hub.h index 41807de0..f46750d9 100644 --- a/class/hub/usbh_hub.h +++ b/class/hub/usbh_hub.h @@ -19,8 +19,6 @@ extern usb_slist_t hub_class_head; extern "C" { #endif void usbh_roothub_thread_wakeup(uint8_t port); -void usbh_hub_register(struct usbh_hub *hub); -void usbh_hub_unregister(struct usbh_hub *hub); int usbh_hub_initialize(void); #ifdef __cplusplus } diff --git a/core/usbh_core.h b/core/usbh_core.h index 39f9ad9b..0fd1ba0c 100644 --- a/core/usbh_core.h +++ b/core/usbh_core.h @@ -160,7 +160,6 @@ struct usbh_hub { struct usb_hub_descriptor hub_desc; struct usbh_hubport child[CONFIG_USBHOST_MAX_EHPORTS]; struct usbh_hubport *parent; - usb_slist_t hub_event_list; }; int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struct usb_endpoint_descriptor *ep_desc); diff --git a/osal/usb_osal.h b/osal/usb_osal.h index 45adf313..d730b74e 100644 --- a/osal/usb_osal.h +++ b/osal/usb_osal.h @@ -12,6 +12,7 @@ typedef void *usb_osal_thread_t; typedef void *usb_osal_sem_t; typedef void *usb_osal_mutex_t; +typedef void *usb_osal_mq_t; typedef void (*usb_thread_entry_t)(void *argument); usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, uint32_t prio, usb_thread_entry_t entry, void *args); @@ -26,10 +27,13 @@ void usb_osal_mutex_delete(usb_osal_mutex_t mutex); int usb_osal_mutex_take(usb_osal_mutex_t mutex); int usb_osal_mutex_give(usb_osal_mutex_t mutex); +usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs); +int usb_osal_mq_send(usb_osal_mq_t mq, uint32_t addr); +int usb_osal_mq_recv(usb_osal_mq_t mq, uint32_t *addr, uint32_t timeout); + size_t usb_osal_enter_critical_section(void); void usb_osal_leave_critical_section(size_t flag); void usb_osal_msleep(uint32_t delay); #endif /* USB_OSAL_H */ - diff --git a/osal/usb_osal_freertos.c b/osal/usb_osal_freertos.c index 009a61b3..65d9f1c3 100644 --- a/osal/usb_osal_freertos.c +++ b/osal/usb_osal_freertos.c @@ -43,7 +43,7 @@ int usb_osal_sem_give(usb_osal_sem_t sem) portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } - return (ret == pdPASS) ? 0 : -EINVAL; + return (ret == pdPASS) ? 0 : -ETIMEDOUT; } usb_osal_mutex_t usb_osal_mutex_create(void) @@ -63,7 +63,30 @@ int usb_osal_mutex_take(usb_osal_mutex_t mutex) int usb_osal_mutex_give(usb_osal_mutex_t mutex) { - return (xSemaphoreGive((SemaphoreHandle_t)mutex) == pdPASS) ? 0 : -EINVAL; + return (xSemaphoreGive((SemaphoreHandle_t)mutex) == pdPASS) ? 0 : -ETIMEDOUT; +} + +usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs) +{ + return (usb_osal_mq_t)xQueueCreate(max_msgs, 4); +} + +int usb_osal_mq_send(usb_osal_mq_t mq, uint32_t addr) +{ + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + int ret; + + ret = xQueueSendFromISR((usb_osal_mq_t)mq, &addr, &xHigherPriorityTaskWoken); + if (ret == pdPASS) { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + + return (ret == pdPASS) ? 0 : -ETIMEDOUT; +} + +int usb_osal_mq_recv(usb_osal_mq_t mq, uint32_t *addr, uint32_t timeout) +{ + return (xQueueReceive((usb_osal_mq_t)mq, addr, timeout) == pdPASS) ? 0 : -ETIMEDOUT; } size_t usb_osal_enter_critical_section(void) diff --git a/osal/usb_osal_rtthread.c b/osal/usb_osal_rtthread.c index 3442ea43..f2f830e7 100644 --- a/osal/usb_osal_rtthread.c +++ b/osal/usb_osal_rtthread.c @@ -68,6 +68,33 @@ int usb_osal_mutex_give(usb_osal_mutex_t mutex) return (int)rt_mutex_release((rt_mutex_t)mutex); } +usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs) +{ + return (usb_osal_mq_t)rt_mq_create("usbh_mq", 4, max_msgs, RT_IPC_FLAG_FIFO); +} + +int usb_osal_mq_send(usb_osal_mq_t mq, uint32_t addr) +{ + return rt_mq_send((rt_mq_t)mq, &addr, 4); +} + +int usb_osal_mq_recv(usb_osal_mq_t mq, uint32_t *addr, uint32_t timeout) +{ + int ret = 0; + rt_err_t result = RT_EOK; + + result = rt_mq_recv((rt_mq_t)mq, addr, 4, rt_tick_from_millisecond(timeout)); + if (result == -RT_ETIMEOUT) { + ret = -ETIMEDOUT; + } else if (result == -RT_ERROR) { + ret = -EINVAL; + } else { + ret = 0; + } + + return (int)ret; +} + size_t usb_osal_enter_critical_section(void) { return rt_hw_interrupt_disable(); |
