USB device stack

Dependents:   mbed-mX-USB-TEST1 USBMSD_SD_HID_HelloWorld HidTest MIDI_usb_bridge ... more

Issue: KL25Z USB HAL code allocating from ISR

I recently tried building the USBMouse sample http://mbed.org/handbook/USBMouse with GCC_ARM and running it on LPC1768, LPC11U24, and KL25Z devices. It worked great on the LPC1768 and LPC11U24 parts but never enumerated on the KL25Z. After some struggles to get it under the debugger, I did finally see the cause of the problem and it was sitting at a hard coded breakpoint that I had previously added to my build system. This breakpoint watches memory allocations/deallocations to make sure that they are never made from an ISR since this typically leads to heap corruption. On the KL25Z device, it was trapping in USBHAL::realiseEndpoint() where it calls malloc() to allocate memory for endpoint buffers https://github.com/mbedmicro/mbed/blob/master/libraries/USBDevice/USBDevice/USBHAL_KL25Z.cpp#L206 and this was called directly from the USB ISR.

The change to use dynamically allocated buffers was made in commit 80518c4. I can see why the change was made since it previously pre-allocated enough memory for all endpoints (4k just for the isochronous endpoints), even if they weren't used. Should this be changed or are these dynamic allocations ok? The constructors for these objects tend to block the main thread while they wait to be enumerated so maybe this is safe! However, I don't think it sets a good example of what to do from an ISR even if it does work in this scenario.

1 comment:

29 Oct 2013

During enumeration Windows will reset the bus a minimum of *two* times. It usually does it many more times than that. With each USB reset malloc is eating up RAM from the heap. malloc's should also never be done from inside an interrupt.