Linker Script and Assigning a value to a specific address

Hello,
I want to keep some variables in my code at certain addresses. For this, I created a new section in the LD file to reserve a certain area from the existing FLASH memory. I wait for the variable I created by typing __attribute__((section(".flash_rw.__at_0x000...))) to write to the address I specified. However, it writes the value to a completely different address in the section I created. I use arm-none-eabi-. GNU Arm Embedded Toolchain version 10 2021.10.

MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x40000 /* 256 KB ana Flash bellek */
FLASH_RW (rx) : ORIGIN = 0x00040000, LENGTH = 0x40000 /* 256 KB yazılabilir Flash bellek */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x18000 /* 96 KB RAM */
}

SECTIONS
{
    ....
    ....
    ....
    ....
    
    .flash_rw :
    {
        . = ORIGIN(FLASH_RW);
        __flash_rw_start__ = .;

        *(.flash_rw)
        *(.flash_rw.*)

        . = ALIGN(4);
        __flash_rw_end__ = .;
    } > FLASH_RW

unsigned short tristor50x35[584] __attribute__((section(".flash_rw.__at_0x0006A4CA"))) = 
{
	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x820,	0x842,	0x842,	0x842,
    ........
};

The output of the code is as follows;

Flash Address tristor50x35 => 0x00057b70

Parents
  • Looking at this thread:

    Yea, the 0x00057b70 was likely just because of automatic placement of all your "*(.flash_rw.*)" after ORIGIN(FLASH_RW). I don't know how that's determined tbh, if that is alphabetical or not, but it's best to assume it's random and then explicitly specify the sections you care about, so that they always end up in the right place.

    as I mentioned in the other thread, the __at_ is an Arm-Compiler only feature that relies on `armlink` and scatter files. With ld or lld and linker scripts this feature doesn't exit and you have to indeed do this manually in the linker script.

    Something I've never tried but might be worth trying:

    If you have a addresses.h header file, I wonder if you can use it in both C source code and in the linker script, e.g.:

    <<<< edited out, correct ones are below>>>

    Although you may need some hacky C preprocessor-concatenating...

    EDIT:::

    Yea my bad, having thought about this more, it does actually need use of the C preprocessor and it is a bit ugly!!

    addresses.h:

    #define _STRINGIFY(x) #x
    #define STRINGIFY(x) _STRINGIFY(x)
    #define _CONCATPREFIX(y) __arm_at_##y
    #define ARM_AT_ADDR(y) STRINGIFY (_CONCATPREFIX (y))
    
    #define ADDR50X35 0x0006A4CA
    << all your other addresses here >>

    In your C code:
    int __attribute__((section(ARM_AT_ADDR (ADDR50X35)))) test2 = 1 ;
    This puts "test2" into a section called "__arm_at_0x0006A4CA".

    Then in the linker script:
    .abs_thyristor ADDR50X35 : { *(ARM_AT_ADDR(ADDR50X35))}

    BUT you also need to pre
    -process the linker script:
    arm-none-eabi-gcc -E -P -x c ldscript.ld > ldscript-new.ld

    And then use ldscript-new.ld when linking... That should work at the end, but up to you if you want to adopt it, of course!!
Reply
  • Looking at this thread:

    Yea, the 0x00057b70 was likely just because of automatic placement of all your "*(.flash_rw.*)" after ORIGIN(FLASH_RW). I don't know how that's determined tbh, if that is alphabetical or not, but it's best to assume it's random and then explicitly specify the sections you care about, so that they always end up in the right place.

    as I mentioned in the other thread, the __at_ is an Arm-Compiler only feature that relies on `armlink` and scatter files. With ld or lld and linker scripts this feature doesn't exit and you have to indeed do this manually in the linker script.

    Something I've never tried but might be worth trying:

    If you have a addresses.h header file, I wonder if you can use it in both C source code and in the linker script, e.g.:

    <<<< edited out, correct ones are below>>>

    Although you may need some hacky C preprocessor-concatenating...

    EDIT:::

    Yea my bad, having thought about this more, it does actually need use of the C preprocessor and it is a bit ugly!!

    addresses.h:

    #define _STRINGIFY(x) #x
    #define STRINGIFY(x) _STRINGIFY(x)
    #define _CONCATPREFIX(y) __arm_at_##y
    #define ARM_AT_ADDR(y) STRINGIFY (_CONCATPREFIX (y))
    
    #define ADDR50X35 0x0006A4CA
    << all your other addresses here >>

    In your C code:
    int __attribute__((section(ARM_AT_ADDR (ADDR50X35)))) test2 = 1 ;
    This puts "test2" into a section called "__arm_at_0x0006A4CA".

    Then in the linker script:
    .abs_thyristor ADDR50X35 : { *(ARM_AT_ADDR(ADDR50X35))}

    BUT you also need to pre
    -process the linker script:
    arm-none-eabi-gcc -E -P -x c ldscript.ld > ldscript-new.ld

    And then use ldscript-new.ld when linking... That should work at the end, but up to you if you want to adopt it, of course!!
Children