[arm-gnu] Placing variable at absolute address in RAM
Bob Brusa
bob.brusa at gmail.com
Thu Apr 5 09:31:47 UTC 2012
Am 04.04.2012 16:33, schrieb JM:
> Hello
>
> I've researched this, asked on other forums, and so far I'm no closer.
>
> I'm trying to place a variable at a specific address in RAM on a TI ARM
> Cortex-M3. I have good reason for doing so, which I can explain briefly:
>
> The micro I'm using, LM3S9B92 has a DMA controller. There are 32 DMA
> channels and each channel requires a 16 byte struct in RAM for
> housekeeping. These 32 structs are placed into an array, which is 512
> bytes if you do the math, and must be placed on a 1024 byte boundary.
> Now....the datasheet indicates that the RAM for unused DMA channels can
> be used for something else. I'm using only one DMA channel, which is
> near the end of the list. If it were near the beginning, this would be
> easier to recover at least some of the wasted RAM by simply not making
> the array 32 members long.
>
> So what I want to do is reserve 16 bytes of RAM at a strategic location.
> It must be 464 bytes from a 1024 byte boundary. This I believe will
> allow the lone DMA channel to function and not allocate unused RAM.
>
> I believe this will involve the linker script, and possibly Makefile.
> I'm ok with Makefile modifications. The linker file I'm almost clueless
> on. Any ideas? My current linker file is below:
>
> MEMORY
> {
> FLASH (rx) : ORIGIN = 0x00001000, LENGTH = 252K
> SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
> }
>
> SECTIONS
> {
> .text :
> {
> KEEP(*(.isr_vector))
> *(.text*)
> *(.rodata*)
> _etext = .;
> } > FLASH
>
> .data : AT (ADDR(.text) + SIZEOF(.text))
> {
> _data = .;
> *(vtable)
> *(.data*)
> _edata = .;
> } > SRAM
>
> .bss(NOLOAD) :
> {
> _bss = .;
> *(.bss*)
> *(COMMON)
> _ebss = .;
> . = ALIGN (8);
> _end = .;
> } > SRAM
> }
>
> /* end of allocated ram _end */
> PROVIDE( _HEAP_START = _end );
>
> /* end of the heap -> align 8 byte */
> PROVIDE ( _HEAP_END = ALIGN(ORIGIN(SRAM) + LENGTH(SRAM),8) );
>
>
>
>
>
>
> _______________________________________________
> arm-gnu mailing list
> arm-gnu at codesourcery.com
> http://sourcerytools.com/cgi-bin/mailman/listinfo/arm-gnu
Hi,
two years ago I had a similar problem. I needed an area at a fixed
address in flash and an other at a known place in ram - with the
requirement, that this part of the ram should not be initialized upon
startup of the program. And here is what I did:
The trick is to define new sections. For the flash case I added the
following lines at the beginning of the relevant source:
#define EEPromArea 0x400
cyg_uint8 eeprombottom[EEPromArea] __attribute__ ((section (".eeromemu")));
and for the sram case (nvv_t is a user-defined type):
nvv_t nvv __attribute__ ((section (".sticky")));
The standard loader file then needs a few modifications - see attachment.
Hope this helps.
Regards Bob
-------------- next part --------------
STARTUP(vectors.o)
ENTRY(reset_vector)
INPUT(extras.o)
GROUP( libtarget.a libgcc.a libsupc++.a )
/* redboot rb_5 uses memory as follows:
* RAM 0x00200000..0x002057f8 parameters
* RAM 0x0021F300..0x00220000 work-area size 0xD00=3328 ?? where from is this info ??
* Flash 0x00100000..0x00111288 redboot code
* Flash 0x00113C00..0x00114000 config-area
*/
MEMORY
{
rom : ORIGIN = 0x00114000, LENGTH = 0x6BC00 /* go above redboot rb_5 */
eerom : ORIGIN = 0x0017FC00, LENGTH = 0x00400 /* eerom emulation area */
ram : ORIGIN = 0x00205800, LENGTH = 0x19a00 /* above redboot */
sram (!I): ORIGIN = 0x0021F200, LENGTH = 0x00100 /* for nvv and below ws of redboot */
}
SECTIONS
{
.debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } .debug_info 0 : { *(.debug_info) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } .note.arm.ident 0 : { KEEP (*(.note.arm.ident)) } /DISCARD/ 0 : { *(.fini_array*) }
__reserved_bootmon = 0x00000000; . = __reserved_bootmon + 0x01000;
.rom_vectors 0x00114000 : { __rom_vectors_vma = ABSOLUTE(.); . = .; KEEP (*(.vectors)) } > rom __rom_vectors_lma = LOADADDR(.rom_vectors);
.ARM.extab ALIGN (0x1) : { PROVIDE (__stext = ABSOLUTE(.)); _stext = ABSOLUTE(.) ; . = .; } > rom /DISCARD/ 0 : { *(.ARM.extab* .gnu.linkonce.armextab.*) } . = ALIGN(8); . = ALIGN(8); __exidx_start = ABSOLUTE(.); .ARM.exidx ALIGN(8) : AT ((LOADADDR (.ARM.extab) + SIZEOF (.ARM.extab) + (8) - 1) & ~ ((8) - 1)) { . = .; } > rom __exidx_end = ABSOLUTE(.); /DISCARD/ 0 : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } .text ALIGN(8) : AT ((LOADADDR (.ARM.exidx) + SIZEOF (.ARM.exidx) + (8) - 1) & ~ ((8) - 1)) { *(.text*) *(.gnu.warning) *(.gnu.linkonce.t.*) *(.init) *(.glue_7) *(.glue_7t) __CTOR_LIST__ = ABSOLUTE (.); KEEP (*(SORT (.ctors*))) __CTOR_END__ = ABSOLUTE (.); __DTOR_LIST__ = ABSOLUTE (.); KEEP (*(SORT (.dtors*))) __DTOR_END__ = ABSOLUTE (.); } > rom _etext = .; PROVIDE (__etext = .);
.fini ALIGN (0x4) : { . = .; *(.fini) } > rom
.rodata ALIGN (0x4) : { . = .; *(.rodata*) *(.gnu.linkonce.r.*) } > rom
.rodata1 ALIGN (0x4) : { . = .; *(.rodata1) } > rom
.fixup ALIGN (0x4) : { . = .; *(.fixup) } > rom
.gcc_except_table ALIGN (0x4) : { . = .; } > rom /DISCARD/ 0 : { *(.gcc_except_table*) }
.eeromemu 0x0017FC00 (NOLOAD) : { . = .; *(.eeromemu) } > eerom
.sticky 0x0021F200 (NOLOAD) : { . = .; *(.sticky) } > sram /* store nvv here */
.fixed_vectors 0x00205800 : { . = .; KEEP (*(.fixed_vectors)) } > ram
.data ALIGN (0x4) : AT ((LOADADDR (.gcc_except_table) + SIZEOF (.gcc_except_table) + (4) - 1) & ~ ((4) - 1)) { __ram_data_start = ABSOLUTE (.); *(.data*) *(.data1) *(.gnu.linkonce.d.*) . = ALIGN (4); KEEP(*( SORT (.ecos.table.*))) ; . = ALIGN (4); __init_array_start__ = ABSOLUTE (.); KEEP (*(SORT (.init_array.*))) KEEP (*(SORT (.init_array))) __init_array_end__ = ABSOLUTE (.); *(.dynamic) *(.sdata*) *(.gnu.linkonce.s.*) . = ALIGN (4); *(.2ram.*) } > ram __rom_data_start = LOADADDR (.data); __ram_data_end = .; PROVIDE (__ram_data_end = .); _edata = .; PROVIDE (edata = .); PROVIDE (__rom_data_end = LOADADDR (.data) + SIZEOF(.data));
.bss ALIGN (0x4) : { __bss_start = ABSOLUTE (.); *(.scommon) *(.dynsbss) *(.sbss*) *(.gnu.linkonce.sb.*) *(.dynbss) *(.bss*) *(.gnu.linkonce.b.*) *(COMMON) __bss_end = ABSOLUTE (.); } > ram
__heap1 = ALIGN (0x8);
. = ALIGN(4); _end = .; PROVIDE (end = .);
}
More information about the arm-gnu
mailing list