EmbDev.net

Forum: ARM programming with GCC/GNU tools Efficient tables


von Bob S. (bobz)


Rate this post
useful
not useful
Can anyone help?
I am creating a simple but long table of RAM addresses in ROM.

static const void* addressTableInROM[]=
{
  &variable,
  &another,
  &etc,
  &etc_
};

This is fine except each address on the ARM is 32bit
and begins with the same 2 bytes 0x2000, e.g. 0x200009A4. Target is
Str71x.

How can I store this table more efficiently;-
 a) in ROM
 b) with global persistence
by say storing only the 2 least significant bytes of each address?



Interestingly it is possible to create such a table in RAM
without global persistence like this;-

void function(void)
{
  const unsigned short addressTableInROM[]=
  {
    (unsigned long)&variable,
    (unsigned long)&another,
    (unsigned long)&etc,
    (unsigned long)&etc_
  };
};

but putting static before const produces the wrong result that is;-
a) all the entries are 0 and
b) no compiler or linker error is produced.
Also the table is smaller but presumably an initial image goes in ROM.

note
1 I am using the latest winarm/gnu distribution 06062006 for arm7tdmi
str71x
  on a ranasonse reva eval board.
2. Casting initialisers is disallowed on other compilers.
3. Arithmetic on pointer initializers is allowed on (older)IAR
compilers.
4. In the first example above, any cast or arithmetic on the initializer
   turns the value to 0.
5. Using Optimizer level 1, .cpp files, no thumb/thumb-interworking.

bobz

von A.K. (Guest)


Rate this post
useful
not useful
Combine all the referenced variables in a struct and fill the table with
the offsets within the struct (using the "offsetof" macro). This is
fairly safe.

von Bob S. (bobz)


Rate this post
useful
not useful
A.K. wrote:
> Combine all the referenced variables in a struct and fill the table with
> the offsets within the struct (using the "offsetof" macro). This is
> fairly safe.

Worked perfectly! THANKYOU A.K.

Here is the test code. The output values are shown in the coments.

typedef struct ak_t
{
  float movedGlbf1;
  float movedGlbf2[10];
  short movedGlbs1;
  char movedGlbc1[2];
}ak_typedef;

ak_typedef ak;

static const u16 addressTableInRom[]=
{
  offsetof(struct ak_t, movedGlbs1),    //should be 44
  offsetof(struct ak_t, movedGlbf2[1])  //should be
};

void test_ak(void) /*
~~~~~~~~~~~~~~~~~~ */
{
  ak.movedGlbs1=-1234;        //init
  ak.movedGlbf2[1]=3.1416;

  display(addressTableInRom[0]);  //44 ok   offset into struct
  display(addressTableInRom[1]);  //8 -ok

  u32 u0 = (u32)&ak + addressTableInRom[0];  //expand offset to address
  u32 u1 = (u32)&ak + addressTableInRom[1];

  displayhex(u0); // 0x200009DC  report address
  displayhex(u1); // 0x200009B8

  display( *(short*)u0 ); // -1234   report @address -- perfect!
  display( *(float*)u1 ); // 3.1416
}

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.