Forums

GCC optimization and IAP

Started by andersryl February 7, 2007
Hi,

I'm using an LPC2214 together with the GNUARM tools and are having
some problems with IAP.

I have one source file with all the IAP function calls (to iap_entry @
0x7FFFFFF1, called iap.c). This file is compiled with the
-mthumb-interwork flag. The rest of the files are compiled without
this flag.

When compiling the source files with -O0 (no optimization) preparing,
erasing and writing to flash works fine. The problem then is that the
resulting program takes too much space so I thought of compiling with
-Os (cuts the code size in half in my case).

When trying this, the IAP calls no longer work. I also tried to
compile the iap.c with -O0 and the rest of the files with -Os but to
no avail. I get an prefetch abort when calling iap_entry.

When comparing the dump-files for the last scenario (iap.c compiled
with -O0 and the rest with -Os) and the original (all compilation with
-O0) the instructions for the functions in iap.c are identical besides
the addresses where they are located.

Here is the dump for the prepareFlashSector function:
00005830 :
5830: e1a0c00d mov r12, sp
5834: e92dd800 stmdb sp!, {r11, r12, lr, pc}
5838: e24cb004 sub r11, r12, #4 ; 0x4
583c: e24dd004 sub sp, sp, #4 ; 0x4
5840: e1a03000 mov r3, r0
5844: e54b3010 strb r3, [r11, #-16]
5848: e59f205c ldr r2, [pc, #92] ; 58ac <.text+0x58ac>
584c: e3a03032 mov r3, #50 ; 0x32
5850: e5823000 str r3, [r2]
5854: e55b2010 ldrb r2, [r11, #-16]
5858: e59f304c ldr r3, [pc, #76] ; 58ac <.text+0x58ac>
585c: e5832004 str r2, [r3, #4]
5860: e55b2010 ldrb r2, [r11, #-16]
5864: e59f3040 ldr r3, [pc, #64] ; 58ac <.text+0x58ac>
5868: e5832008 str r2, [r3, #8]
586c: e59f303c ldr r3, [pc, #60] ; 58b0 <.text+0x58b0>
5870: e5933000 ldr r3, [r3]
5874: e59f0030 ldr r0, [pc, #48] ; 58ac <.text+0x58ac>
5878: e59f1034 ldr r1, [pc, #52] ; 58b4 <.text+0x58b4>
587c: e1a0e00f mov lr, pc
5880: e12fff13 bx r3
5884: e3a0320e mov r3, #-536870912 ; 0xe0000000
5888: e2833903 add r3, r3, #49152 ; 0xc000
588c: e3a02070 mov r2, #112 ; 0x70
5890: e5c32000 strb r2, [r3]
5894: e59f3018 ldr r3, [pc, #24] ; 58b4 <.text+0x58b4>
5898: e5933000 ldr r3, [r3]
589c: e1a00003 mov r0, r3
58a0: e24bd00c sub sp, r11, #12 ; 0xc
58a4: e89d6800 ldmia sp, {r11, sp, lr}
58a8: e12fff1e bx lr
58ac: 40000904 andmi r0, r0, r4, lsl #18
58b0: 40000200 andmi r0, r0, r0, lsl #4
58b4: 400006fc strmid r0, [r0], -r12

The content of the RAM locations:
0x40000200: 0x7FFFFFF1
0x400008b0: IAP_command (uint32_t IAP_command[5];)
0x400006a8: IAP_result (uint32_t IAP_result[2] = {0,0};)

The IAP related function pointer and RAM -buffer are defined like:
typedef void (*IAP) (uint32_t [], uint32_t []);
IAP iap_entry = (IAP) IAP_LOCATION;
uint8_t IAP_Data1[512] __attribute__ ((aligned (4)));

Anyone understand why it doesn't work with -Os optimization?

/Anders

An Engineer's Guide to the LPC2100 Series

Did you solve your issue with GNUARM?

Regards,

Peter

Hi,
>
>I'm using an LPC2214 together with the GNUARM tools and are having
>some problems with IAP.
>
>I have one source file with all the IAP function calls (to iap_entry @
>0x7FFFFFF1, called iap.c). This file is compiled with the
>-mthumb-interwork flag. The rest of the files are compiled without
>this flag.
>
>When compiling the source files with -O0 (no optimization) preparing,
>erasing and writing to flash works fine. The problem then is that the
>resulting program takes too much space so I thought of compiling with
>-Os (cuts the code size in half in my case).
>
>When trying this, the IAP calls no longer work. I also tried to
>compile the iap.c with -O0 and the rest of the files with -Os but to
>no avail. I get an prefetch abort when calling iap_entry.
>
>When comparing the dump-files for the last scenario (iap.c compiled
>with -O0 and the rest with -Os) and the original (all compilation with
>-O0) the instructions for the functions in iap.c are identical besides
>the addresses where they are located.
>
>Here is the dump for the prepareFlashSector function:
>00005830 :
> 5830: e1a0c00d mov r12, sp
> 5834: e92dd800 stmdb sp!, {r11, r12, lr, pc}
> 5838: e24cb004 sub r11, r12, #4 ; 0x4
> 583c: e24dd004 sub sp, sp, #4 ; 0x4
> 5840: e1a03000 mov r3, r0
> 5844: e54b3010 strb r3, [r11, #-16]
> 5848: e59f205c ldr r2, [pc, #92] ; 58ac
> 584c: e3a03032 mov r3, #50 ; 0x32
> 5850: e5823000 str r3, [r2]
> 5854: e55b2010 ldrb r2, [r11, #-16]
> 5858: e59f304c ldr r3, [pc, #76] ; 58ac
> 585c: e5832004 str r2, [r3, #4]
> 5860: e55b2010 ldrb r2, [r11, #-16]
> 5864: e59f3040 ldr r3, [pc, #64] ; 58ac
> 5868: e5832008 str r2, [r3, #8]
> 586c: e59f303c ldr r3, [pc, #60] ; 58b0
> 5870: e5933000 ldr r3, [r3]
> 5874: e59f0030 ldr r0, [pc, #48] ; 58ac
> 5878: e59f1034 ldr r1, [pc, #52] ; 58b4
> 587c: e1a0e00f mov lr, pc
> 5880: e12fff13 bx r3
> 5884: e3a0320e mov r3, #-536870912 ; 0xe0000000
> 5888: e2833903 add r3, r3, #49152 ; 0xc000
> 588c: e3a02070 mov r2, #112 ; 0x70
> 5890: e5c32000 strb r2, [r3]
> 5894: e59f3018 ldr r3, [pc, #24] ; 58b4
> 5898: e5933000 ldr r3, [r3]
> 589c: e1a00003 mov r0, r3
> 58a0: e24bd00c sub sp, r11, #12 ; 0xc
> 58a4: e89d6800 ldmia sp, {r11, sp, lr}
> 58a8: e12fff1e bx lr
> 58ac: 40000904 andmi r0, r0, r4, lsl #18
> 58b0: 40000200 andmi r0, r0, r0, lsl #4
> 58b4: 400006fc strmid r0, [r0], -r12
>
>The content of the RAM locations:
> 0x40000200: 0x7FFFFFF1
> 0x400008b0: IAP_command (uint32_t IAP_command[5];)
> 0x400006a8: IAP_result (uint32_t IAP_result[2] = {0,0};)
>
>The IAP related function pointer and RAM -buffer are defined like:
> typedef void (*IAP) (uint32_t [], uint32_t []);
> IAP iap_entry = (IAP) IAP_LOCATION;
> uint8_t IAP_Data1[512] __attribute__ ((aligned (4)));
>
>Anyone understand why it doesn't work with -Os optimization?
>
>/Anders
>