Skip to content

Commit 8320d8f

Browse files
hathachclaude
andcommitted
fix stm32h5 hard fault when reading UID with ICACHE enabled
On STM32H5, reading UID_BASE with ICACHE enabled causes a hard fault (ST errata). Cache the unique ID at the very start of board_init(), before any user code has a chance to enable ICACHE. Closes: #3588 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7c3f597 commit 8320d8f

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

hw/bsp/stm32h5/family.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@
4646
TU_ATTR_UNUSED static void Error_Handler(void) {
4747
}
4848

49+
// STM32H5 errata: reading UID_BASE with ICACHE enabled causes hard fault.
50+
// Cache the unique ID early in board_init() before ICACHE may be enabled.
51+
static uint32_t cached_uid[3];
52+
4953
typedef struct {
5054
GPIO_TypeDef* port;
5155
GPIO_InitTypeDef pin_init;
@@ -94,6 +98,12 @@ static UART_HandleTypeDef UartHandle = {
9498
#endif
9599

96100
void board_init(void) {
101+
// Cache UID before ICACHE is enabled (STM32H5 errata: reading UID_BASE with ICACHE causes hard fault)
102+
volatile uint32_t* stm32_uuid = (volatile uint32_t*) UID_BASE;
103+
cached_uid[0] = stm32_uuid[0];
104+
cached_uid[1] = stm32_uuid[1];
105+
cached_uid[2] = stm32_uuid[2];
106+
97107
HAL_Init(); // required for HAL_RCC_Osc TODO check with freeRTOS
98108
SystemClock_Config(); // implemented in board.h
99109
SystemCoreClockUpdate();
@@ -185,13 +195,12 @@ uint32_t board_button_read(void) {
185195

186196
size_t board_get_unique_id(uint8_t id[], size_t max_len) {
187197
(void) max_len;
188-
volatile uint32_t* stm32_uuid = (volatile uint32_t*) UID_BASE;
189198
uint32_t* id32 = (uint32_t*) (uintptr_t) id;
190199
uint8_t const len = 12;
191200

192-
id32[0] = stm32_uuid[0];
193-
id32[1] = stm32_uuid[1];
194-
id32[2] = stm32_uuid[2];
201+
id32[0] = cached_uid[0];
202+
id32[1] = cached_uid[1];
203+
id32[2] = cached_uid[2];
195204

196205
return len;
197206
}

0 commit comments

Comments
 (0)