记一次STM32H503冷启动后进入HardFult_Handler的问题
发布时间:2026/9/29 9:50:55来源:尧图网络
文章目录前言问题发现问题处理后记前言最近一个板子用了STM32H503KBU6芯片刚用就发现个问题这个芯片通过调试器调试可以正常工作但是下电后再冷启动程序就无法正常工作了。最后测试发现这个问题还是稍微有些偏门的主要原因是使用官方工具生成的代码直接就有问题。问题发现需要说明的是我这里用的是LL库HAL库不一定存在这个问题。接上调试器关闭调试复位芯片选项可以查看到芯片进入了HardFult_Handler问题出在MX_USART2_UART_Init但是实际上去查看或者调试MX_USART2_UART_Init是没有问题的这个问题只出现在冷启动的时候。后来发现问题其实在上面一行MX_RTC_Init。这个函数中在冷启动时会去复位backup域这个动作会清除SRAM2默认情况下编译出来的栈是在SRAM2上的前面的MX_GPIO_Init()把GPIOB0x42020400缓存在[SP4]约为0x20007E94。Backup Domain reset将其清零。随后UART初始化从[SP4]取出r00访问[r0 8]即0x00000008最终进入HardFault。问题处理发现问题处理起来就比较简单了只要把栈内存定位到SRAM1上就行我这里选择修改链接脚本STM32H503xx_FLASH.ld来实现相关调整。把原本的RAM中的SRAM2单独拆分出来这样后面栈就被定位到了SRAM1上/* Memories definition */ MEMORY{/* RAM(xrw):ORIGIN0x20000000, LENGTH32K */ RAM(xrw):ORIGIN0x20000000, LENGTH16K SRAM2(xrw):ORIGIN0x20004000, LENGTH16K /* BOOT: FLASH(rx):ORIGIN0x08000000, LENGTH56K */ /* APP:FLASH(rx):ORIGIN0x08010000, LENGTH56K */ FLASH(rx):ORIGIN0x08000000, LENGTH56K}/* Highest address of the user mode stack */ _estackORIGIN(RAM) LENGTH(RAM);/* end ofRAMRamtypememory */ _sstack_estack - _Min_Stack_Size;这个修改虽然处理好了栈的部分但是需要使用SRAM2时就需要设置段然后手动将数据定位到该段上来使用了.sram2_bss(NOLOAD):{.ALIGN(4);__sram2_bss_start__.;KEEP(*(.sram2_bss))KEEP(*(.sram2_bss.*)).ALIGN(4);__sram2_bss_end__.;}SRAM2使用时可以用下面方式定位__attribute__((section(.sram2_bss),aligned(sizeof(8))))staticuint8_tmem_pool_buf[8192]{0};需要注意的是这里定义的sram2_bss这个段的内存可能需要手动清零才保险可以在MX_RTC_Init后最初使用前使用下面代码来清零externuint8_t__sram2_bss_start__[];externuint8_t__sram2_bss_end__[];size_tsize(uintptr_t)__sram2_bss_end__-(uintptr_t)__sram2_bss_start__;memset(__sram2_bss_start__,0,size);完整的链接脚本如下/* ****************************************************************************** ** ** file:LinkerScript.ld ** ** author:Auto-generated by STM32CubeIDE ** ** brief:Linker scriptforSTM32H503xx Device from STM32H5 series ** 128Kbytes FLASH ** 32Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and sizeifexternal memory is used ** ** Target:STMicroelectronics STM32 ** ** Distribution: Thefileis distributed as is, without any warranty ** of any kind. ** ****************************************************************************** ** attention ** ** Copyright(c)2023STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be foundinthe LICENSEfile**inthe root directory of this software component. ** If no LICENSEfilecomes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler)/* Memories definition */ MEMORY{/* RAM(xrw):ORIGIN0x20000000, LENGTH32K */ RAM(xrw):ORIGIN0x20000000, LENGTH16K SRAM2(xrw):ORIGIN0x20004000, LENGTH16K /* BOOT: FLASH(rx):ORIGIN0x08000000, LENGTH56K */ /* APP:FLASH(rx):ORIGIN0x08010000, LENGTH56K */ FLASH(rx):ORIGIN0x08000000, LENGTH56K}/* Highest address of the user mode stack */ _estackORIGIN(RAM) LENGTH(RAM);/* end ofRAMRamtypememory */ _sstack_estack - _Min_Stack_Size;_Min_Heap_Size0x400;/* required amount of heap */ _Min_Stack_Size0x800;/* required amount of stack */ /* Sections */ SECTIONS{/* The startup code intoFLASHRomtypememory */ .isr_vector:{.ALIGN(4);KEEP(*(.isr_vector))/* Startup code */.ALIGN(4);}FLASH /* The program code and other data intoFLASHRomtypememory */ .text:{.ALIGN(4);*(.text)/* .text sections(code)*/ *(.text*)/* .text* sections(code)*/ *(.glue_7)/* glue arm to thumb code */ *(.glue_7t)/* glue thumb to arm code */ *(.eh_frame)KEEP(*(.init))KEEP(*(.fini)).ALIGN(4);_etext.;/* define a global symbols at end of code */}FLASH /* Constant data intoFLASHRomtypememory */ .rodata:{.ALIGN(4);*(.rodata)/* .rodata sections(constants, strings, etc.)*/ *(.rodata*)/* .rodata* sections(constants, strings, etc.)*/.ALIGN(4);}FLASH .ARM.extab(READONLY):/* The READONLY keyword is only supportedinGCC11 and later, remove itifusing GCC10 or earlier. */{.ALIGN(4);*(.ARM.extab* .gnu.linkonce.armextab.*).ALIGN(4);}FLASH .ARM(READONLY):/* The READONLY keyword is only supportedinGCC11 and later, remove itifusing GCC10 or earlier. */{.ALIGN(4);__exidx_start.;*(.ARM.exidx*)__exidx_end.;.ALIGN(4);}FLASH .preinit_array(READONLY):/* The READONLY keyword is only supportedinGCC11 and later, remove itifusing GCC10 or earlier. */{.ALIGN(4);PROVIDE_HIDDEN(__preinit_array_start.);KEEP(*(.preinit_array*))PROVIDE_HIDDEN(__preinit_array_end.);.ALIGN(4);}FLASH .init_array(READONLY):/* The READONLY keyword is only supportedinGCC11 and later, remove itifusing GCC10 or earlier. */{.ALIGN(4);PROVIDE_HIDDEN(__init_array_start.);KEEP(*(SORT(.init_array.*)))KEEP(*(.init_array*))PROVIDE_HIDDEN(__init_array_end.);.ALIGN(4);}FLASH .fini_array(READONLY):/* The READONLY keyword is only supportedinGCC11 and later, remove itifusing GCC10 or earlier. */{.ALIGN(4);PROVIDE_HIDDEN(__fini_array_start.);KEEP(*(SORT(.fini_array.*)))KEEP(*(.fini_array*))PROVIDE_HIDDEN(__fini_array_end.);.ALIGN(4);}FLASH /* Used by the startup to initialize data */ _sidataLOADADDR(.data);/* Initialized data sections intoRAMRamtypememory */ .data:{.ALIGN(4);_sdata.;/* create a global symbol at data start */ *(.data)/* .data sections */ *(.data*)/* .data* sections */ *(.RamFunc)/* .RamFunc sections */ *(.RamFunc*)/* .RamFunc* sections */.ALIGN(4);}RAM ATFLASH /* Initialized TLS data section */ .tdata:ALIGN(4){*(.tdata .tdata.* .gnu.linkonce.td.*).ALIGN(4);_edata.;/* define a global symbol at data end */ PROVIDE(__data_end.);PROVIDE(__tdata_end.);}RAM ATFLASH PROVIDE(__tdata_startADDR(.tdata));PROVIDE(__tdata_size__tdata_end - __tdata_start);PROVIDE(__data_startADDR(.data));PROVIDE(__data_size__data_end - __data_start);PROVIDE(__tdata_sourceLOADADDR(.tdata));PROVIDE(__tdata_source_endLOADADDR(.tdata) SIZEOF(.tdata));PROVIDE(__tdata_source_size__tdata_source_end - __tdata_source);PROVIDE(__data_sourceLOADADDR(.data));PROVIDE(__data_source_end__tdata_source_end);PROVIDE(__data_source_size__data_source_end - __data_source);/* Uninitialized data section intoRAMRamtypememory */ /* Uninitialized TLS data section */ .tbss(NOLOAD):ALIGN(4){_sbss.;/* define a global symbol at bss start */ __bss_start___sbss;*(.tbss .tbss.*).ALIGN(4);PROVIDE(__tbss_end.);}RAM PROVIDE(__tbss_startADDR(.tbss));PROVIDE(__tbss_size__tbss_end - __tbss_start);PROVIDE(__tbss_offsetADDR(.tbss)- ADDR(.tdata));PROVIDE(__tls_base__tdata_start);PROVIDE(__tls_end__tbss_end);PROVIDE(__tls_size__tls_end - __tls_base);PROVIDE(__tls_alignMAX(ALIGNOF(.tdata), ALIGNOF(.tbss)));PROVIDE(__tls_size_align(__tls_size __tls_align -1)~(__tls_align -1));PROVIDE(__arm32_tls_tcb_offsetMAX(8, __tls_align));PROVIDE(__arm64_tls_tcb_offsetMAX(16, __tls_align));.bss(NOLOAD):ALIGN(4){/* This is used by the startupinorder to initialize the .bss section */ *(.bss)*(.bss*)*(COMMON).ALIGN(4);_ebss.;/* define a global symbol at bss end */ __bss_end___ebss;PROVIDE(__bss_end.);}RAM PROVIDE(__non_tls_bss_startADDR(.bss));PROVIDE(__bss_start__tbss_start);PROVIDE(__bss_size__bss_end - __bss_start);.sram2_bss(NOLOAD):{.ALIGN(4);__sram2_bss_start__.;KEEP(*(.sram2_bss))KEEP(*(.sram2_bss.*)).ALIGN(4);__sram2_bss_end__.;}SRAM2 /* User_heap_stack section, used to check that there is enoughRAMRamtypememory left */ ._user_heap_stack(NOLOAD):{.ALIGN(8);PROVIDE(end.);PROVIDE(_end.);.. _Min_Heap_Size;.. _Min_Stack_Size;.ALIGN(8);}RAM /* Remove information from the compiler libraries */ /DISCARD/:{libc.a:*(*)libm.a:*(*)libgcc.a:*(*)}.ARM.attributes0:{*(.ARM.attributes)}}后记不停的换平台带来的就是不停的踩坑虽然很花时间不过很多新平台在特定场合下用起来还是很不错的。
网站建设高端定制企业官网