I try to use linker-generated region symbols to programmatically obtain the size of flash memory consumed by my app. When I compile it, compiler gives me this:
Program Size: Code=11688 RO-data=576 RW-data=28 ZI-data=6068
So I figure out that used flash size is Code+Ro = 11688 + 576 = 12264 bytes.
Then I write this code to obtaint this size programmatically:
extern unsigned int Image$$ER_IROM1$$Length; static const uint32_t size_bytes = (uint32_t) &(Image$$ER_IROM1$$Length);
However this variable is equal to 11892 (0x2E74) which is less then shown by compiler output. I then go and obtain linker symbol Image$$ER_IROM1$$Limit and it's equal to 0x08002E74. My flash memory begins at 0x08000000 so it also shows less used memory.
I then go and check memory window and I see that there is some non-zero values beyond address 0x08002E74 so I guess linker is indeed wrong here.
I use this (generated by Keil) scatter file:
LR_IROM1 0x08000000 0x00030000 { ; load region size_region ER_IROM1 0x08000000 0x00030000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 0x00007000 { ; RW data .ANY (+RW +ZI) } RW_IRAM2 0x20007000 0x00001000 { MDR32F9Qx_eeprom.o (+RO) .ANY (+RW +ZI) } }
What am I doing wrong? How can I obtain the correct size of used flash?
What size is the LOAD REGION? Image$$LR_IROM1$$Length;
When I try to use Load Region length as
extern unsigned int Image$$LR_IROM1$$Length;
I get linker error: Error: L6218E: Undefined symbol Image$$LR_IROM1$$Length (referred from main.o).
After a lot of googling I was able to obtain the correct name for that symbol and it does show correct size of used flash (code + rw data + padding + linker veneers + god knows what else):
Load$$LR$$LR_IROM1$$Length
This gave me 0x3004 == 12 292, which, suprisingly, is bigger then the sum of compiler's output 'code' and 'ro-data' but according to memory window is indeed the smallest address where 0xFF are located. I presume that compiler doesn't mention linker veneers and padding in the compile output.
I still have no idea how that name is formed, why there is no Load$$LR_IROM1$$Length. Documentation (http://www.keil.com/support/man/docs/armlink/armlink_pge1362065951979.htm) is quite breif at that.
This is a slightly different symbol than a standard load execution region symbols
What you described is a load region symbol Load$$LR$$... :
www.keil.com/.../armlink_pge1362065953823.htm
The article you originally linked to was for **execution region** symbols.
The **load region** or (load view) is the power-on view of the device, i.e. the layout of your memory before the scatterloader has zero-initialized you stack, copied initialized variables into ram.
The **Execution region** or (Execution view) is the memory layout when your main() is running, everything is ready to execute. See:
www.keil.com/.../armlink_pge1362065902090.htm
Hope that helps.