Boot loader: Preventing library calls

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Boot loader: Preventing library calls

2,090 Views
dpaul
Contributor I

Greetings:

 

Is there a pragma or compiler switch which forces CodeWarrior to generate in line code rather than library calls?

 

I am sure this has been asked before, but obviously one needs to prevent one's re-flashing boot loader from calling functions with are begin replaced, including those hidden ones the compiler itself generates to it's library.  

 

In my case, I have a boot segment which contains the boot loader code and a separate re-flashable code area.  A pointer manipulation in the boot loader compiled down to making a library call.  Unfortunately, that library function resides in the re-flashable code area and had been erased.  Oops!

 

I really want only  my boot load module to have this restriction.

 

Thanks for any suggestions.

doug

Labels (1)
0 Kudos
Reply
10 Replies

1,204 Views
CompilerGuru
NXP Employee
NXP Employee

You forgot to mention for which architecture and derivative the question is, runtime routines are compiler specific.

For some cases there might be ways for the compiler to avoid runtime calls, but in general the compiler wont be able to compile arbitrary C core without using runtime calls.

 

The general solution for the problem is to split up the application into 2 separate applications, one containing the boot loader (and it's copies of the needed runtime routines) and a separate one for the main application code. 

In a safe field flash upgrade scenario I would think that the bootloader itself does not get reflashed to avoid a time window where the device is not recoverable. If so, using a separate elf file also helps to isolate any dependencies between the changing and the non changing code. For example if the bootloader uses a function in the app code, this immediately fails when the app code is erased and therefore easy to detect (as you did :smileyhappy: ). However if the app uses some code of the bootloader, it will work just fine, until one day the bootloader changes just a little, addresses shift a bit and then when the app in the field gets updated and an old bootloader is present, the call into the bootloader misses it target. (While it just worked fine with the new bootloader when testing the app...).

 

If you decide to stick with the "bootloader is part of the app" approach, then for the 8/16 bit compilers (S12/S08), there is a message which can be mapped to an error to fail when the compiler uses a runtime call. By default the message is off. Optimizing for speed usually uses fewer runtime calls.

 

Daniel

0 Kudos
Reply

1,204 Views
dpaul
Contributor I

I am writing in CodeWarrior 5.9.0 and targeting the MC9S08AC32.  My ambiguity was in hopes there might be a generic way to do this.

 

I appreciate the two apps approach.  Indeed, I am using that approach in another part of this development.  Unfortunately, in the case of these Freescale devices, I am under directive to duplicate, as close as possible, the approach used previously.  That is, I'm stuck with the single app boot loader approach, at least for the time being.

 

It seems in previous instances, the solution was to examine the assembler output for any undesired runtime calls and adjust the code as necessary.  Obviously this is a laborious approach, fraught with maintenance problems, as I myself just fell victim to.  

 

There are a plethora of options and switches in CodeWarrior as befitting a product with a rich and venerable history.  It seems there ought to be just such a feature buried in there somewhere.

 

Thanks!

doug

0 Kudos
Reply

1,204 Views
kef
Specialist I

Yet another stupid directive. The only right solution is to do 2 separate apps. Using HEXFILE bootloader.s19 directive in applications PRM solves possible bootloader_is_erased_by_debugger issues.

 

 

Daniel, thanks for pointing to C3605 message (CW for S08). I'll use that sometimes.

 

 

Doug, C3605 message can be enabled in compilers setting. Alt+F7 -> Compiler for HC08 -> Messages -> Disabled. Highliting C3605 message and moving it to Information, Error or Warning category will enable it globally. I guess this is not what you want. To enable C3605 only in some parts of code, add these lines to your code:

 

#pragma MESSAGE WARNING C3605 // enable C3605 warning
<bootloader_code>

#pragma MESSAGE DISABLE C3605 // disable C3605 message

0 Kudos
Reply

1,204 Views
ignisuti
Contributor IV

I'm coming up to speed on an existing project and this is my first time using Freescale products. The project was initially setup as two applications (Bootloader and Application code) by a former engineer. I've been asked to join those into a single project.

 

From what I've read in this post, it is best to keep this as two seperate projects, right?

I'd like to learn more about making this decision. Can you guys recommend a good link to previous discussion on this topic?

0 Kudos
Reply

1,204 Views
kef
Specialist I

Yes, bootloader and application should be two separate applications. Consider the case when  you need to firmware-upgrade some old product. You may have N compiler patches since that product was installed. Now you can compile and link bootloader and app at once, but at client's site you have old bootloader, which is linked with old libraries. Those old libraries may be not compatible with newly compiled application. Good to you if you have working copy of old compiler. But if not, then having separate bootloader and app, you don't care how old your bootloader is. If it is working, then you will be able to flash new application, no matter what compiler vendor or version it was made with.

You may say "ok, but I'll flash both, application and bootloader". This is another wrong idea. Bootloader should be write protected and never reflashed. Even if you are powered from robust backup batteries, I would not eliminate the possibility of power loss or reset after bootloader was erased, but before it was written back to flash.

0 Kudos
Reply

1,204 Views
ignisuti
Contributor IV

Thanks for the explanation.

 

Does this assume the Bootloader is using code from the Application segments? What if the Bootloader was completely independent of the Application code (uses no variables or functions from the Application code) and just needs the starting address of the the startup routine which calls main()?

 

Supporting two seperate projects is a bit cumbersome during development. Just trying to explore all the options.

0 Kudos
Reply

1,203 Views
kef
Specialist I

It is difficult and time consuming to make sure bootloader is not using any runtime routines from the library. You change some option or upgrade compiler and suddenly app and bootloader are calling the same shared routine. Do you want this?

 

Just include bootloader hex or s19 file in application code using "HEXFILE bootloader.s19" command in prm file. One click and application is build and being downloaded to MCU with bootloader included.

 

0 Kudos
Reply

1,203 Views
ignisuti
Contributor IV

Okay, I'm ready to give this a try now.

 

First problem is that I don't have a .prm file. I have a .lcf file. Is that the same?

0 Kudos
Reply

1,204 Views
kef
Specialist I

This thread was about S08. Help for coldfire lcf files mention INCLUDE directive. But I'm not sure how to use it. It seems it lcf INCLUDE assumes binary only files.

0 Kudos
Reply

1,204 Views
ignisuti
Contributor IV

That doesn't sound too bad. I'll give it a shot. Thanks!

0 Kudos
Reply