Showing results for 
Search instead for 
Did you mean: 

Why does the HAL USB CDC driver call malloc in an ISR context?

Associate II

Since __malloc_lock has not been implemented by default, newlib's malloc / _malloc_r is not reentrant or thread safe (including ISR safe). This seems like a bug.

This will cause very bad interactions with user code use of malloc, including heap corruption. Additionally, most RTOS's heaps are not ISR-safe, so when using the freertos heap it causes a crash. Usually when using newlib & freertos I implement _mallor_r to use the rots heap, and provide __malloc_lock and __malloc_unlock so it is threadsafe. This is necessary so the C library internal allocations are threadsafe, but doing so causes a crash when the cdc driver attempts to allocate memory within the ISR.

Can this be changed to allow either a statically allocated buffer, a user provided buffer, or a thread-context dynamically allocated buffer? I have moved the classData it is trying to allocate to be static for now, but in general this needs to be allocated per usb instance, so a single one is not enough.

Perhaps a user provided buffer passed in at configuration time would be better.


I think Bob S assumption is very plausible (which makes me scratching my head even harder), as the CDC interface has no "context binding" or whatsoever, which pretty much confirms the "single CDC interface" implementation:

typedef struct _USBD_CDC_Itf
  int8_t (* Init)(void);
  int8_t (* DeInit)(void);
  int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length);
  int8_t (* Receive)(uint8_t *Buf, uint32_t *Len);
  int8_t (* TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum);
} USBD_CDC_ItfTypeDef;