bootloader and application in seperate projects

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

bootloader and application in seperate projects

1,832 Views
Seppel
Contributor I

Hi @all,

 

i want to split bootloader code from application code in seperate projects. I find some good hints in this forum, f.e. https://community.freescale.com/message/29324#29324. But my project still don't work (who would have thought this :smileyhappy: ) I use CW 5.9.0, C-Code projects, WinXP, MC9S08DV32 Controller. Till now i have create bootloader project and app project, and both work fine for itself. In the PRM files i seperate the ROM segments for bootloader code and app code.Both projects have standard _Startup codes (generated by CW) and the entry point for self written functions is void main(void).

 

Now i want to add bootloader.s19 to my app by using HEXFILE bootloader.s19 instruction in PRM File. Doing this i get problems with startvector! There is an error in debuggers command window: Code loading overlap detected in range 0x0000FFFE..0x0000FFFF and when i run the application with added bootloader.s19, the startvector goes to app instead of bootloader! I hoped that the startvector become the address of bootloader startup, by adding HEXFILE bootloader.s19, but it don't. How can i add my bootloader project/code/s19 to the app-project, where the bootloader starts after reset?


Labels (1)
0 Kudos
6 Replies

820 Views
bigmac
Specialist III

Hello,

 

This error is indicative that the reset vector is defined in two different places.  This will be possibly be within a vector table, and also the PRM file.  If using a vector table, the entry within the PRM file should be commented out.

 

If the linker were to examine the contents of the S19 file - I am not sure whether it does - it may also detect the two different reset vector values.

 

The reset vector should point to the bootloader code whenever the bootloader is present.  This is not the same _Startup location as when the application is compiled.  Actually, the "start08.c" code will be generated twice, once for the boot loader compile, and again for the application compile.  When using the bootloader, its_Startup() function would commence via the reset vector.  Once this function is completed there will be a direct jump to the bootloader main().

 

The bootloader needs to know the application's _Startup address (the contents of the application's reset vector), so that a direct jump may occur, when required.  This would mean that the application link would need to be aware of the presence of the bootloader S19 file, to correctly relocate its reset vector value.  Maybe this is possible with the modified _Startup vector entry within the PRM file, where the address is explicitly defined.

 

Regards,

Mac

 

0 Kudos

820 Views
Seppel
Contributor I

Hi bigmac and thanks for your reply.

 

You are completly right, i have two different reset vector values: one in the added bootloader.s19 file (goes to _Startup of Bootloader) and one in the application project in MCUinit.c (standard Interrupt vector table). So the linker were to examine the contents of the S19 file how you correctly assumed.

 

The bootloader needs to know the application's _Startup address (the contents of the application's reset vector), so that a direct jump may occur, when required.

Right, my bootloader code know the _Startup address (==Reset vector) of the app. In bootloader_main() i check a flag. If this flag is zero, the code jumps to this app _Startup address: If (flag == 1), the bootloader loads flash-data over CAN BUS.

 

This would mean that the application link would need to be aware of the presence of the bootloader S19 file, to correctly relocate its reset vector value

And thats the point! When i generate an extra project for the app and want to test the app by its own, without presents of any bootloader, my reset vector is the app _Startup. That works fine. But if i want to add bootloader code i have to change more than adding HEXFILE bootloader.s19 in the PRM, right? I thought by adding this HEXFILE command in the end of PWM file, the Linker will just overwrite the app-reset-vector with the bootloader-reset-vector... but he don't.

So i have to change the reset vector in my app too, right? In detail i have to...

1) relocate the app reset vector to the bootloader _Startup (like in bootloader.s19 file) and...

2) add HEXFILE bootloader.s19 instruction in prm.

And if i want to check my app itself, without bootloader i have to comment out the HEXFILE instruction and relocate the reset vecotr to the app _Startup. Is there something else to do?

 

By the way: by adding HEXFILE bootloader.s19 in the PRM file - how does Linker decide, which data he takes from app and which he takes from bootloader.s19?

0 Kudos

820 Views
bigmac
Specialist III

Hello,

 

Maybe the following thread will provide a solution to your problem?  You would need two different PRM files for the application code, when the bootloader is present, or not present.

https://community.freescale.com/thread/103778

 

Regards,

Mac

 

0 Kudos

820 Views
Seppel
Contributor I

Hi bigmac,

i studied your link, thanks. I could solve the problem with the overlapping by creating 2 different PRM versions as described. When i debug with PEmicro i can see, that on reset my bootloader starts first, check a flag, and jump to app if the flag is zero. Good news so far. But my app doesn't work right :smileysad: And i can't really say, what the reasons for the errors are.

I found out that i have same STACK errors, so i increase the stacksize, what solve one error. Therefor i got a question:how do i have to deal with RAM in bootloader and app project? In my actual bootloader and app project i use the same RAM areas for standard things:

