Open js-nano opened 2 years ago
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:https://github.com/Microchip-MPLAB-Harmony/usb/blob/204d5f2d29d7ced2e9bd42cb9c3a4e4546e8fdfd/driver/usbdp/src/dynamic/drv_usbdp_device.c#L842
USB_DEVICE_Detach()
then callsDRV_USBDP_EndpointDisable()
...https://github.com/Microchip-MPLAB-Harmony/usb/blob/204d5f2d29d7ced2e9bd42cb9c3a4e4546e8fdfd/driver/usbdp/src/dynamic/drv_usbdp_device.c#L859
... which then proceeds to try to lock the same mutex, with a timeout of
OSAL_WAIT_FOREVER
:https://github.com/Microchip-MPLAB-Harmony/usb/blob/204d5f2d29d7ced2e9bd42cb9c3a4e4546e8fdfd/driver/usbdp/src/dynamic/drv_usbdp_device.c#L1232
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-L282I've not got the hardware to test one of the
FreeRTOS
demo projects, so I can't say if they workThanks, -Jon