Reply
Highlighted
Posts: 5
Registered: ‎03-18-2013

Bootloader - compiler optimizations

Hello,

a year ago we started with EMF32. Within that thime we have made a lot of different Prototypes (GG, TG) with different applications. I have made a Bootloader for our devices. For this I have taken the IAR project from AN0003 and ported it to a Atollic TrueStudio project. Instead of using a xmodem communication I read the firmware from an an external eeprom on the device. After I have checked the crc I make a restart and enter the bootloader. There I check the file again and start to flash the new firmare and make a restart after the firmware was written.


This all work good and we are happy with the solution we have found. But now the Bootloader has about 8kByte of Flash memory, because we have use the debug configuration from Atollic Truestudio. For the release we have now tried to use the Release configuration. But then the Booloader will no longer start the original application. If i use the release configuration with optimization level -o0 or -o1 then it will work and the bootloader will start the application. But if I use optimization lever -o2 or higher then it looks like that the bootloader starts right but after __asm (mov pc, r1); within the boot_jump function nothing happens and the booloader will not start the application. This has nothing to do with the update progress itself because this also happen if I only start the device with the booloader and the application on it. They has been programmes with the energyaware commander. So at the moment I don't know what I can do that the bootloader will also work with optimizatons!!!

 


Posts: 529
Registered: ‎08-07-2012

Bootloader - compiler optimizations

My guess is that the compiler is optimizing away the function arguments. Since the C compiler does not know that the sp an pc arguments to the BOOT_jump() function are being used it can remove these arguments and thus save a few instructions when calling the function. 

You need to somehow tell the compiler that the assembly code is using the arguments. I think in GCC you should do something like this



__asm(msr msp, %[sp] : : [sp] r (sp));
__asm(msr psp, %[sp] : : [sp] r (sp));

I just had a look at the instructions here: 

http://www.ethernut.de/en/documents/arm-inline-asm.html


Posts: 5
Registered: ‎03-18-2013

Bootloader - compiler optimizations

Thank you Filip!

I'm not really good in asm statements! So here is teh original routine that I tried to use:


void BOOT_jump(uint32_t sp, uint32_t pc)

{

  (void) sp;

  (void) pc;

  /* Set new MSP, PSP based on SP (r0)*/

  __asm(msr msp, r0);

  __asm(msr psp, r0);

  /* Jump to PC (r1)*/

  __asm(mov pc, r1);

}



An tI thinke that the compiler make some otimizations on the last statement.


So what should I change here to be sure that there is no omtimization on that.

Thank you


Markus


Posts: 529
Registered: ‎08-07-2012

Bootloader - compiler optimizations

I do not think there is any problem with the last statement. My guess is that the compiler removes the arguments to the function, since they are not explicitly used. You should step through the code with your debugger and see what is actually stored in R0, R1 when it enters the function and also what ends up in SP/PC after the code completes. 

My suggestion was to rewrite the function to something like below. However, this type of things are highly compiler dependent, so you have to verify if it works on your system. I have not tried this myself. 



void BOOT_jump(uint32_t sp, uint32_t pc)
{
(void) sp;
(void) pc;

/* Set new MSP, PSP based on SP (r0) */
__asm(msr msp, %[sp] : : [sp] r (sp));
__asm(msr psp, %[sp] : : [sp] r (sp));

/* Jump to PC (r1)*/
__asm(mov pc, %[pc] : : [pc] r (pc));
}
Posts: 5
Registered: ‎03-18-2013

Bootloader - compiler optimizations

Thank you Filip!

If I use __asm(mov pc, %[pc] : : [pc] r (pc)); instead of __asm(mov pc, r1); then it works and there are no optimizations!

first I have tried to debug and the debugger (attloic Truestudio) told me that sp and pc are optimized out

With the new statement I see now the pc and sp also in the debugger and the application ist started!

 


Thank you Markus