问题描述
我正在开发 Silabs ARm Cortex M3 (EFM32PG12)
我想在堆和堆栈之间声明一个链接器部分 XXX,在那里放置一个变量,稍后查看(硬件故障主题)是否该变量变脏。
.heap (copY):
{
__HeapBase = .;
__end__ = .;
end = __end__;
_end = __end__;
KEEP(*(.heaP*))
__HeapLimit = .;
} > RAM
.xxx (NOLOAD): /* my DEBUG section */
{
. = ALIGN(4);
__xxx_start__ = .;
KEEP(*(.xxx*))
__xxx_end__ = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections,and assign
* values to stack symbols later */
.stack_dummy (copY):
{
KEEP(*(.stack*))
} > RAM
/* Set stack top to end of RAM,and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit,"region RAM overflowed with stack")
/* Check if FLASH usage exceeds FLASH size */
ASSERT( LENGTH(FLASH) >= (__etext + SIZEOF(.data)),"FLASH memory overflowed !")
现在在我的代码中,我声明了这样的变量
__attribute__((section(".xxx"))) volatile uint32_t dirtyvar = 0x12345678;
*(COMMON)
COMMON 0x20000c7c 0x6004 ./src/dbg_malloc.o
0x20000c7c dbgMallocData
COMMON 0x20006c80 0x4 ./src/drv_uart.o
0x20006c80 frames
COMMON 0x20006c84 0x4 ./src/error.o
0x20006c84 __stack_chk_guard
COMMON 0x20006c88 0x4 c:/siliconlabs/simplicitystudio/v5/developer/toolchains/gnu_arm/7.2_2017q4/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/softfp\libc_nano.a(lib_a-reent.o)
0x20006c88 errno
0x20006c8c . = ALIGN (0x4)
0x20006c8c __bss_end__ = .
.heap 0x20006c90 0x2000
0x20006c90 __HeapBase = .
0x20006c90 __end__ = .
0x20006c90 end = __end__
0x20006c90 _end = __end__
*(.heaP*)
.heap 0x20006c90 0x2000 ./CMSIS/EFM32PG12B/startup_gcc_efm32pg12b.o
0x20008c90 __HeapLimit = .
.xxx 0x20006c8c 0x4 load address 0x00009b88
0x20006c8c . = ALIGN (0x4)
0x20006c8c __xxx_start__ = .
*(.xxx*)
.xxx 0x20006c8c 0x4 ./src/error.o
0x20006c8c dirtyvar
0x20006c90 __xxx_end__ = .
.stack_dummy 0x20006c90 0x80
*(.stack*)
.stack 0x20006c90 0x80 ./CMSIS/EFM32PG12B/startup_gcc_efm32pg12b.o
0x20040000 __StackTop = (ORIGIN (RAM) + LENGTH (RAM))
0x2003ff80 __StackLimit = (__StackTop - SIZEOF (.stack_dummy))
0x20040000 PROVIDE (__stack,__StackTop)
0x00000001 ASSERT ((__StackLimit >= __HeapLimit),region RAM overflowed with stack)
0x00000001 ASSERT ((LENGTH (FLASH) >= (__etext + SIZEOF (.data))),FLASH memory overflowed !)
OUTPUT(5GNR_EFM32.axf elf32-littlearm)
如何正确声明这个区域,以便我可以在崩溃时看到 HEAP 是否损坏了我的堆栈?
我尽我所能:
- 我为 malloc/free 编写了一个包装器,它按预期工作
- 我用 -fstack-protector-all 编译,这里似乎一切正常
- 我试图写一个像这样的 HARD FAULT 处理程序,但 CFSR 的内容完全无关
void debugHardfault(uint32_t *sp)
{
uint32_t cfsr = SCB->CFSR;
uint32_t hfsr = SCB->HFSR;
uint32_t mmfar = SCB->MMFAR;
uint32_t bfar = SCB->BFAR;
uint32_t r0 = sp[0];
uint32_t r1 = sp[1];
uint32_t r2 = sp[2];
uint32_t r3 = sp[3];
uint32_t r12 = sp[4];
uint32_t lr = sp[5];
uint32_t pc = sp[6];
uint32_t psr = sp[7];
printf("HardFault:\n");
printf("SCB->CFSR 0x%08lx\n",cfsr);
/*
* HFSR
* 0x1b4b09b3
*
*
* 00011011 01001011 00001001 10110011
*
*/
printf("SCB->HFSR 0x%08lx\n",hfsr);
printf("SCB->MMFAR 0x%08lx\n",mmfar);
printf("SCB->BFAR 0x%08lx\n",bfar);
printf("\n");
printf("SP 0x%08lx\n",(uint32_t)sp);
printf("R0 0x%08lx\n",r0);
printf("R1 0x%08lx\n",r1);
printf("R2 0x%08lx\n",r2);
printf("R3 0x%08lx\n",r3);
printf("R12 0x%08lx\n",r12);
printf("LR 0x%08lx\n",lr);
printf("PC 0x%08lx\n",pc);
printf("PSR 0x%08lx\n",psr);
while(1);
}
注意: 当我使用 -O3 编译时,这个错误会更频繁(仍然是随机的)。
我提到的另一个问题是 malloc() 永远不会像我有无限堆那样返回 NULL,所以这就是我怀疑堆栈溢出的原因。
先谢谢你,
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)