This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Obtaining the address of the last variable in RAM

Hi All

Does some one have a quick answer to finding the address of the last variable used in the system RAM?

My memory layout is .vectTable .bss, .data, .sysmem.

.vectTabel is forced to the start of SRAM and the others follow. Sometimes .sysmem is not used and the actual ordering of the area in the memory are possibly not actually defined.

There is no stack section since the stack pointer is simply set to the top of SRAM.

This means that there is space between the end of variables in the sections mentioned above and the stack pointer (minus some stack area space) which is to be used dynamically for other purposes. Therefore the first address of this space between the two is required.

Ex. With GCC I simply put a linker symbol after the other areas. With some compilers I use something like (sfe(.bss)) to get the location. The TI linker document suggests that there is an "end" symbol but this is not recognised when building for the Stellaris M3. I also tried the "." directive but this didn't help since it was always at the start of a section and there was no guaranty which would actually end up at the highest location.

Finally I can calculate the value by interpreting the CINIT table which the start-up code uses to initialise variables. But this is the last resort since it may fail if the table's content changes in new compiler version.

Any simple one line solution?

Regards

Mark

  • Have you tried using the linker END operator? Please take a look at the TMS470 Assembly Language Tools Users Guide, Section 7.5.8.7 for its usage. The operator can be associated with a output section (such as .bss, to find the load-time end address of that section), or if you need to know the end address of a group of sections, you could use the GROUP specification to specify that sections be allocated in a particular order, and then use the END operator for the group.

    This FAQ might be helpful to understand ordering of sections using the GROUP specification: http://processors.wiki.ti.com/index.php/Code_Generation_Tools_FAQ#Q:_How_can_I_get_the_linker_to_place_a_piece_of_code_or_data_so_that_it_comes_before_all_the_rest.3F

  • Many thanks!

    I didn't manage it from the linker details in the assembler user's guide (not clear enough without a couple more examples) but the FAQ seems to have done trick (much more obvious):

    SECTIONS
    {
        .vectors:   > 0x00000000
        .text   :   > FLASH
        .const  :   > FLASH
        .cinit  :   > FLASH
        .pinit  :   > FLASH

        .vect_tab:  > 0x20000000, type=NOINIT

        output_section_1 : {
            *(.sysmem)
            *(.data)
            *(.bss)
        } > SRAM END(end_of_ram)

        .stack  :   > SRAM2
    }

    Using this the HEAP, initialised and uninitialised data in RAM are located after the vector table (the actual order is not important for me so I didn't try the GROUP method). Then a variable called end_of_ram is located on the top of that so that its address can be used to know where this actually is.

    To force the SP to the top of RAM, SRAM2 is declared as the top bytes of SRAM. This allows the stack pointer size to be set to zero so that the initialisation code doesn't move it.

    One slightly annoying side-effect is that the linker generates a warning when the HEAP is not used since it can't put anything into .sysmem, but this can be lived with...

    Regards

    Mark