View previous topic :: View next topic |
Author |
Message |
Glen Guest
|
questions about bootloader and reset vector locations... |
Posted: Fri Jul 31, 2009 3:36 pm |
|
|
I've looked through the forum topics but didn't see this answered:
The example bootloaders that I've seen seem to be designed to reside at location 0 in memory, and relocate the reset and interrupt vectors to new locations at the end of the bootloader. It's not clear to me why it is done this way. Would it be possible to leave the vectors where they are and just start the bootloader after them, i.e. #org 0x20, 0x7F, and then have the application reside above that? I'm sure this probably has already been discussed to death somewhere, but I didn't find it when searching...
thanks,
Glen |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Glen Guest
|
hmmm... |
Posted: Fri Jul 31, 2009 4:18 pm |
|
|
Thanks, I read that discussion and it explains the differences between locating the bootloader in low vs. high memory. But it still isn't clear if I could locate it in low memory but after the interrupt vectors. As it seems that it's possible to locate the bootloader wherever you want in memory, why start it at zero, thus forcing the relocation of the vectors...
Thanks,
Glen |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
Re: hmmm... |
Posted: Sat Aug 01, 2009 9:14 am |
|
|
Glen wrote: | Thanks, I read that discussion and it explains the differences between locating the bootloader in low vs. high memory. But it still isn't clear if I could locate it in low memory but after the interrupt vectors. As it seems that it's possible to locate the bootloader wherever you want in memory, why start it at zero, thus forcing the relocation of the vectors...
Thanks,
Glen |
Not all bootloaders force the interrupt vectors to be remapped. Configuring a high bootloader is straight forward, you preserve the memory for the reset vector and place the rest of the bootloader in high memory. It get murly when the bootloader is programmed in a high level language, such as C, as lots of implementations expect the C start up code to be located in the first 64K of program memory.
With bootloaders residing in low memory, you need to be careful with applications that are very latency sensitive. For some applications they cannot tolerate a jump at the interrupt vector. Instead the interrupt handler starts immediately at the vector location. In this case you need to ensure that the bootloader has left enough program space free above the vestor to enable the handler to reside completely below the bootloader. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
Glen Guest
|
|
Posted: Sat Aug 01, 2009 3:05 pm |
|
|
Andrew, thanks for the response. Yes, it looks like the compiler wants to place the entire ISR starting at the interrupt vector address. So as long as I leave enough room for the ISR before starting the bootloader, and then leave enough room for the bootloader before starting the main application, everything should work...
Thanks,
Glen |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Tue Aug 04, 2009 11:44 am |
|
|
One important point that was missed here is (but not in the PCM referenced thread):
Look at the PIC you're using and how it protects code.
PIC parts have different programming/locking capability.
You might want to put your bootloader in a memory range that you can write protect (even from itself). And this can be different from PIC to PIC.
As for the interrupt vector, that might be included in that protection range (which also includes the INIT vector at 0x000)... so consider that carefully as well.
I just went through this designing something. It made sense to have the bootloader in low memory with IRQ vectors remapped.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
Guest
|
|
Posted: Thu Aug 06, 2009 12:17 pm |
|
|
Ben, thanks for your input. From what I can tell, it looks like the main reason to relocate the reset and interrupt vectors would be as you mention, so you can write protect the boot block but still be able to change the vectors. I'm less concerned about write protection so I think leaving the vectors in their original positions will work.
Another question though: I want the boot loader to be able to jump to the main application after it is done loading. How do I locate the main code so that I know where to jump to? Even though I #org the main application at a known address, the compiler locates the starting location somewhere else. If I look at the reset vector generated by the compiler for the main application, it is pointing off into high memory. I tried doing a #build(reset=...) to place the main applications' reset vector at a known location, then have the boot loader jump to that location on completion, but that didn't work either. Any suggestions?
thanks,
Glen |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Thu Aug 06, 2009 12:37 pm |
|
|
Anonymous wrote: |
Another question though: I want the boot loader to be able to jump to the main application after it is done loading. How do I locate the main code so that I know where to jump to? Even though I #org the main application at a known address, the compiler locates the starting location somewhere else. If I look at the reset vector generated by the compiler for the main application, it is pointing off into high memory. I tried doing a #build(reset=...) to place the main applications' reset vector at a known location, then have the boot loader jump to that location on completion, but that didn't work either. Any suggestions?
|
Both the bootloader and the real application have a #org at the start where the application goes.
In bootloader.c there's a function:
Code: |
// ==============================================================
// This places bogus application at 800
// that gets overwritten when the real application is loaded into memory.
//
#org APP_ADDR,APP_END
void application(void) {
fprintf(COMM, "No Application to Run\r\n");
}
|
This puts in "bogus" code in case there's no application to at least run and say, "Hey! There's no application to run!" so the user knows.
The real application is set to program right over that... so there's an application to run!
On a slight tweak to the bootloader, I put in kbhit checks to see if '0' is pressed to reboot the PIC so I can go back and actually put in the program. (instead of power cycling) -- this is a feature consider on memory availability.... but you get the idea. You can have all sorts of fun.
You can check some spot in memory (or block) that you KNOW won't == all 0xFF (empty prog space) to determine something is loaded...
I'm rambling.. you get the idea.
Cheers,
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
Guest
|
|
Posted: Thu Aug 06, 2009 5:04 pm |
|
|
I've been playing around with that approach, but it seems to be very picky about where the #org statement goes. If I have any #include files between the #org and main(), then main won't be located where I would like it. If I put the #org immediately before main(), then the compiler complains that I run out of ROM space. I'm guessing that's because all of the stuff prior to main() doesn't get put where it should. I'm still wrestling with it...
Thanks for your help!
Glen |
|
|
Guest
|
|
Posted: Thu Aug 06, 2009 9:10 pm |
|
|
Well, I ended up getting a little more creative with my solution. I modified the bootloader to watch for the reset vector address when the main application is downloaded. I extract the address and store it in a known location in program memory. On power-up I read the location, if it is 0xFFFF then I know there is no application loaded so I remain in the bootloader. If it is not 0xFFFF then it must be the start vector address of the application, so I jump to it. It seems to work so far...
Thanks for your help,
Glen |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Thu Aug 06, 2009 9:35 pm |
|
|
No problem...
It's not such a cut-and-dried task typically.. so a little thought and massage to what you want isn't just a surprise -- it's more expected.
Have fun with it!
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
cassioriguela
Joined: 25 Oct 2011 Posts: 27
|
|
Posted: Fri Dec 02, 2011 6:35 am |
|
|
Sorry about wake up topic.
I have a issue about it. How can I remap the reset vector ? I tried remapping reset vector with #build instruction but it doesn't work. After reset, my program doesn't get work. I can do it with #ORG instruction, but is it correct ?
Thanks ! |
|
|
|