Hi,
Can anyone tell me how my code can know what size the image is in FLASH ? Is there a symbol that I can reference that shows how much space the image occupies ?
I know this information is obvious from the generated .HEX file (and it may be possible to work it out from the .MAP file). I currently have to post-process the .HEX file and patch it (updating the relevant line's checksum accordingly).
Surely there is an easier way to do this !
Note that I'm not looking for the size of the CODE segment, just the overall image size.
Any ideas ?
Thanks,
David.
The linker scatter file which defines memory layout (regions and export symbols) can be quite complex and is indented for advanced users which need special features. uVision takes out the complexity and handles this automatically with auto generated scatter file.
From your listing of linker symbols I guess the following scatter file was used:
LR_IROM1 0x00005000 ???(size) { ER_IROM1 0x00005000 ???(size) { *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x40000060 ???(size) { .ANY (+RW +ZI) } }
IROM1 has no RW/ZI regions and therefore the length of those regions is 0.
When you look at the generated map file you should see something like:
Load Region LR_IROM1 (Base:0x00005000, Size:0x00006254 Execution Region ER_IROM1 (Base: 0x00005000, Size: 0x000059ec Execution Region RW_IRAM1 (Base: 0x40000060, Size: 0x00000a80
Flash Image Size covers the code and constants (IROM1) and values for non-zero initialized variables (RW from IRAM1) and is Image$$ER_IROM1$$Length + Image$$RW_IRAM1$$RW$$Length.
This applies only when RW data is not compressed. If it is compressed (search for COMPRESSED in the map file) then the image will be smaller and I believe that there is no linker symbol which gives this information (last time I checked).
If you want to protect the image with CRC you can still do this even if RW data is compressed by padding the remaining area with known values or for example make sure that the unused Flash was erased (value 0xFF).
Hi Robert,
Once again, thanks for your assistance - we're definitely getting closer.
Out of interest, do you work for Keil ? If not, where are you getting this information from ? The online help just doesn't seem (at least to me) to explain this properly.
The example you gave has allowed me to get at the IRAM1 linker symbols, but I'm still not getting the numbers that I need. Your example appears to add the FLASH Code size to the RAM data size. I'm trying to determine the "actual" number of bytes occupied in FLASH by the entire downloaded image. This is probably something like the sum of the RO code and the compressed R/W and ZI data.
Perhaps it would help if I explained a bit more about what I am trying to achieve :-
I have a USB-capable BootLoader and a separate downloadable application. The BootLoader has to perform (among other checks) a CRC validation on the application before running it. In order to calculate the CRC, it needs to know both the location and the size of the application image. The location isn't a problem. At the moment I post-process the application HEX file, and insert the size at a known offset from the start of the image, before downloading the patched image to FLASH. I want to be able to build that size information into the image directly, using information that should be available from the linker. I'm not looking for the amount of RAM the application uses, or the expanded size of any ZI regions; I just need the actual size (in bytes) of the application image as stored in FLASH.
Do you know how I can achieve this ?
The current values from my application image are as follows :-
Load$$ER_IROM1$$Base = 0x00005000 Image$$ER_IROM1$$Base = 0x00005000 Image$$ER_IROM1$$Length = 0x000059EC Image$$ER_IROM1$$Limit = 0x0000A9EC Image$$ER_IROM1$$RO$$Base = 0x00005000 Image$$ER_IROM1$$RO$$Base = 0x00005000 Image$$ER_IROM1$$RO$$Length = 0x000059EC Image$$ER_IROM1$$RO$$Limit = 0x0000A9EC Image$$ER_IROM1$$RW$$Base = 0x0000A9EC Image$$ER_IROM1$$RW$$Length = 0x00000000 Image$$ER_IROM1$$RW$$Limit = 0x0000A9EC Image$$ER_IROM1$$ZI$$Base = 0x0000A9EC Image$$ER_IROM1$$ZI$$Length = 0x00000000 Image$$ER_IROM1$$ZI$$Limit = 0x0000A9EC Load$$RW_IRAM1$$Base = 0x0000A9EC Image$$RW_IRAM1$$Base = 0x40000060 Image$$RW_IRAM1$$Length = 0x00000868 Image$$RW_IRAM1$$Limit = 0x400008C8 Image$$RW_IRAM1$$RO$$Base = 0x40000060 Image$$RW_IRAM1$$RO$$Base = 0x40000060 Image$$RW_IRAM1$$RO$$Length = 0x00000000 Image$$RW_IRAM1$$RO$$Limit = 0x40000060 Image$$RW_IRAM1$$RW$$Base = 0x40000060 Image$$RW_IRAM1$$RW$$Length = 0x00000868 Image$$RW_IRAM1$$RW$$Limit = 0x400008C8 Image$$RW_IRAM1$$ZI$$Base = 0x400008C8 Image$$RW_IRAM1$$ZI$$Length = 0x00000218 Image$$RW_IRAM1$$ZI$$Limit = 0x40000AE0
I don't understand why the IROM1 RW and ZI regions both show as having lengths of 0. Surely these should show the compressed sizes of the RW and ZI regions respectively. Can you explain this ?
Thanks again,
The complete image size in this case is the size of Flash execution region plus the size of RAM R/W region (non-zero initialized variables).
Total_Flash_Load_Image_Size = Image$$ER_IROM1$$Length + Image$$RW_IRAM1$$RW$$Length
The actual size can be even less when initial R/W values are compressed.
As you can see linker symbols are available also for IRAM1 (with the RW_ prefix).
Thanks Robert,
This is starting to make some sense - i just wish the documentation did :-)
As you suggest, I can access Image$$ER_IROM1$$Limit but this is NOT the end of the image; it may be the end of the code. I need to determine the actual end of the image in FLASH but cannot find the "magic incantation" to generate a valid symbol for this.
Using the ER_ROM1 region name, I can determine the following for my image :-
Load$$ER_IROM1$$Base = 0x00005000 Image$$ER_IROM1$$Base = 0x00005000 Image$$ER_IROM1$$Length = 0x000056E8 Image$$ER_IROM1$$Limit = 0x0000A6E8 Image$$ER_IROM1$$RO$$Base = 0x00005000 Image$$ER_IROM1$$RO$$Base = 0x00005000 Image$$ER_IROM1$$RO$$Length = 0x000056E8 Image$$ER_IROM1$$RO$$Limit = 0x0000A6E8 Image$$ER_IROM1$$RW$$Base = 0x0000A6E8 Image$$ER_IROM1$$RW$$Length = 0x00000000 Image$$ER_IROM1$$RW$$Limit = 0x0000A6E8 mage$$ER_IROM1$$ZI$$Base = 0x0000A6E8 Image$$ER_IROM1$$ZI$$Length = 0x00000000 Image$$ER_IROM1$$ZI$$Limit = 0x0000A6E8
However, the image in FLASH continues to 0x0000A783. I presume the extra is the ZI region which is expanded at startup, but the symbols above seem to indicate otherwise.
Incidentally, are there similar symbols for the "IRAM1" region name ? Substituting "IRAM1" for "IROM1" in the above symbol names does not work !
Can you (or anyone) suggest the correct symbol name for the end of the image when not using a custom scatter file ?
I know I could find this address by scanning backwards through FLASH, but this should not be needed.
Thanks for your help,
The symbol names depend on the definitions in the Linker Scatter file.
When using the automated way in uVision (Linker Option "Use Memory Layout from Target Dialog" is checked) the memory regions which are defined under settings for Target Dialog are used.
For example if IROM1 is used then symbols like "Image$$ER_IROM1$$Length" are available.
The definition in C would be: extern unsigned int Image$$ER_IROM1$$Length;
Reinhard,
Using the sample code at http://www.keil.com/support/man/docs/armlink/armlink_chdcceee.htm results in the following error :-
.\Debug\test.axf: Error: L6218E: Undefined symbol Image$$ZI$$Limit (referred from main.o).
Can anyone advise how to use these symbols ?
Thanks, David.
Thanks for the quick response Reinhard. I have seen this page before, but could never make any sense of it. Can you give me an example of an actual symbol name that can be referenced from within C ?
e.g. For the ZI region, should the base symbol name be :-
Image$$region_name$$ZI$$Base OR Image$$ER_ZI$$ZI$$Base OR ImageER_ZI$$ZI$$Base OR ImageER_ZIZI$$Base OR something else ?
The documentation doesn't specify how or where the actual region names (ER_RO, ER_RW & ER_ZI) are substituted into the specified symbol name templates. Does anyone else understand this page ?
If I try to use the symbol "Image$$region_name$$ZI$$Limit" from C, I get "undefined symbol" errors. Declaring it as "extern" makes no difference.
I'm just trying to determine the highest address used by the image.
The region symbols should allow you to do this. See here: www.keil.com/.../armlink_chdcgbjd.htm
View all questions in Keil forum