2025-11-19 1:43 PM
I'm in the middle of attempting to reconfigure the clock tree on my STM32F303K8. The old clock tree looks like
The new clock tree looks like
The old clock tree works fine. The new clock tree always fails on boot; not always in the same address but always in the neighbourhood of HAL_RCC_ClockConfig. An example stack trace looks like
In this case it claims to have failed on this line 769 of HAL_RCC_ClockConfig:
/* Get Start Tick */
tickstart = HAL_GetTick();This is failing in the MX-generated code well before any of my own code runs. The goal is to keep the CPU clock at 64 MHz but reduce everything after the AHB prescaler. The diff of the RCC section in the .ioc file looks like this:
Solved! Go to Solution.
2025-11-20 9:48 AM - edited 2025-11-20 9:52 AM
The reference manual would be the correct place to look for that info.
HCLK of 4 MHz doesn't require wait states.
> The goal is to keep the CPU clock at 64 MHz but reduce everything after the AHB prescaler.
Not entirely sure where the cortex clock is here.
RM says that HCLK is the Cortex clock which aligns with the RMs specifications on wait states.
Changing wait states to 2 suggests this may be incorrect, but the RM is typically the best source of info.
2025-11-19 3:45 PM
It looks like the vector table offset isn't set correctly.
Ensure USER_VECT_TAB_ADDRESS is #defined in the HAL configuration file, or that SCB->VTOR is otherwise being set correctly.
You could set __disable_irq() at the start of main() and see if it finishes, which would verify the above.
2025-11-19 4:40 PM
I will try that, but... why would only changing the clock tree corrupt the vector table offset? That's quite strange.
2025-11-20 8:21 AM
@TDK wrote:Ensure USER_VECT_TAB_ADDRESS is #defined in the HAL configuration file
In Core/Src/system_stm32f3xx.c I see
/* Note: Following vector table addresses must be defined in line with linker
configuration. */
/*!< Uncomment the following line if you need to relocate the vector table
anywhere in Flash or Sram, else the vector table is kept at the automatic
remap of boot address selected */
/* #define USER_VECT_TAB_ADDRESS */
#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */But that doesn't change between the old and new versions, and neither version has any other mention of USER_VECT_TAB_ADDRESS. Since the old one was working, I don't have much choice but to assume that that isn't the issue.
or that SCB->VTOR is otherwise being set correctly.
In the functioning case, VTOR is 0. In the malfunctioning case it is also 0.
If I step through, it's this line that seems to smash the stack:
if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
2025-11-20 8:28 AM
@TDK wrote:You could set __disable_irq() at the start of main() and see if it finishes, which would verify the above.
This does not seem to have changed the behaviour.
2025-11-20 8:36 AM
Okay so probably not that.
Not real sure, but what I would do is look at the RCC clock settings at the register level after or as they are set by HAL_RCC_ClockConfig and validate those against what is allowed per the reference manual. Perhaps look just prior to the system clock being changed at __HAL_RCC_SYSCLK_CONFIG.
Consider looking into the reason for the hard fault. STM32CubeIDE has a hard fault analyzer. Window -> Show View -> Fault Analyzer. Probably going to see an IMPRECISE_ERR which is hard to pin down but is usually something fundamentally wrong with the clock settings. Occasionally due to a power issue but if you're reducing the clock I doubt that's the case here.
2025-11-20 9:24 AM
The only other suspicious thing I saw was that MX modified this parameter:
FLASH_LATENCY_2
to
FLASH_LATENCY_0
2025-11-20 9:36 AM - edited 2025-11-20 9:48 AM
Right, so manually reverting FLASH_LATENCY_0 to FLASH_LATENCY_2 fixes the issue. Searching the internet for this symbol didn't turn up much. I wonder what's going on here. FLASH_LATENCY_1 also succeeds.
MX even has a field for this, but it's disabled:
2025-11-20 9:48 AM - edited 2025-11-20 9:52 AM
The reference manual would be the correct place to look for that info.
HCLK of 4 MHz doesn't require wait states.
> The goal is to keep the CPU clock at 64 MHz but reduce everything after the AHB prescaler.
Not entirely sure where the cortex clock is here.
RM says that HCLK is the Cortex clock which aligns with the RMs specifications on wait states.
Changing wait states to 2 suggests this may be incorrect, but the RM is typically the best source of info.
2025-11-20 10:23 AM
@TDK wrote:> The goal is to keep the CPU clock at 64 MHz but reduce everything after the AHB prescaler.
Not entirely sure where the cortex clock is here.
RM says that HCLK is the Cortex clock which aligns with the RMs specifications on wait states.
Sigh. Yep. Back to 64 MHz, then...