View previous topic :: View next topic |
Author |
Message |
gilavar
Joined: 03 Mar 2009 Posts: 24
|
Question about bootload in PIC24FJxxx |
Posted: Thu Jul 09, 2009 12:52 pm |
|
|
In my application I am using two devices. PC connected to the station via USB. I am using FTDI (232RL) with PIC24FJ32-004 to host the remote devices via custom 1-wire protocol. In remote devices I am using PIC24FJ16-002.
Boatloads on both, station and remote devices needed for the future firmware updates. Download of the latest firmware and the bootload activated by the application itself as a menu function.
To do this, I decided to go with my own code in the predefined memory block closer to the end of the memory. In updates I am planning to #ORG this section to protect it from any accidents and #define fixed address of the bootload function. I will keep all custom communication routines within bootloader block.
I would appreciate if some of PICC gurus will give me a hint on the problems I am facing.
Another question is about write_memory function. It is very fuzzy in manuals how big is the block to be erased. The way I see it for PIC24FJ32, function erasing 0x400 blocks. In other words if I will write to 0x0000 then erased block will be 0x0000~0x03FF, next block 0x0400~0x07FF and so on. Is this correct? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Jul 09, 2009 2:56 pm |
|
|
Yes, the PIC24FJ code page and erase size is 0x400 words (the usual way to count PIC24 addresses) respectively 0x800 bytes (which is the address metric of hex-files).
In my opinion, a PIC24 bootloader layout should be implemented according to Microchip AN1157 in the bottom code pages, because this is the only way to achieve a fail safe protection of reset vectors. |
|
|
gilavar
Joined: 03 Mar 2009 Posts: 24
|
|
Posted: Thu Jul 09, 2009 4:59 pm |
|
|
You right, I forgot about 16+8 word configuration. Does that mean erasable block of memory address will be 0x0000~0x07FF; 0x0800~0x15FF and so on?
In this case I can’t write for example in the middle of the block at address 0x0400 without erasing entire block 0x0000~0x07FF, correct?
Application do not need to start-up through the bootloader and I were planning to locate my bootloader in 0X4800~0x55FF block. I sought in this case I am not interfering with the reset vectors, interrupts and fuses and can update them any time. In other words bootloader will be called only from the main function of already running application with goto (address). As soon as pointer goes to the bootloader address, i am planning to disable all the interrupts and peripherals working only with the IO pin for one-wire. Do you think I still have to take care of the reset vectors in this case? |
|
|
gilavar
Joined: 03 Mar 2009 Posts: 24
|
|
Posted: Thu Jul 09, 2009 5:47 pm |
|
|
OK, now it is more confusing. Checking the PIC’s datasheet (page 41 [4.0]) were:
With RTSP, the user may write program memory data in blocks of 64 instructions (192 bytes) at a time, and erase program memory in blocks of 512 instructions (1536 bytes) at a time.
512 instructions with two address location each sending me back to 0x400. Is there something I do not understand about fourth blank byte? |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Thu Jul 09, 2009 7:03 pm |
|
|
gilavar wrote: | OK, now it is more confusing. Checking the PIC’s datasheet (page 41 [4.0]) were:
With RTSP, the user may write program memory data in blocks of 64 instructions (192 bytes) at a time, and erase program memory in blocks of 512 instructions (1536 bytes) at a time.
512 instructions with two address location each sending me back to 0x400. Is there something I do not understand about fourth blank byte? |
It is a phantom byte. The main reason to put the bootloader, implemented in C, in low memory is because some compilers expect the startup code to be located in the first 64K bytes of program memory. A bootloader implemented in assembler has not such limitation.
Quote: | In my opinion, a PIC24 bootloader layout should be implemented according to Microchip AN1157 in the bottom code pages, because this is the only way to achieve a fail safe protection of reset vectors. |
From my perspective, other than the startup issue already mentioned, the location of the bootloader can be anywhere in program memory, as long as it does not overlay the Erase page containing the reset vector. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Jul 10, 2009 12:52 am |
|
|
As said, the code page size is 0x400 words (or 0x200 instructions). Due to the 24 bit instructions size, there is a dummy byte included in each double-word, but you don't have to care for it, except when using program memory for data storage.
Quote: | The main reason to put the bootloader, implemented in C, in low memory is because some compilers expect the startup code to be located in the first 64K bytes of program memory. | It may be an additional reason, but not with PIC24. In my opinion, the only serious reason is full protection against bootloader corruption, which requires to protect the reset vector, too.
Regarding assembler coding of bootloader: As far as I see, PCD assembler misses yet important elements to control reset and interrupt vectors. So this option isn't fully accessable now without using Microchip tools. |
|
|
gilavar
Joined: 03 Mar 2009 Posts: 24
|
|
Posted: Fri Jul 10, 2009 12:56 am |
|
|
FvM wrote: | As said, the code page size is 0x400 words (or 0x200 instructions). Due to the 24 bit instructions size, there is a dummy byte included in each double-word, but you don't have to care for it, except when using program memory for data storage.
Quote: | The main reason to put the bootloader, implemented in C, in low memory is because some compilers expect the startup code to be located in the first 64K bytes of program memory. | It may be an additional reason, but not with PIC24. In my opinion, the only serious reason is full protection against bootloader corruption, which requires to protect the reset vector, too.
Regarding assembler coding of bootloader: As far as I see, PCD assembler misses yet important elements to control reset and interrupt vectors. So this option isn't fully accessable now without using Microchip tools. |
Great, thank you guys! |
|
|
jer Guest
|
interrupt vectors |
Posted: Fri Sep 04, 2009 11:51 am |
|
|
If you protect the first block containing the reset vector and the interrupt vectors but then try to load a different firmware through the bootloader which uses a different interrupt configuration how can the bootloader modify the interrupt vector table? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Sep 04, 2009 12:18 pm |
|
|
Some aspects of PIC24 bootloader layout have been discussed in previous threads, e.g.:http://www.ccsinfo.com/forum/viewtopic.php?t=36155
Regarding interrupt vectors in a failsafe (bottom located) bootloader, Microchip's AN1157 discusses the possible options. Generally, you can't modify the interrupt vector table, so you have to use either fixed ISR addresses in the application code or redirect the interrupts from ISR stubs in the bootloader using a second vector table in the application code.
The latter variant is slower and doesn't work with PCD due to some restrictions in the assembler functionality, as far as see. The PCD assembler e.g. lacks the option to place jumps to code labels in the assembly code, also it can't include arbitrary data.
The first variant (fixed ISR addresses) works fine, you must decide however, which ISRs are to be supported when fixing the bootloader. |
|
|
Jer Guest
|
|
Posted: Wed Sep 09, 2009 9:49 am |
|
|
Let me see if I am understanding you right. I was going to put all my #int definitions in my bootloader area and just have them call a function outside of the bootloader area, but you are saying this won't work? I suppose because there isn't a fixed address to jump to. So I have to do a bunch of #org's to fix the ISR routines outside of the bootloader. How do I set up the vector table to jump to those addresses? |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Wed Sep 09, 2009 10:04 am |
|
|
I leave the IVT untouched by the bootloader and available for use by the user application.
There is a possibility that the page containing the reset vector could be corrupted but, to put this into perspective, I have hundreds of devices in the field using this method and countless products deployed by my customers using my bootloaders. I had not experienced a failure as a result of corruption of the page containing the reset vector. Neither have I had bug reports from customers to this effect.
The advantage with my approach is that you can bootload a replacement bootloader. I had a project in outback Australia a few years back where system software was upgraded via GSM radios. There was a problem in the field because the signal would drop in and out and the bootloader would often fail the bootload process prematurely. The solution was to upgrade all the bootloaders in the field (about 40) this required compiling a temporary bootloader that sat in the user application space. When the original bootloader passed control to the user application (in this case the interim bootloader) the interim was then used to replace the original bootloader. This flexibility is not available for bootloaders that are inside a protection block.
No single approach suits everyone. You need to balance the pros and cons for your environment. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Sep 09, 2009 11:17 am |
|
|
Quote: | So I have to do a bunch of #org's to fix the ISR routines outside of the bootloader. How do I set up the vector table to jump to those addresses? | Yes, that's a straightforward way to do it. The method is discussed as "Option A: Direct Mapping to ISR" in Microchip's Application Note AN1157.
In the bootloader application, I have dummy ISRs to set the IVT addresses. The main application has to use the same ISR offset's of course. If the predefined size isn't sufficient, an ISR can be extended by function calls.
Code: | #org APP_BASE+0x100, APP_BASE+0x17f
#int_RDA
void RDA1_isr(void)
{
}
#org APP_BASE+0x180, APP_BASE+0x1ff
#int_TBE
void TBE1_isr(void)
{
} |
|
|
|
Jer Guest
|
|
Posted: Wed Sep 09, 2009 3:15 pm |
|
|
Thanks, I think I've got that right now, one more question:
where are CONST variables stored in memory? I noticed the list file ignores them so I am assuming they get stored in configuration memory space or something? does this mean they are unable to be modified by a bootloader? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Sep 09, 2009 11:18 pm |
|
|
Constants are stored in regular code memory, near the individual system function that is called to read it. You can trace it in the *.lst file, after commenting out the #nolist directive at top of the header file. No special measures are needed regarding const usage with bootloader. |
|
|
|