PLACEMENTDEFAULT_RAM                             INTO  RAM;_DATA_ZEROPAGE, MY_ZEROPAGE  INTO  Z_RAM;...END

1) Can i use RAM in this way, or do i have to devide everything into bootloader and app used RAM (especially STACK)?

 

2) How do i have to jump from bootloader to app code? I try different ways that i found in this forum, with c-code and function pointers, up to assembler jumps, but mostly they don't work. F.e. Code:

//suggested in other forum posts:ldhx  #0x7F7F  // Application startup vector -> H:X get 0x7F7Fldhx  ,x       // Fetch vector contents -> Here my H:X is set to 0xFFFF!?! jmp   ,x       // Direct jump to application startup -> because of last command, jump to 0xFFFF -> error//by trying different ways, i found out that jump works with this:      ldhx  #0x7F7F  // Application startup vector -> H:X get 0x7F7Fjmp   ,x       // Direct jump to application startup -> with this i can jump to app at 0x7F7F

With the second code-example i can jump to app, but my app doesn't run correct, could that be the reason (because of don't saving same registers, no PUSH or something like that)? Why do others repeat this ldhx command (first example)?

 

 3)  How can i define  a fixed RAM address for my bootloader_flag, which is knwon in bootloader and app? This flag is set in app and its value must be present after reset (no zero out) in bootloader.

Till now, in bootloade project this var is set into a extra bootloader RAM segment (in PRM), defined with NO_INIT. I try to put it on fixed address with @ command: unsigned char bootloader_flag @0x480; But this became overwrite by standard vars that are also in this RAM segment and which are allocated without @. In app project i have the same RAM segmentation and generate this flag with unsigned char bootloader_flag @0x480; In app its ok to use the @ because this flag is the onliest var i put in this RAM segment. But after reset, in bootloader code this bootloader_flag become Zero -> why? 

 

0 Kudos

820 Views
bigmac
Specialist III

Hello,

 

Since you will require a reset to exit the application, and re-enter the bootloader, the allocation of RAM resources for the bootloader should not matter.  When the application code is entered, it will simply re-allocate the RAM, including the stack, for its own purpose.  Once the application code starts, the bootloader is finished.

 

What does the address 0x7F7F represent?  It cannot be the location of the application's _Startup function since this is not fixed, and it seems inappropriate as a vector location.

 

As an example, let's assume that the bootloader occupies the flash sectors between 0xF700 and 0xFFFF.  For the 9S08DN device, this block should be a multiple of 768 bytes, the flash sector size.  (For most other MC9S08' the multiple would be 512 bytes).  This would mean that the uppermost address for the application code would be 0xF6FF.  It would then be usual for the bootloader, when loading the program, to reposition the application reset vector from 0xFFFE to 0xF6FE.

 

When using the BDM to directly load the application code, this repositioning needs to be taken into account by the linking process for the application.  Within the PRM file, you might invoke  VECTOR ADDRESS 0xF6FE _Startup in lieu of the normal invocation VECTOR 0 _Startup

 

However, should the reset vector already be included within a vector table, this method will not work.  What repositioning method are you using for the vectors other than the reset vector?

 

With the above assumptions, the following assembly code would be required to enter the application's _Startup function.

 

__asm {

   ldhx  #0xF6FE  // Address of repositioned reset vector
   ldhx  ,x       // Vector contents - address of _Startup
   jmp   ,x       // Jump to startup function

}

 

The second method that you mention will not work because the contents at address 0xF6FE-0xF6FF should be a vector value, and not an instruction - this is effectively an indirect jump.  The following method, which has a subtle difference from your second method, should also work for the repositioned vector.

 

__asm {

   ldhx  0xF6FE   // Read contents of repositioned vector
   jmp   ,x       // Jump to startup function

}

 

Before attempting to jump to the application code, it would be worthwhile to modify the above code to check that the vector value has actually been programmed, and contains a value other than 0xFFFF.  If not, the operation should remain within the bootloader.

 

With regard to SOPT, and other write-once system registers, you may leave them at the POR default settings until the application code is commenced.  However, if the default settings are unsuitable for the bootloader operation, you will need to initialise within the bootloader, with settings that also suit the application.  This may include features that are not required by the current version of the application code, but might be required for a future version.

 

Regards,

Mac

0 Kudos

820 Views
Seppel
Contributor I

Yes i found the problem :smileyhappy:

The error was caused by write-once register SOPT1. I have put it to zero in bootloader, because i don't need Watchdog, IIC or STOP or something else in bootloader mode (i have to think about Watchdog in future). But in app i need STOP and IIC. In MCUinit.c in app i initialisized SOPT1 with right values but a secound time, which than is ignored.

 

Really bad error and hard to find, but now everything seems to work fine :smileyhappy: So question 3) is obsolete now, but if you have some info about 1) and 2) please let me know.

0 Kudos