diff --git a/class/audio/usbh_audio.c b/class/audio/usbh_audio.c index 63b0b857..4aed30fe 100644 --- a/class/audio/usbh_audio.c +++ b/class/audio/usbh_audio.c @@ -594,6 +594,7 @@ static int usbh_audio_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf) } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister Audio Class:%s\r\n", hport->config.intf[intf].devname); usbh_audio_stop(audio_class); } diff --git a/class/cdc/usbh_cdc_acm.c b/class/cdc/usbh_cdc_acm.c index 53666b32..2fc54eed 100644 --- a/class/cdc/usbh_cdc_acm.c +++ b/class/cdc/usbh_cdc_acm.c @@ -193,6 +193,7 @@ static int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf) #endif if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister CDC ACM Class:%s\r\n", hport->config.intf[intf].devname); usbh_cdc_acm_stop(cdc_acm_class); } diff --git a/class/cdc/usbh_cdc_ecm.c b/class/cdc/usbh_cdc_ecm.c index 286af231..094ea14f 100644 --- a/class/cdc/usbh_cdc_ecm.c +++ b/class/cdc/usbh_cdc_ecm.c @@ -221,6 +221,7 @@ static int usbh_cdc_ecm_disconnect(struct usbh_hubport *hport, uint8_t intf) } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister CDC ECM Class:%s\r\n", hport->config.intf[intf].devname); usbh_cdc_ecm_stop(cdc_ecm_class); } diff --git a/class/cdc/usbh_cdc_ncm.c b/class/cdc/usbh_cdc_ncm.c index 7e35da36..b7c89f3d 100644 --- a/class/cdc/usbh_cdc_ncm.c +++ b/class/cdc/usbh_cdc_ncm.c @@ -239,6 +239,7 @@ static int usbh_cdc_ncm_disconnect(struct usbh_hubport *hport, uint8_t intf) } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister CDC NCM Class:%s\r\n", hport->config.intf[intf].devname); usbh_cdc_ncm_stop(cdc_ncm_class); } diff --git a/class/hid/usbh_hid.c b/class/hid/usbh_hid.c index cb407f54..5c400c7b 100644 --- a/class/hid/usbh_hid.c +++ b/class/hid/usbh_hid.c @@ -299,6 +299,7 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf) } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister HID Class:%s\r\n", hport->config.intf[intf].devname); usbh_hid_stop(hid_class); } diff --git a/class/msc/usbh_msc.c b/class/msc/usbh_msc.c index 88c90b0b..fe91a5bf 100644 --- a/class/msc/usbh_msc.c +++ b/class/msc/usbh_msc.c @@ -342,6 +342,7 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf) } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister MSC Class:%s\r\n", hport->config.intf[intf].devname); usbh_msc_stop(msc_class); } diff --git a/class/vendor/net/usbh_asix.c b/class/vendor/net/usbh_asix.c index 60b64472..981c5067 100644 --- a/class/vendor/net/usbh_asix.c +++ b/class/vendor/net/usbh_asix.c @@ -638,6 +638,7 @@ static int usbh_asix_disconnect(struct usbh_hubport *hport, uint8_t intf) } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister ASIX Class:%s\r\n", hport->config.intf[intf].devname); usbh_asix_stop(asix_class); } diff --git a/class/vendor/net/usbh_rtl8152.c b/class/vendor/net/usbh_rtl8152.c index 60fec839..9c4b6570 100644 --- a/class/vendor/net/usbh_rtl8152.c +++ b/class/vendor/net/usbh_rtl8152.c @@ -2121,6 +2121,7 @@ static int usbh_rtl8152_disconnect(struct usbh_hubport *hport, uint8_t intf) } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister rtl8152 Class:%s\r\n", hport->config.intf[intf].devname); usbh_rtl8152_stop(rtl8152_class); } diff --git a/class/vendor/serial/usbh_ch34x.c b/class/vendor/serial/usbh_ch34x.c index a6908345..3941d47d 100644 --- a/class/vendor/serial/usbh_ch34x.c +++ b/class/vendor/serial/usbh_ch34x.c @@ -311,6 +311,7 @@ static int usbh_ch34x_disconnect(struct usbh_hubport *hport, uint8_t intf) } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister CH34X Class:%s\r\n", hport->config.intf[intf].devname); usbh_ch34x_stop(ch34x_class); } diff --git a/class/vendor/serial/usbh_cp210x.c b/class/vendor/serial/usbh_cp210x.c index f3b0d461..f58350e6 100644 --- a/class/vendor/serial/usbh_cp210x.c +++ b/class/vendor/serial/usbh_cp210x.c @@ -260,6 +260,7 @@ static int usbh_cp210x_disconnect(struct usbh_hubport *hport, uint8_t intf) } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister CP210X Class:%s\r\n", hport->config.intf[intf].devname); usbh_cp210x_stop(cp210x_class); } diff --git a/class/vendor/serial/usbh_ftdi.c b/class/vendor/serial/usbh_ftdi.c index b45f4d52..6bc19b20 100644 --- a/class/vendor/serial/usbh_ftdi.c +++ b/class/vendor/serial/usbh_ftdi.c @@ -440,6 +440,7 @@ static int usbh_ftdi_disconnect(struct usbh_hubport *hport, uint8_t intf) } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister FTDI Class:%s\r\n", hport->config.intf[intf].devname); usbh_ftdi_stop(ftdi_class); } diff --git a/class/vendor/serial/usbh_pl2303.c b/class/vendor/serial/usbh_pl2303.c index 35574cdc..ece32538 100644 --- a/class/vendor/serial/usbh_pl2303.c +++ b/class/vendor/serial/usbh_pl2303.c @@ -375,6 +375,7 @@ static int usbh_pl2303_disconnect(struct usbh_hubport *hport, uint8_t intf) } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister PL2303 Class:%s\r\n", hport->config.intf[intf].devname); usbh_pl2303_stop(pl2303_class); } diff --git a/class/vendor/wifi/usbh_bl616.c b/class/vendor/wifi/usbh_bl616.c index 059086be..e44df5bd 100644 --- a/class/vendor/wifi/usbh_bl616.c +++ b/class/vendor/wifi/usbh_bl616.c @@ -337,6 +337,7 @@ static int usbh_bl616_disconnect(struct usbh_hubport *hport, uint8_t intf) } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister BL616 WIFI Class:%s\r\n", hport->config.intf[intf].devname); usbh_bl616_stop(bl616_class); } diff --git a/class/vendor/xbox/usbh_xbox.c b/class/vendor/xbox/usbh_xbox.c index 0c3339c9..364ca27c 100644 --- a/class/vendor/xbox/usbh_xbox.c +++ b/class/vendor/xbox/usbh_xbox.c @@ -86,6 +86,7 @@ int usbh_xbox_disconnect(struct usbh_hubport *hport, uint8_t intf) } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister XBOX Class:%s\r\n", hport->config.intf[intf].devname); usbh_xbox_stop(xbox_class); } diff --git a/class/video/usbh_video.c b/class/video/usbh_video.c index cd8e5e65..077b6bb9 100644 --- a/class/video/usbh_video.c +++ b/class/video/usbh_video.c @@ -483,6 +483,7 @@ static int usbh_video_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf) } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister Video Class:%s\r\n", hport->config.intf[intf].devname); usbh_video_stop(video_class); } diff --git a/class/wireless/usbh_bluetooth.c b/class/wireless/usbh_bluetooth.c index 59c0586f..af7167c0 100644 --- a/class/wireless/usbh_bluetooth.c +++ b/class/wireless/usbh_bluetooth.c @@ -134,6 +134,7 @@ static int usbh_bluetooth_disconnect(struct usbh_hubport *hport, uint8_t intf) // } #endif if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister Bluetooth Class:%s\r\n", hport->config.intf[intf].devname); usbh_bluetooth_stop(bluetooth_class); } diff --git a/class/wireless/usbh_rndis.c b/class/wireless/usbh_rndis.c index 8eef39dd..b6e43a76 100644 --- a/class/wireless/usbh_rndis.c +++ b/class/wireless/usbh_rndis.c @@ -438,6 +438,7 @@ static int usbh_rndis_disconnect(struct usbh_hubport *hport, uint8_t intf) // } if (hport->config.intf[intf].devname[0] != '\0') { + usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister RNDIS Class:%s\r\n", hport->config.intf[intf].devname); usbh_rndis_stop(rndis_class); } diff --git a/common/usb_osal.h b/common/usb_osal.h index 324d3ae3..1975f208 100644 --- a/common/usb_osal.h +++ b/common/usb_osal.h @@ -42,6 +42,7 @@ struct usb_osal_timer { */ 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); void usb_osal_thread_delete(usb_osal_thread_t thread); +void usb_osal_thread_schedule_other(void); usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count); void usb_osal_sem_delete(usb_osal_sem_t sem); diff --git a/osal/idf/usb_osal_idf.c b/osal/idf/usb_osal_idf.c index b64539d9..a79faf8e 100644 --- a/osal/idf/usb_osal_idf.c +++ b/osal/idf/usb_osal_idf.c @@ -25,6 +25,18 @@ void usb_osal_thread_delete(usb_osal_thread_t thread) vTaskDelete(thread); } +void usb_osal_thread_schedule_other(void) +{ + TaskHandle_t xCurrentTask = xTaskGetCurrentTaskHandle(); + const UBaseType_t old_priority = uxTaskPriorityGet(xCurrentTask); + + vTaskPrioritySet(xCurrentTask, tskIDLE_PRIORITY); + + taskYIELD(); + + vTaskPrioritySet(xCurrentTask, old_priority); +} + usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count) { return (usb_osal_sem_t)xSemaphoreCreateCounting(1, initial_count); diff --git a/osal/usb_osal_freertos.c b/osal/usb_osal_freertos.c index e03275c1..6bdd883b 100644 --- a/osal/usb_osal_freertos.c +++ b/osal/usb_osal_freertos.c @@ -30,6 +30,18 @@ void usb_osal_thread_delete(usb_osal_thread_t thread) vTaskDelete(thread); } +void usb_osal_thread_schedule_other(void) +{ + TaskHandle_t xCurrentTask = xTaskGetCurrentTaskHandle(); + const UBaseType_t old_priority = uxTaskPriorityGet(xCurrentTask); + + vTaskPrioritySet(xCurrentTask, tskIDLE_PRIORITY); + + taskYIELD(); + + vTaskPrioritySet(xCurrentTask, old_priority); +} + usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count) { usb_osal_sem_t sem = (usb_osal_sem_t)xSemaphoreCreateCounting(1, initial_count); diff --git a/osal/usb_osal_liteos_m.c b/osal/usb_osal_liteos_m.c index 9e97dbb9..cda86665 100644 --- a/osal/usb_osal_liteos_m.c +++ b/osal/usb_osal_liteos_m.c @@ -55,6 +55,18 @@ void usb_osal_thread_delete(usb_osal_thread_t thread) } } +void usb_osal_thread_schedule_other(void) +{ + UINT32 task_id = LOS_CurTaskIDGet(); + const UINT16 old_priority = LOS_TaskPriGet(task_id); + + LOS_TaskPriSet(task_id, OS_TASK_PRIORITY_LOWEST); + + LOS_TaskYield(); + + LOS_TaskPriSet(task_id, old_priority); +} + usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count) { UINT32 sem_handle; diff --git a/osal/usb_osal_nuttx.c b/osal/usb_osal_nuttx.c index 3a4e7f0c..49911573 100644 --- a/osal/usb_osal_nuttx.c +++ b/osal/usb_osal_nuttx.c @@ -63,6 +63,18 @@ void usb_osal_thread_delete(usb_osal_thread_t thread) kthread_delete(pid); } +void usb_osal_thread_schedule_other(void) +{ + struct tcb_s *tcb = nxsched_self(); + const int old_priority = tcb->sched_priority; + + nxsched_set_priority(tcb, SCHED_PRIORITY_MIN); + + sched_yield(); + + nxsched_set_priority(tcb, old_priority); +} + usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count) { int ret; diff --git a/osal/usb_osal_rtthread.c b/osal/usb_osal_rtthread.c index dd1075a5..14448fc4 100644 --- a/osal/usb_osal_rtthread.c +++ b/osal/usb_osal_rtthread.c @@ -34,6 +34,23 @@ void usb_osal_thread_delete(usb_osal_thread_t thread) rt_thread_delete(thread); } +void usb_osal_thread_schedule_other(void) +{ + rt_thread_t self = rt_thread_self(); + rt_uint8_t priority; +#if (RTTHREAD_VERSION >= RT_VERSION_CHECK(5, 0, 0)) + const rt_uint8_t old_priority = RT_SCHED_PRIV(self).current_priority; +#else + const rt_uint8_t old_priority = self->current_priority; +#endif + priority = RT_THREAD_PRIORITY_MAX - 1; + rt_thread_control(self, RT_THREAD_CTRL_CHANGE_PRIORITY, (void *)&priority); + + rt_thread_yield(); + + rt_thread_control(self, RT_THREAD_CTRL_CHANGE_PRIORITY, (void *)&old_priority); +} + usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count) { usb_osal_sem_t sem = (usb_osal_sem_t)rt_sem_create("usbh_sem", initial_count, RT_IPC_FLAG_FIFO); diff --git a/osal/usb_osal_threadx.c b/osal/usb_osal_threadx.c index 5d2e13c7..62dd3b84 100644 --- a/osal/usb_osal_threadx.c +++ b/osal/usb_osal_threadx.c @@ -69,6 +69,18 @@ void usb_osal_thread_delete(usb_osal_thread_t thread) tx_byte_release(thread); } +void usb_osal_thread_schedule_other(void) +{ + TX_THREAD *current_thread = tx_thread_identify(); + const UINT old_priority = current_thread->tx_thread_priority; + + tx_thread_priority_change(current_thread, TX_MAX_PRIORITIES - 1, &old_priority); + + tx_thread_relinquish(); + + tx_thread_priority_change(current_thread, old_priority, &old_priority); +} + usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count) { TX_SEMAPHORE *sem_ptr = TX_NULL; diff --git a/osal/usb_osal_zephyr.c b/osal/usb_osal_zephyr.c index c087c962..ce214e6e 100644 --- a/osal/usb_osal_zephyr.c +++ b/osal/usb_osal_zephyr.c @@ -74,6 +74,22 @@ void usb_osal_thread_delete(usb_osal_thread_t thread) k_free(thread); } +void usb_osal_thread_schedule_other(void) +{ +#if (KERNELVERSION >= 0x3070000) + struct k_thread *current_thread = k_sched_current_thread_query(); +#else + struct k_thread *current_thread = z_current_get(); +#endif + const int old_priority = k_thread_priority_get(current_thread); + + k_thread_priority_set(current_thread, K_LOWEST_APPLICATION_THREAD_PRIO); + + k_yield(); + + k_thread_priority_set(current_thread, old_priority); +} + usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count) { struct k_sem *sem;