You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This sequence is guaranteed to cause a deadlock (assuming USB_DEVICE_Detach() is not called from an interrupt context).
Steps leading to the deadlock
I encountered this problem when trying to use both FreeRTOS and the default USB stack on a SAM G55 XPlained Pro board.
The docs say to call USB_DEVICE_Detach() in response to the USB_DEVICE_EVENT_POWER_REMOVED(1).
But the VBUS monitoring occurrs in DRV_USBDP_Tasks(), which is called in a task context (not an interrupt context) when using FreeRTOS. This means that when the USB_DEVICE_EVENT_POWER_REMOVED event is passed into the task event handler, the task is not running in an interrupt context
Modifying osal_freertos.h so that all the OSAL_Mutex functions use a recursive mutex solves the problem, indicating that the problem is indeed caused by the mutex locking.
Are you using polled usb mode instead of the default interrupt mode? I believe that is not recommended, but I agree this shouldn't happen either way. FWIW my event handler by default runs in an interrupt context and Detach() works fine.
There's a deadlock when calling
USB_DEVICE_Detach()
Cause of the deadlock
If
USB_DEVICE_Detach()
is called from a non-interrupt context, a mutex is locked:usb/driver/usbdp/src/dynamic/drv_usbdp_device.c
Line 842 in 204d5f2
USB_DEVICE_Detach()
then callsDRV_USBDP_EndpointDisable()
...usb/driver/usbdp/src/dynamic/drv_usbdp_device.c
Line 859 in 204d5f2
... which then proceeds to try to lock the same mutex, with a timeout of
OSAL_WAIT_FOREVER
:usb/driver/usbdp/src/dynamic/drv_usbdp_device.c
Line 1232 in 204d5f2
This sequence is guaranteed to cause a deadlock (assuming
USB_DEVICE_Detach()
is not called from an interrupt context).Steps leading to the deadlock
I encountered this problem when trying to use both FreeRTOS and the default USB stack on a SAM G55 XPlained Pro board.
The docs say to call
USB_DEVICE_Detach()
in response to theUSB_DEVICE_EVENT_POWER_REMOVED
(1).But the VBUS monitoring occurrs in
DRV_USBDP_Tasks()
, which is called in a task context (not an interrupt context) when using FreeRTOS. This means that when theUSB_DEVICE_EVENT_POWER_REMOVED
event is passed into the task event handler, the task is not running in an interrupt contextWhy does the demo project work?
Calling
USB_DEVICE_Detach()
in the G55 cdc_com_port_single demo project works, because the OSAL implementation used isosal_implementation_basic.h
. In this implementation, the mutex locking doesn't take the timeout into account, so the deadlock doesn't occur:https://github.com/Microchip-MPLAB-Harmony/usb_apps_device/blob/e8089912b07a7c4eaec5d5ee81c6929badfc9a9f/apps/cdc_com_port_single/firmware/src/config/sam_g55_xpro/osal/osal_impl_basic.h#L274-L282
I've not got the hardware to test one of the
FreeRTOS
demo projects, so I can't say if they workThanks,
-Jon
The text was updated successfully, but these errors were encountered: