STM32H7 USB driver fails highest optimization (-O3)
- October 25, 2019
- 4 replies
- 1528 views
People (and me) 'complain' about, compiling a project with USB HAL drivers with highest optimization (GCC with -O3) does not work. You had to fall back to -O2.
Sure, I found the reason and easy to fix:
The low-level driver, file 'stm32h7xx_ll_usb.c' has a lot of missing volatile (or __IO) definitions.
Example:
uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef *USBx)
{
uint32_t tmpreg;
tmpreg = USBx->GINTSTS;
tmpreg &= USBx->GINTMSK;
return tmpreg;
}
'tmpreg' is used on an USB peripheral register which are properly defined as __IO (volatile).
The variables used on such __IO registers should be also defined as __IO.
Or: make sure on loops where the 'count' is used, it is also a volatile (otherwise a loop could be optimized to nothing by compiler if such variable is not used, actually).
Example:
static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
{
uint32_t count = 0U;
/* Wait for AHB master IDLE state. */
do
{
if (++count > 200000U)
{
return HAL_TIMEOUT;
}
}
So, I have added on several places the volatile as additional declaration, e.g.:
uint32_t USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
{
uint32_t USBx_BASE = (uint32_t)USBx;
volatile uint32_t tmpreg, msk, emp;
msk = USBx_DEVICE->DIEPMSK;
emp = USBx_DEVICE->DIEPEMPMSK;
msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
return tmpreg;
}
So, check all these 'tmpreg' variables and add volatile to it (where it is used on an __IO registers).
BTW:
There is also one tmpreg defined as static, w/o any need to do so:
HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)
{
uint32_t USBx_BASE = (uint32_t)USBx;
uint32_t ch_num = (uint32_t)hc->ch_num;
/*static*/ __IO uint32_t tmpreg = 0U;
Also check if count variables used in 'empty' waiting loops should be augmented with volatile.
After these changes - I can compile and run with optimization level -O3.
I have attached here my modified USB LL drivers for STM32H7xx.
