2023-09-05 05:49 AM - edited 2023-09-07 04:57 AM
Hi everyone,
I recently triggered a bug in multiple projects using the same MCU STM32L151ZC. When booting the CPU I reproducibly get an assert_failed() call from HAL_RCC_OscConfig(). I created a clean project in CubeIDE to analyse the problem, which I attached. With this everyone should be able to reproduce the error. The only modifications I made to the autogenerated code are enabling the USE_FULL_ASSERT macro and forwarding all failure interrupts to Error_Handler().
Letting the code run in debug mode, triggers the assert_param() macro in stm32l1xx_hal_rcc.c line 692. This can be traced down to a wrong value (not the value thats written in the code) being written to RCC_OscInitStruct.PLL.PLLSource in SystemClock_Config(). Braking the execution before this line of code and stepping over it leads to the correct value being stored. Breaking right after this line of code leads to an 65535 being written instead of the correct value.
From what I found so far, it looks like the value of the line above (RCC_PLLSOURCE_HSE) gets written both to PLLState and PLLSource. When reordering the lines the double written value changes but the behaviour stays the same. I was thinking this might be a stack corruption problem and this doesn't occure, when I make the structure a global, but it don't see the SP changing and I found no IRQ to be executed... so no idea what would cause this. That the error doesn't occure while stepping in debug mode still hints to some timing problem.
Edit: I inserted HAL_Delay() calls from 1 to 100 ms between HAL_Init() and SystemClock_Config() which didn't influence the behaviour. So most likely not a timing problem...
When disabling the prefetch buffer in the CubeMX rcc settings, this also seems to make the problem disappear, but I am uncertain, whether its really gone or the simptoms are just not notable.
I am glad for every help, as I don't understand the mechanism and therefore mistrust every workaround.
Regards,
2023-09-05 06:51 AM
breakpoint in the line below RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8; so PLLMUL should be 786432:
breakpoint in line RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8; and stepping over the line in debugger, the value of PLLMUL actually is 786432:
2023-09-07 04:49 AM
I further investigated into this. With enabled prefetch buffer, some to all build configurations lead to this error. With disabled prefetch buffer (in the .ioc) but enabled 64 bit flash access mode (done automatically in HAL) I cant provoke the error to occure in any build configuration. This was reproducable in multiple projects all using firmware package "STM32Cube FW_L1 V1.10.4".
Might it be possible, that there is something wrong with the prefetch buffer and that the build settings influence at which absolut addresses the erroneous instructions land?
RM0038 recommends to first set the CPU speed and afterwards enable the prefetch buffer:
The HAL activates the prefetch buffer right at the start of main() in HAL_Init(), while the HCLK is configured in SystemClock_Config() as next call from main. Might there be a problem with the prefetch buffer, if the flash is still running at low clocks without wait states?
2023-09-22 03:50 AM - edited 2023-09-25 12:37 AM
Hello @D. Reiher
According to RM0038, the prefetch feature is useful if at least one wait state is needed to access the Flash memory.
Since the number of wait states can be adjusted in SystemClockConfig(), the prefetch should be enabled after configuring the CPU frequency. This is because the prefetch buffer is closely related to the number of wait states used for accessing the flash memory.
An internal ticket has been already submitted and tracked (161339) to add __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); after HAL_RCC_ClockConfig().
Thank you for the question and providing these details.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.