Extern variable seems to have two addresses?

392 views Asked by At

I am working with a library that declares a uint32_t in a .h and defines it in a .c. The program can't read the variable and crashes.

Declaration :

extern uint32_t SystemCoreClock;

Definition :

uint32_t SystemCoreClock = 4000000;

Using the variable :

uint32_t tickNum=123, *ptr1=NULL, *ptr2=NULL; // added by me to debug
ptr1 = &tickNum;                              // added by me to debug
ptr2 = &SystemCoreClock;                      // added by me to debug
tickNum = SystemCoreClock;                    // added by me to debug

Then I check the addresses with gdb.

Execute first 3 lines.

Normal stuff (ptr1 == &ticknum and *ptr1 == ticknum):

(gdb) p &tickNum
$3 = (uint32_t *) 0x20017fdc
(gdb) p ptr1
$4 = (uint32_t *) 0x20017fdc
(gdb) p *ptr1
$5 = 123

Now execute the last line of code.

Strange stuff (ptr2 != &SystemCoreClock and *ptr2 != SystemCoreClock) :

(gdb) p &SystemCoreClock
$6 = (uint32_t *) 0x20000004 <SystemCoreClock>
(gdb) p ptr2
$7 = (uint32_t *) 0x681b4b20           // should be 0x20000004, beyond end of memory (see memory map bellow)
(gdb) p SystemCoreClock
$8 = 4000000
(gdb) p *ptr2
$9 = 0                                 // should be 4000000
(gdb) p tickNum 
$10 = 0                                // should be 4000000

How can that be ?!

Memory map, my guess from the linker script :

0x20000000 - 0x20018000, LENGTH = 96K       RAM
0x10000000 - 0x10008000, LENGTH = 32K       RAM
0x08000000 - 0x08100000, LENGTH = 1024K     FLASH

Real linker script :

/* Specify the memory areas */
MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 96K
RAM2 (xrw)      : ORIGIN = 0x10000000, LENGTH = 32K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 1024K
}

  • Target : STM32L4 ARM-CortexM4 MCU
  • Host : Linux, Qt Creator, arm-none-eabi-gcc, OpenOCD
  • Versions : CubeMX v4.18.0 , STM32L4 package v1.6.0, gcc v5.4.1
0

There are 0 answers