GCC rodata problem with AT91EB40A evaluation board

From: Kari Veikkolainen (kaba_at_nic.fi)
Date: 12/31/03


Date: Wed, 31 Dec 2003 11:51:42 +0200

I'm using AT91EB40A evaluation board and GCC.
Everything works just fine until I use .rodata -section in my program. If I
use rodata the program is compiled, but it doesn't work as it should. I
would be very happy if somebody could tell me what I'm doing wrong.

---Source code I'm using looks like this---:

/* GPIO set and reset registers */
#define PIO_SODR 0xffff0030
#define PIO_CODR 0xffff0034

/* Bits to be set/reset on the GPIO port in order to toggle the LED */
#define RED_LED 1 << 6

/* Quick and dirty macros to write a register or memory location word,
halfword or byte */
#define WRITEREGW(addr,value) *((volatile unsigned int *) (addr)) = (value)
#define WRITEREGH(addr,value) *((volatile unsigned short *) (addr)) =
(value)
#define WRITEREGB(addr,value) *((volatile unsigned char *) (addr)) = (value)

unsigned long LEDS[8]={1<<16,1<<17,1<<18,1<<19,1<<3,1<<4,1<<5,1<<6};
/*(rodata) Doesn't work */
unsigned long LEDS2[8];

int main(void)
{
 register int i;
 unsigned long led_ptr;

 LEDS2[0]=1<<16; /*(data) Works fine! */
 LEDS2[1]=1<<17;
 LEDS2[2]=1<<18;
 LEDS2[3]=1<<19;
 LEDS2[4]=1<<3;
 LEDS2[5]=1<<4;
 LEDS2[6]=1<<5;
 LEDS2[7]=1<<6;

 asm(" .global .L29");

 while (1) {

 for(led_ptr=0;led_ptr<8;led_ptr++){
  WRITEREGW(PIO_CODR,LEDS2[led_ptr]); /* led on */
  for (i=0x120000;i>0;i--) {}
  WRITEREGW(PIO_SODR,LEDS2[led_ptr]); /* led off */
  for (i=0x120000;i>0;i--) {}
 }

 }

}

---This is linker script I'm using---:

ENTRY(vectors)

SEARCH_DIR(.)

/*
 There is a single memory segment, representing the 256K on-board SRAM.
*/
MEMORY
{
 sram : org = 0x00010000, len = 0x00040000 /* 256KBytes of SRAM */
}

SECTIONS
{
 .text : /* text section*/
 {
         *(.text);
         . = ALIGN(4);
  *(.glue_7t);
  . = ALIGN(4);
  *(.glue_7);
  . = ALIGN(4);
         etext = .;
 } > sram

 .rodata ADDR(.text) + SIZEOF(.text) : /* I have added this by myself to
Lewins code */
 {
  rodatastart = .;
  __rodata_start__ = . ;
  *(.rodata)
         . = ALIGN(4);
         __rodata_end__ = . ;
         erodata = .;
         _erodata = .;
 }

 .data ADDR(.rodata) + SIZEOF(.rodata) : /* Data section*/
 {
  datastart = .;
  __data_start__ = . ;
  *(.data)
         . = ALIGN(4);
         __data_end__ = . ;
         edata = .;
         _edata = .;
 }

 .bss ADDR(.data) + SIZEOF(.data) : /* Stack section */
 {
  __bss_start__ = . ;
  *(.bss); *(COMMON)
  __bss_end__ = . ;
  _stack_bottom = . ;
  . += 0x800 ;
  _stack_top = . ;
 }

 end = .;
 _end = .;
 __end__ = .;

 /* Symbols */
 .stab 0 (NOLOAD) :
 {
  [ .stab ]
 }

 .stabstr 0 (NOLOAD) :
 {
  [ .stabstr ]
 }
}

---My makefile ---:

CFLAGS = -g -I. -mcpu=arm7tdmi
ASFLAGS = -mcpu=arm7tdmi -gstabs
LDFLAGS = -Teb40-ram.ld -nostartfiles -Lgcc -L. -Wl,-Map=$@.map

OBJS = boot.o main.o
EXE = example2.elf

all:example2.sr example2.bin

$(EXE): $(OBJS)
 arm-elf-gcc $(LDFLAGS) -o $(EXE) $(OBJS)

%.o:%.c
 arm-elf-gcc -c $(CFLAGS) $< -o $@

%.s:%.c
 arm-elf-gcc -S $(CFLAGS) $< -o $@

%.o:%.s
 arm-elf-as $(ASFLAGS) $< -o $@

%.sr:%.elf
 arm-elf-objcopy -v -O srec $< $@

%.bin:%.elf
 arm-elf-objcopy -v -O binary $< $@

clean:
 rm -f $(OBJS)
 rm -f $(EXE)

***************************************
Kari Veikkolainen
kaba @ nic. fi --remove spaces--