Description Some users find their (constant) jump tables get placed in RAM (in RW data) rather than ROM (constdata), using code like this:
typedef void PFUNC(void); const PFUNC *table[3] = {func0, func1, func2};
Solution This typedef is incorrect for this purpose. It should read something like:
typedef void (*PFUNC)(void);
The PFUNC type is a pointer to a void function that has no parameters. This can then be used to create an array of constant function pointers as follows:
const PFUNC table[] = {func0, func1, func2};
The following example shows this in full:
extern void func0(void); extern void func1(void); extern void func2(void);
typedef void (*PFUNC)(void); const PFUNC table[] = {func0, func1, func2};
void jump(unsigned i) { if (i <=2) table[i](); }
If this is compiled, then disassembled with:
armcc -c jump.c decaof -c jump.o
the table[] has been placed in a read only C$$constdata area, and so can then be placed in ROM as required.
** Area C$$code, Alignment 4, Size 20 (0x0014), 1 relocations Attributes: Code{32bit,FPIS3}: Read only EXPORT jump jump 0x000000: CMP r0,#2 0x000004: MOVHI pc,lr 0x000008: LDR r1,0x10 0x00000c: LDR pc,[r1,r0,LSL #2] 0x000010: 00000000 literal pool
** Area C$$constdata, Alignment 4, Size 12 (0x000c), 3 relocations Attributes: Data: Read only
After linking, the literal pool will contain the address of the table in ROM.
|