Part Number: MSP430-GCC-OPENSOURCE
Other Parts Discussed in Thread: MSP430F249
I iterate over a table of function-pointers, placed inside the flash-memory using the linker-script. GCC keeps the loop/iteration pointer in r12 across the indirect call. I understand r12 to be a caller-saved register, so the called function if free to clobber the register and the caller should preserve it across the call.
Here is my example application:
typedef void(*sys_init_t)(void);
static void init_fn_0(void) {
/* trivial, does not disturb r12 */
}
static void init_fn_1(void) {
volatile int a = 1, b = 2, c = 3, d = 4, e = 5;
(void)a; (void)b; (void)c; (void)d; (void)e;
/* enough live locals at -Os to force r12 use as scratch */
}
__attribute__((section(".sys_init"), used))
static const sys_init_t init0 = init_fn_0;
__attribute__((section(".sys_init"), used))
static const sys_init_t init1 = init_fn_1;
extern const sys_init_t __sys_init_start;
extern const sys_init_t __sys_init_end;
void sys_init(void) {
for(const sys_init_t* fn = &__sys_init_start; fn < &__sys_init_end; fn++) {
(*fn)();
}
}
int main() {
sys_init();
return 0;
}
I use the original linker-script for the MSP430F249 with the following addition to the SECTIONS part:
.sys_init :
{
__sys_init_start = .;
KEEP(*(.sys_init));
__sys_init_end = .;
} > ROM
I'm building the application like this:
msp430-elf-gcc -mcpu=msp430 -mmcu=msp430f249 -g0 -Os -D__MSP430F249__=1 -c main.c -o main.o
msp430-elf-gcc -mcpu=msp430 -mmcu=msp430f249 -g0 -Os -D__MSP430F249__=1 -T linker.ld main.o -o example.out
00001148 <sys_init>:
1148: 3c 40 00 11 mov #4352, r12 ;#0x1100
0000114c <.L4>:
114c: 3c 90 04 11 cmp #4356, r12 ;#0x1104
1150: 01 28 jnc $+4 ;abs 0x1154
1152: 30 41 ret
00001154 <.L5>:
1154: 3d 4c mov @r12+, r13 ;
1156: 8d 12 call r13 ;
1158: f9 3f jmp $-12 ;abs 0x114c
As one can see, after the call r13 we jump right back to 0x114c, where r12 is evaluated again, even though the called function could have clobbered the register. In that case, the code will crash.
msp430-elf-gcc --version:
msp430-elf-gcc (Mitto Systems Limited - msp430-gcc 9.3.1.11) 9.3.1