I designed an embedded software (written in C++ and almost all C++ objects are dynamically linked using heap) targeting on MKE02 MCU(64KB Flash with 4KB SRAM), but it has a serious bug causing hard fault occasionally.
This is a bug when the code size and data size of the application software approaches its maximum, and corruptions of data structures created by "new" operator were observed before. I had to upgrade the MCU from MKE02Z32 (32KB Flash with 4KB SRAM) to MKE02Z64 (64KB Flash with 4KB SRAM) because of this bug recently, and this upgrade did solve the problem.
Unfortunately, the application size is now getting big enough to hit the bug again. In order to find a complete solution for this bug, please help me understand more about the runtime memory map of this MCU.
As shown in the snapshot (from ProcessorExpert, KDS 3.0 platform) below, the starting address of the software is 0x4600 with max code length of 0xB1F0, the code space ends at 0xFBFF, 0xFC00 - 0xFFFF is used for data storage, and 0x0 – 0x45FF is used for a bootloader designed by ourselves.
The result from compiler (with optimization level –O0) and linker is as below:
Text 42760 data 140 bss 3584 dec 46484 hex B594
The map file and linker file are attached.
The following are taken from the map file:
0x0000ef7c ___ROM_AT = .
.data 0x1ffffc00 0x68 load address 0x0000ef7c
.bss 0x1ffffc68 0x300 load address 0x0000efe4
0x1fffff80 0xb00 load address 0x0000effc
0x1fffff80 __heap_addr = .
0x1fffff80 __HeapBase = .
0x20000680 . = (. + __heap_size)
*fill* 0x1fffff80 0x700
0x20000680 __HeapLimit = .
0x20000a80 . = (. + __stack_size)
*fill* 0x20000680 0x400
0x20000c00 _estack = 0x20000c00
0x20000c00 __SP_INIT = _estack
0x20000c00 __stack = _estack
0x00000700 __heap_size = 0x700
0x00000400 __stack_size = 0x400
However, I tested the heap pointer using the code which looks like the following:
uint32_t* heapPtr = (uint32_t*) _sbrk(0);
myDebugger.Print("HeapStart = 0x%X", (uint32) heapPtr);
MyApp *myApp = new MyApp();
heapPtr = (uint32_t*) _sbrk(0);
myDebugger.Print("heapPtr = 0x%X", (uint32) heapPtr);
It prints out:
HeapStart = 0x200003B8
heapPtr = 0x20000864
based upon above information, now I have questions below:
- Why the heap addresses defined in the map file (0x1fffff80 – 0x20000680) are different from that returned by _sbrk(0) (0x200003B8 – 0x20000864)?
- Why the Stack address has different definition in the map file (0x20000a80 vs 0x20000c00) while startup.c loads 0x20000c00 into SP?
- How to safely get the stack pointer while application is running?
Thanks a lot for any replies.