Under certain optimization levels all works OK, but with other ones - it hangs CPU during USB enumeration.
To figure out I decided to check this on demo from the Chibios release package. Behavior was the same.
Environment:
- STM32F4Discovery
- Keil uVision MDK version 5.0 (also tested with 4.54 & 4.57 - results are the same)
- Chibios 2.6.1 release
- USB CDC example from ChibiOS_2.6.1/demos/ARMCM4-STM32F407-DISCOVERY-MEMS adapted for Keil
- Ordinary Linux host with USB 2.0, running WinXP on VirtualBox (the same behavior on other Linux & Windoze machines)
- Wireshark to capture USB traffic
- Various compiler optimization levels (see below)
Result: If optimization level is -O0 or any other but with -Otime everything works, but without -Otime system hangs as soon as USB host enumerate device. Look at the attached traffic and a wireshark screenshot.
Various cases:
-O0 - works good
-O1 - hangs
-O2 - hangs
-O3 - hangs
-O0 -Otime - works good
-O1 -Otime - works good
-O2 -Otime - works good
-O3 -Otime - works good
compiler string example (working):
-c --cpu Cortex-M4 -g -O1 -Otime --apcs=interwork -I. -I.\conf -I.\os\kernel\include -I.\os\ports\common\ARMCMx
-I.\os\ports\common\ARMCMx\CMSIS\include -I.\os\ports\RVCT\ARMCMx -I.\os\ports\RVCT\ARMCMx\STM32F4xx
-I.\os\hal\include -I.\os\hal\platforms\STM32 -I.\os\hal\platforms\STM32\GPIOv2 -I.\os\hal\platforms\STM32\OTGv1
-I.\os\hal\platforms\STM32F4xx -I.\os\various -I.\os\hal\platforms\STM32\USARTv2 -I.\os\hal\platforms\STM32\TIMv1
-I.\os\hal\platforms\STM32\SPIv2 -I.\os\various -I.\os\various\devices_lib\accel
-I C:\Keil\ARM\RV31\INC
-I C:\Keil\ARM\PACK\ARM\CMSIS\3.20.3\CMSIS\Include
-I C:\Keil\ARM\PACK\Keil\STM32F4xx_DFP\1.0.5\Device\Include
-DSTM32F40XX -D__heap_base__="Image$$RW_IRAM1$$ZI$$Limit" -D__heap_end__="Image$$RW_IRAM2$$Base" -o ".\out\*.o"
--omf_browse ".\out\*.crf" --depend ".\out\*.d"
compiler string example (not working - hang during enumeration):
-c --cpu Cortex-M4 -g -O1 --apcs=interwork -I. -I.\conf -I.\os\kernel\include -I.\os\ports\common\ARMCMx
-I.\os\ports\common\ARMCMx\CMSIS\include -I.\os\ports\RVCT\ARMCMx -I.\os\ports\RVCT\ARMCMx\STM32F4xx
-I.\os\hal\include -I.\os\hal\platforms\STM32 -I.\os\hal\platforms\STM32\GPIOv2 -I.\os\hal\platforms\STM32\OTGv1
-I.\os\hal\platforms\STM32F4xx -I.\os\various -I.\os\hal\platforms\STM32\USARTv2 -I.\os\hal\platforms\STM32\TIMv1
-I.\os\hal\platforms\STM32\SPIv2 -I.\os\various -I.\os\various\devices_lib\accel
-I C:\Keil\ARM\RV31\INC
-I C:\Keil\ARM\PACK\ARM\CMSIS\3.20.3\CMSIS\Include
-I C:\Keil\ARM\PACK\Keil\STM32F4xx_DFP\1.0.5\Device\Include
-DSTM32F40XX -D__heap_base__="Image$$RW_IRAM1$$ZI$$Limit" -D__heap_end__="Image$$RW_IRAM2$$Base" -o ".\out\*.o"
--omf_browse ".\out\*.crf" --depend ".\out\*.d"
I'm attaching complete compileable Keil project to demonstrate it.
I'm assuming some sort of a bug in usb_lld driver in which I'm hunting now. As a result of investigation I would post a patch and write an issue in bug tracker.
Would appreciate any hints where to dig.