This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Linker Region Symbols discrepancy

Hi all,

I am building a project using uVision4 on a STM32F207 based system. This uses flash segments of various lengths which I am variously dedicating to bootloader code, application code and shared configuration.

In order to manage this I am using a scatter file containing the following info

LR_IROM2 0x0800C000 0x4000  {    ; load region size_region
  FLASHCFG 0x800C000 0x400 {
        *(.flashcfg)
  }
  APPCFG 0x800C400 0x400 {
        *(.appcfg)
  }
}

and code containing constructs such as

const S_APP_CONFIG msAppConfig __attribute__((used)) __attribute__((section(".appcfg")))

where S_APP_CONFIG is a data structure contains the various configuration.

So I have two configuration areas, up to 0x400 bytes long each, in one flash segment. In order to manage this effectively I need to know the actual extent of the used memory as although the segment is 0x4000 long, each config area may only be a handful of bytes long so when updating I only want to do what is necessary and not rewrite the whole 16k segment.

Looking through the manuals I discovered the the load and execution region symbols and thought there would be ideal to reference the location and size of these areas from the code. I have defined the following symbols in the code.

extern uint8_t  Load$$LR$$LR_IROM2$$Base[]; // Address of the load region
extern size_t   Load$$LR$$LR_IROM2$$Length; // Length of the load region
extern uint8_t  Load$$LR$$LR_IROM2$$Limit[]; // Address of the byte beyond the end of the load region
extern uint8_t  Load$$FLASHCFG$$Base[]; // Address of the execution region
extern size_t   Load$$FLASHCFG$$Length; // Length of the execution region
extern uint8_t  Load$$FLASHCFG$$Limit[]; // Address of the byte beyond the end of the execution region
extern uint8_t  Load$$APPCFG$$Base[]; // Address of the execution region
extern size_t   Load$$APPCFG$$Length; // Length of the execution region
extern uint8_t  Load$$APPCFG$$Limit[]; // Address of the byte beyond the end of the execution region

I would expect the first three to relate to the load region as a whole, and the others to be specific to the exection regions. Sure enough in the map file that results from the link phase I get this in the Memory Map section.

  Load Region LR_IROM2 (Base: 0x0800c000, Size: 0x00000014, Max: 0x00004000, ABSOLUTE)

    Execution Region FLASHCFG (Base: 0x0800c000, Size: 0x00000008, Max: 0x00000400, ABSOLUTE)
    Base Addr    Size         Type   Attr      Idx    E Section Name        Object
    0x0800c000   0x00000008   Data   RW         3650    .flashcfg           flash_config.o

    Execution Region APPCFG (Base: 0x0800c400, Size: 0x0000000c, Max: 0x00000400, ABSOLUTE)
    Base Addr    Size         Type   Attr      Idx    E Section Name        Object
    0x0800c400   0x0000000a   Data   RW         3436    .appcfg             app_config.o

So I can see that the FLASHCFG and APPCFG regions are correctly located (at 0x800c000 and 0x800c400 respectively) and sized (8 and 12 bytes). So it looks like it's all going to work!

However when I try and use the defined symbols programmatically I run into a problem. Putting their values out on debug I can see this

LR_IROM2 BASE:0800c000 -> LIMIT:0800c014 LENGTH:20
FLASHCFG BASE:0800c000 -> LIMIT:0800c008 LENGTH:8
APPCFG   BASE:0800c008 -> LIMIT:0800c014 LENGTH:12

Although the map file has correctly positioned the regions, the actual values assigned to the related symbols assume they are just contiguous and APPCFG has been placed at 0x0800c008 instead of 0x0800c400 and the length of the LR_IROM2 region is listed as 20 bytes and not 0x40c (0x400 offset plus 0xc length).

Having a further delve into the map file I can see the symbols listed with the following addresses/values in the Global Symbols section.

    Load$$LR$$LR_IROM2$$Base                 0x0800c000   Number         0  anon$$obj.o ABSOLUTE
    Load$$LR$$LR_IROM2$$Limit                0x0800c014   Number         0  anon$$obj.o ABSOLUTE
    Load$$LR$$LR_IROM2$$Length               0x00000014   Number         0  anon$$obj.o ABSOLUTE
    Load$$FLASHCFG$$Base                     0x0800c000   Number         0  anon$$obj.o ABSOLUTE
    Load$$FLASHCFG$$Limit                    0x0800c008   Number         0  anon$$obj.o ABSOLUTE
    Load$$FLASHCFG$$Length                   0x00000008   Number         0  anon$$obj.o ABSOLUTE
    Load$$APPCFG$$Base                       0x0800c008   Number         0  anon$$obj.o ABSOLUTE
    Load$$APPCFG$$Limit                      0x0800c014   Number         0  anon$$obj.o ABSOLUTE
    Load$$APPCFG$$Length                     0x0000000c   Number         0  anon$$obj.o ABSOLUTE

From this it appears that the linker map file is itself confused about where these symbols are and their dimensions.

It is, of course, possible that I have misunderstood the whole concept but otherwise is anyone able to explain what is going on here and how I can actually determine the real location and dimensions of those symbols?

Regards

Philip Coombes