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

Global Variables are not being initialized

I am switching from using GNU ARM toolchain to using the ARM DS-5 compiler toolchain. The microcontroller I am programming has flash memory starting at 0x08000000, and RAM starting at 0x20000000. My application contains a main() function that just increments a global variable. I set the initial value of the global variable to 0xaa, however it seems that the scatterload function does not copy the initial value to the variable's execution address. When I debug the code the initial value is 0xFFFFFFFF(the default value of the flash memory). I think what is happening is that the scatterload function is accessing where the initial value should have been in flash and copying it to RAM. The problem is that the data was not loaded to the flash. When I print out the map of the elf file, I see the variable in the .data.var section.

Here is what my scatter file looks like:

LOAD_ROM_1 0x08000000 0x100000 {

  FLASH 0x08000000 {
    startup_stm32l476xx.o (RESET, +FIRST)
    * (InRoot$$Sections)
    .ANY (+RO)
  }

  SRAM1 0x20000000 0x18000 {
    .ANY (+RW, +ZI)
  }

}

I am debugging my code using arm gdb from the GNU toolchain. One think that looks odd to me is when I load the program it displays:

(gdb) load
Loading section FLASH, size 0x5a8 lma 0x8000000
Loading section SRAM1, size 0x8 lma 0x20000000
Start address 0x8000188, load size 1456
Transfer rate: 6 KB/sec, 728 bytes/write.
(gdb)

It seems like the SRAM region is being loaded directly to the microcontroller RAM. I intended it to be loaded into flash after the read-only memory and then be copied into RAM by the scatterload function.

There seems to be something I don't understand about the scatterloading process. Anyone else see what I am doing wrong?

Thanks

Parents
  • Thanks for your help,

    I am able to step through __main, and it branches to __scatterload_rt2 and then branches to __rt_entry_sh. Eventually __main calls main(), however when I print out the value of my global variable it has not been initialized to the value I set but is instead set to 0xFFFFFFFF.

    So my understanding is...
    Everything in the load region (LOAD_ROM_1 in my case) is loaded at 0x08000000. Then when the program is run, every execution region with a different address from the load address is copied to its execution address. So in my case SRAM1 is copied from where it was loaded in flash to its execution address(0x20000000). Is this understanding correct?

    What seems to be actually happening is a little different, it seems that the SRAM1 section is being loaded to (0x20000000).

    Here are the first three sections listed fromelf:

    ** Section #1 'FLASH' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
        Size   : 1448 bytes (alignment 4)
        Address: 0x08000000
    
    
    ** Section #2 'SRAM1' (SHT_PROGBITS) [SHF_ALLOC + SHF_WRITE]
        Size   : 8 bytes (alignment 8)
        Address: 0x20000000
    
    
    ** Section #3 'SRAM1' (SHT_NOBITS) [SHF_ALLOC + SHF_WRITE]
        Size   : 1632 bytes (alignment 8)
        Address: 0x20000008
    

    Also I think I should clarify, I am not using the entire DS-5 development studio, I am only using the ARM Compiler toolchain that it uses(ARMCompiler6.6). Couldn't figure out how to edit my post so the tag is a bit misleading. For now I am just trying to get something simple working using cmake.

Reply
  • Thanks for your help,

    I am able to step through __main, and it branches to __scatterload_rt2 and then branches to __rt_entry_sh. Eventually __main calls main(), however when I print out the value of my global variable it has not been initialized to the value I set but is instead set to 0xFFFFFFFF.

    So my understanding is...
    Everything in the load region (LOAD_ROM_1 in my case) is loaded at 0x08000000. Then when the program is run, every execution region with a different address from the load address is copied to its execution address. So in my case SRAM1 is copied from where it was loaded in flash to its execution address(0x20000000). Is this understanding correct?

    What seems to be actually happening is a little different, it seems that the SRAM1 section is being loaded to (0x20000000).

    Here are the first three sections listed fromelf:

    ** Section #1 'FLASH' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
        Size   : 1448 bytes (alignment 4)
        Address: 0x08000000
    
    
    ** Section #2 'SRAM1' (SHT_PROGBITS) [SHF_ALLOC + SHF_WRITE]
        Size   : 8 bytes (alignment 8)
        Address: 0x20000000
    
    
    ** Section #3 'SRAM1' (SHT_NOBITS) [SHF_ALLOC + SHF_WRITE]
        Size   : 1632 bytes (alignment 8)
        Address: 0x20000008
    

    Also I think I should clarify, I am not using the entire DS-5 development studio, I am only using the ARM Compiler toolchain that it uses(ARMCompiler6.6). Couldn't figure out how to edit my post so the tag is a bit misleading. For now I am just trying to get something simple working using cmake.

Children
  • Running objdump on the elf file clears things up a little for me..

    ubuntu@ubuntu-xenial:~/clang_test/build$ arm-none-eabi-objdump -h HARDWARE_TESTS.elf
    
    HARDWARE_TESTS.elf:     file format elf32-littlearm
    
    Sections:
    Idx Name          Size      VMA       LMA       File off  Algn
      0 FLASH         000005a8  08000000  08000000  00000038  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, CODE
      1 SRAM1         00000008  20000000  20000000  000005e0  2**3
                      CONTENTS, ALLOC, LOAD, DATA
      2 SRAM1         00000660  20000008  20000008  000005e8  2**3
                      ALLOC
      3 .debug_abbrev 00000151  00000000  00000000  000005e8  2**0
                      CONTENTS, READONLY, DEBUGGING
      4 .debug_frame  000004d4  00000000  00000000  00000739  2**0
                      CONTENTS, READONLY, DEBUGGING
      5 .debug_info   0000055e  00000000  00000000  00000c0d  2**0
                      CONTENTS, READONLY, DEBUGGING
      6 .debug_line   000002cd  00000000  00000000  0000116b  2**0
                      CONTENTS, READONLY, DEBUGGING
      7 .debug_pubnames 000000ba  00000000  00000000  00001438  2**0
                      CONTENTS, READONLY, DEBUGGING
      8 .debug_pubtypes 0000008e  00000000  00000000  000014f2  2**0
                      CONTENTS, READONLY, DEBUGGING
      9 .debug_str    000003a2  00000000  00000000  00001580  2**0
                      CONTENTS, READONLY, DEBUGGING
     10 .debug_ranges 00000030  00000000  00000000  00001922  2**0
                      CONTENTS, READONLY, DEBUGGING
     11 .note         0000001c  00000000  00000000  0000439c  2**2
                      CONTENTS, READONLY
     12 .comment      00000344  00000000  00000000  000043b8  2**0
                      CONTENTS, READONLY
    
    

    When my program is linked SRAM1 region is given load address 0x20000000. What I want is VMA to be 0x20000000 and LMA to be 0x08000000+(some offset). Not sure why this is happening though. Are there any other parameters I need to pass to the linker other than --scatter file?