![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
Bootloader question |
Posted: Sun Mar 16, 2014 7:34 am |
|
|
COMPILER: 4.141
PIC: 24HJ128GP306
Hello,
I looked at the CCS example for the bootloader and it is pretty straightforward. However, I do have a question about memory management which I cannot seem to find... or perhaps I'm not understanding something.
In example EX_PCD_Bootloader.c, basically, it's a simple program checks a pin and if high, it jumps to the bootloader section. The actual bootloader code is written at the end of the PIC memory. This example has a simple main() section and that's about it and is written at the beginning of the memory at 0x400. Fair enough.
This is basically similar to what I want in my application. But, this is where I am not sure... If I re-program everytime *that* piece of code that checks the pin at startup, then in a successful upgrade, that code along with my own code would be upgraded... but if anything was to go wrong while doing a firmware upgrade, especially if it is a remote upgrade, then the PIC could become completely unaccessible if the problem occurs while the upgrade is writing that main() function that reads the pin. Understand what I mean?
What I want is that simple program (that reads the pin) along with the bootloader to be written once and only once with the CCS programmer (I have the ICD-U64). Then, all other programming afterwards will be done through the serial port (PINS F4 and F5 using an FTDI cable). After the initial programming with the CCS programmer, the PIC should basically become a device that waits for a firmware upgrade OR starts a piece of code at address X... in other words, the PIC will now be a generic device that has a simple program in it that, when powered-up, checks a pin and if high, starts the bootloader otherwise, runs another program.
When I write my own program (the real program), how do I specify that it should start at some other address? And since my own program also has a main() in it, will it go bonkers after the FW upgrade? Does any of this make sense?
As a test, using the CCS example, I wrote the initial program using the U64 programmer and displayed "Hello world" right after that *if* statement that checks the pin... so, at power-up, if the pin is low, my terminal console writes <Hello world>. Then, I changed to "Hello Benoit" and hit the compile button but this time, I reprogrammed everything using the serial port through the bootloader and it worked - at power-up, if the pins is low it now says "Hello Benoit". However, this is where I'm confused - I don't want to have to overwrite that piece of code intrinsically to the programmer - that initial code should be written once.
Does any of this make sense?
Thanks,
Benoit |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Sun Mar 16, 2014 8:34 am |
|
|
Yes it makes sense to me and I haven't used bootloaders since the 68HC11 dayze! Seems everyone puts blind faith in the bootloader completing the upgrade without problems. Silly things like an EMP 'glitch', soft power supply,bad connection can easily trash the 'upgrade'. If you consider 'BIOS' upgrades on PC, I'm pretty sure they keep the current FW active until the new FW is fully downloaded and verified(checksum OK ?).ONLY after verification does the new FW become the real FW.
Since I haven't used bootloaders on PICs I don't know what 'safety' precautions they use,others will though.
hth
jay |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Sun Mar 16, 2014 9:58 am |
|
|
You don't reprogram the bootloader. This is written once (with a conventional programmer). The main 'runtime' code, does not include the bootloader. Often the bootloader will be written to refuse to overwrite the program area where the bootloader itself is held, and (if this is in low memory - the PIC has instructions to write protect this separately from the rest of the memory), it'll often be write protected. This is why 'low memory' bootloaders are more common than high memory ones on the PIC. Only the PIC24 and later (hence PCD), have the ability to protect the upper memory separately, and hence on these it is worth putting the bootloader here. This also helps since the configuration data is held in the same area, allowing both to be in a similar protected area.
The #BUILD instruction allows you to set 'where' the compiled code locates.
You can do 'transfer then write' bootloaders, where the receive component writes something like an external EEPROM, and then the actual reprogramming is done from this, only if it's checksum is correct, but simply protecting the bootloader, and then having this verify that the write was correct is the simplest approach.
No, people don't rely on the bootloader always being right. It is protected, so it'll still be present, if something does go wrong.
No, main has no 'meaning'. It is just a code name for 'this is where the code is to start'. When you #build, you specify where the initial jump is placed, and _this_ jumps to the 'main' in the code compiled at this point. Once the bootloader jumps to the initial jump location (which has to be where it expects it to be), this then jumps to the new 'main'.
ex_pcd_Bootload.c, shows a program to be loaded _with_ the example bootloader. pcd_bootloader.h, ensures that this won't overwrite the bootloader. |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Mar 17, 2014 6:18 am |
|
|
Hmm... So if the #build instruction sets *where* the code is written, what's the difference with the #org instruction?
PCD_bootloader.h contains these lines:
Code: |
#define LOADER_SIZE 0x3FF
#define LOADER_END ( getenv( "PROGRAM_MEMORY" ) -1 )
#define LOADER_ADDR ( LOADER_END - LOADER_SIZE )
#org LOADER_ADDR, LOADER_END {}
|
Sorry, I know that the CCS documentation and Microchip docs are available but memory management like this is new stuff to me and it's my first attempt at bootloaders so bear with me please.
Ideally, what I want is the following:
1) Initially burn the bootloader somewhere (end?) using the CCS programmer, along with a very simple "main" program that *never* get overwritten such as:
Code: |
void main(void)
{
// On powerup, check if the programming pin is low to enter bootloader
if( input( PROGRAMING_PIN ) == true )
{
printf( "\n\rFirmware upgrade - hit any key to continue..." );
getc();
#asm
goto LOADER_ADDR
#endasm
}
// Run main program since MCU started normally
#asm
goto MAIN_PROGRAM_START
#endasm
}
|
This _IS_ the program that should _ALWAYS_ run at MCU startup. Then...
2) After the burning of the base code above using the CCS programmer, when the MCU is restarted, upload a simple "Hello Ben" (HB) program using the serial port (FTDI to serial adapter);
3) After the HB program is uploaded, restart the MCU while the programming pin is low: at this point, the HB program will run.
4) Change HB to "Good bye" (GB), compile, set the programming pin to high and re-upload that program to the MCU using the FTDI serial adapter and restart the MCU - now the GB program should run.
That sounds fairly easy, it's just a matter I guess of telling the MCU where the HB/GB program will be written.
Does this make sense? What do I need to modify to my code (#build?) to do this?
Note here that the HB/GB are basically a one-line example but in reality, the program I will upload for real is quite a complex program with around 12 separate files and thousands of lines of code. Note that this code and the product are already done and fully functional... The only thing left to add as an extra is the bootloader portion for firmware upgrades if needed.
I cannot provide a CCS programmer to every customer - I want to provide the cheap FTDI cable with every device shipped. That's the easiest solution. So the bootloader is the last thing to implement and I think it should be easy to implement if I can just understand better the entire outfit (which is the reason for asking for help here as opposed to reading the docs - I cannot ask questions to docs!).
Thanks again,
Benoit |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Mon Mar 17, 2014 9:27 am |
|
|
Very different from ORG. As I said it sets where the _initial_ jump to the main code resides. The rest of the code comes after this. You can't #ORG the initial jump.
The bit you have snipped out of bootloader.h, is only used if you are defining a _low memory_ bootloader. Hence the main code is put after this. |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Mar 17, 2014 9:44 am |
|
|
Hi again Ttelmah...
Ok, so, going back to my problem... This is what I'm reading in Microchip's docs (AN1094: Bootloader for dsPIC30F/33F and PIC24F/24H Devices):
"The bootloader target application is located in the dedicated program memory region, starting at address 0x400. On start-up, the bootloader reads program memory address 0xC00, which contains a bootloader delay value. If the bootloader fails to detect UART activity within the time period specified by the delay value, it suspends itself and transfers execution to the user application located at program memory address 0xC02".
Fair enough... but I guess I'm missing something here... Take the most basic program (not even the bootloader, just the most basic a program can be):
Hello.c:
---------------------------------------
#include "HelloWorld.h"
void main( void )
{
fprintf( MONITOR_SERIAL, "\n\rBenoit!" );
while( 1 );
}
---------------------------------------
Hello.h:
---------------------------------------
#include <24HJ128GP306.h>
#fuses HS, WDT, PR, WPOSTS16
#use delay( crystal = 36864000, clock = 73728000 )
#use rs232( UART2, baud=9600, parity=N, bits=8, STREAM=MONITOR_SERIAL, ERRORS )
---------------------------------------
When I compile and run this, I see "Benoit!" on my serial terminal.
The .hex file generated by the program above is this:
:080000001602040000000000DC
:100400003220EF00C3202000008041001040BA00DD
:100410000160EF00000006000A0D000042650000C8
:100420006E6F0000697400002100000081E0A800E8
:1004300034002000243A880024012000343A880047
:100440000E00FC00301020003174200082072000D4
:10045000A3092000824878008348780043E7B7006A
:100460004800DE0021742000620420007305200093
:100470008248780083487800804878000028EF00A0
:100480000400280084118800044020009411880092
:10049000F40E2000C41188002CA3EF002AA3EF0063
:1004A0000FF82300F0FF230020A0B7000000000099
:1004B0000FF82300F0FF230020A0B7000000000089
:1004C00001002000010078000160EF00000202003E
:1004D000000000008100E8003322AF00FEFF37007B
:1004E00034A2B700800020000008E600F5FF3700C6
:0C04F00078020400000000000040FE0044
:0200000401F009
:10000000CF0000FFCF0000FF070000FF800000FFCF
:10001000460000FFDF0000FFE70000FFC30000FF15
:00000001FF
;PIC24HJ128GP306
;CRC=A96F CREATED="17-Mar-14 11:36"
Let's say that _this is_ the program I want to upload using the bootloader, I would assume that somewhere in either the .c file or the .h file I have to specify *where* I want this program to be located in memory, right?
So in the HEX code above, the second line indicates that there are 16 parameters (0x10) and the start address is 0x400. Right there, this is inconsistent with Microchip's explanation: it says the code will check the delay at 0xC00 and if there is such delay and it expires, then it will run the user application at 0xC02. The bootloader should be at 0x400.
So in the case of my application above, I don't have a bootloader so shouldn't the program be at 0xC02? I'm really confused here because my program does start at 0x400, not 0xC02. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Mon Mar 17, 2014 10:01 am |
|
|
bootloader.h does this for you.
If you load this in the bootloader code, it sees that there isn't a define for _bootloader_ (so knows this is the run time code), and for high memory bootloader, there is not a define 'BOOTLOADER_AT_START', (if there is, then it uses #build to locate the start of the code above the bootloader). If the bootloader is at the end, it doesn't have to relocate the initial jumps, and just uses #ORG. |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Mar 17, 2014 10:34 am |
|
|
But what I'm trying to say/explain/understand is since I need a "default program" that checks the input pin to know if it should go in boot loader mode or not, then this program cannot be overwritten hence my second post where I show some code:
Code: |
void main(void)
{
// On powerup, check if the programming pin is low to enter bootloader
if( input( PROGRAMING_PIN ) == true )
{
printf( "\n\rFirmware upgrade - hit any key to continue..." );
getc();
#asm
goto LOADER_ADDR
#endasm
}
// Run main program since MCU started normally
#asm
goto MAIN_PROGRAM_START
#endasm
} |
That line >> goto MAIN_PROGRAM_START <<, I added this... how do I specify where MAIN_PROGRAM_START is located? CCS's original code doesn't specify what to do... there's nothing.
But anyhow, what I'm trying to understand here is the whole concept. What I read in Microchip's docs don't jive with what I'm observing.
Why does the Microchip docs say that the bootloader code starts at 0x400 and the normal program starts at 0xC02 when in fact, just the most basic program starts at 0x400 as shown in my HEX code?
If I don't understand exactly what's going-on, it'll be quite difficult to implement bootloader right?
I realize that the bootloader portion is written at the end of the memory. I can see all of that if I read the entire PIC using the ICD-U64 programmer. But that "main" program that reads the prog pin is starting at 0x400... not 0xC02.
Let me re-explain: basically, I need TWO programs:
1) The first program, the most basic program, checks the prog pin. If HIGH, jump to the bootloader code. If LOW, executes my real program @ 0x?????. This first program with the bootloader code is programmed with the CCS programmer once and once only.
2) The real program - the one that should run if the prog pin is low - that program will be programmed if the prog pin is HIGH and will be programmed using a serial cable. But where??
Going back to program #1: how do I tell it to run the _real program_ if the prog pin is low? If I look at ex_pcd_bootloader.c which is basically program #1 that checks the prog pin, that's basically the first program that starts when the MCU boots. But how does it know where to start MY program? There's nothing after the if statement.
So my real program, should I simply compile it like I do normally but then boot with the bootloader code and "upload" it and it should work? If so, how does the intial program know *where* to load and start my program from?
Not sure how else I can explain this... or if I'm not clear as to what I don't understand?
Last edited by benoitstjean on Mon Mar 17, 2014 11:01 am; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Mar 17, 2014 10:58 am |
|
|
Ok, here's a little exercise I did to perhaps explain better:
I compiled ex_pcd_bootloader.c and burned it to my PIC using the U64 programmer. Note that I added plain text for the sake of knowing where I'm at in the code... so, on power-up, I see this on my serial console:
Hit any key when ready...
At this point, if I read the contents of the PIC using the U64 programmer, the result is a 495,547 bytes-long file with what I presume to be the "main(void)" code starting at address 0x400... here's the line in the dumped hex file:
[...]
:1003E000FFFFFF00FFFFFF00FFFFFF00FFFFFF0019
:1003F000FFFFFF00FFFFFF00FFFFFF00FFFFFF0009
:100400003220EF00C3202000008041001040BA00DD (start of main)
[...]
Now if I scroll down to the very end of this dump, I see the following, which I presume is the bootloader code:
[...]
:10A7E000FFFFFF00FFFFFF00FFFFFF00FFFFFF0075
:10A7F000FFFFFF00FFFFFF00FFFFFF00FFFFFF0065
:10A800004055020001000000FFFFFF00FFFFFF00B6 (start of bootloader)
all the way down to
:10AEB000B01180000000FE00FFFFFF00FFFFFF0059
:10AEC000FFFFFF00FFFFFF00FFFFFF00FFFFFF008E
then it's blank all the way down to 0xAFF0. Fair enough.
Now, this is where I do a "firmware upgrade".
I tie an alligator clip to my prog pin to make it go HIGH and hit spacebar. Then, the serial console displays:
Firmware upgrade - hit any key to continue...
So now, I hit spacebar and now it says:
Upload file NOW
and it just sits there waiting. So, in TeraTerm, I click FILE > SEND FILE and choose "hello_world.hex".
IMPORTANT NOTE: That same "hello_world" application, if I was to compile and burn it alone with the U64 programmer, at power-up, I'd see "Hello world" on my serial console, that's it. And if I do this and look at the hex dump, I will see, again starting at 0x400, the start of THIS program (I can actually find the "hello world" hex character in the hex dump.
But here, the excercise is to program "hello world" using the bootloader...
So, now, I upload the file using TeraTerm through my little FTDI to serial converter. It goes all the way up to 100% and then the PIC reboots.
The result? Nothing!! Nothing gets printed! No "hello world" nor "Hit any key when ready...". Nothing.
At this point, if I now re-read the entire contents of the PIC, the _ONLY_ data starts at address 0xA800 - that's the bootloader code that got programmed initially with the U64 programmer.... but there' no other code nowhere. Everything else has been overwritten.
Does this make more sense? |
|
![](templates/subSilver/images/spacer.gif) |
jeremiah
Joined: 20 Jul 2010 Posts: 1328
|
|
Posted: Mon Mar 17, 2014 10:59 am |
|
|
benoitstjean wrote: |
Why does the Microchip docs say that the bootloader code starts at 0x400 and the normal program starts at 0xC02 when in fact, just the most basic program starts at 0x400 as shown in my HEX code?
|
The main reason is because you as the programmer have not told it to do as the bootloader wishes. The compiler itself has absolutely zero knowledge of a microchip bootloader (or any bootloader), so it cannot know to put the code at 0x0C02. You have to tell it that. That is where what the others have been saying come into play. Things like the #build statement tell the compiler certain things that it needs to know to work with the bootloader. Per comments above, the file bootloader.h has such statements in it
What you want to do is have your selector program happen before the bootloader, but that isn't going to work. At the point your selector program is running you have already been through the bootloader and finished. You can always rewrite the miicrcochip bootloader to use the pin input like you want, but out of the box, it won't work.
EDIT: Also, just as an FYI, the address 0x400 that you are seeing is actually 0x200. The file format is byte addresses. PIC24's address in words, so it is divide file addresses by 2. |
|
![](templates/subSilver/images/spacer.gif) |
jeremiah
Joined: 20 Jul 2010 Posts: 1328
|
|
Posted: Mon Mar 17, 2014 11:13 am |
|
|
As an example, if you told me you wanted a hello world application that was to be run by a bootloader and the bootloader had the following requirements:
1. timeout at 0xc00
2. New firmware starts at 0xc02
3. All firmware interrupts remapped at 0x0c06
4. Crystal frequency = 36864000, but multiplied to 73728000 by PLL
and you haven't given me a bootloader.h
Then I might do the following:
Code: |
#case
#include <24HJ128GP306.h>
#fuses NONE //stops you from overwriting bootloader fuses
#build(reset=0x0C02, interrupt=0x0C06) //tells the compiler this is where the bootloader expects these
#org 0x0000,0x0BFF{} //makes sure you can't write code to the bootloader
#rom int16 0x0C00 = {10000} //timeout value
#use delay( crystal = 36864000, clock = 73728000 )
#use rs232( UART2, baud=9600, parity=N, bits=8, STREAM=MONITOR_SERIAL, ERRORS )
// ---- main program beginning ----
void main()
{
fprintf( MONITOR_SERIAL, "\n\rBenoit!" );
while( 1 );
}
|
Do you see the key differences in code from what I am posting versus what you have posted?
EDIT:
Generated Hex:
Code: |
File Summary:
Filename: pic24_test.hex
File Status: Good
Target Chip: PIC24HJ128GP306
File Type: INHX8 (Intel Hex)
Program Size: 62 Instructions (1%)
Program Range: 0C00-0000, 0BFF-0E73
Checksum: 800A
Config Size: 0 bytes
Created: 17-Mar-14 13:05
Addresses are: Word addresses
Program Memory
000C00: 00002710 00040E14 00000000
000DFE: 00EF2032
000E00: 0020E0A3 00418000 00BA4010 00EF6001
000E08: 00060000 00000D0A 00006542 00006F6E
000E10: 00007469 00000021 0024780F 00247FF0
000E18: 00B7A020 00000000 00A8E081 00200034
000E20: 00883A24 00200124 00883A34 00FC000E
000E28: 00201030 00207431 00200782 002009A3
000E30: 00784882 00784883 00B7E743 00DE0048
000E38: 00207421 00200462 00200573 00784882
000E40: 00784883 00784880 00EF2800 00280004
000E48: 00881184 00204004 00881194 00200EF4
000E50: 008811C4 00EFA32C 00EFA32A 00200001
000E58: 00780001 00EF6001 00020DFE 00000000
000E60: 00E80081 00AF2233 0037FFFE 00B7A234
000E68: 00200080 00E60800 0037FFF5 00040E6E
000E70: 00000000 00FE4000
;PIC24HJ128GP306
;CRC=C2E7 CREATED="17-Mar-14 13:05"
|
And if you look at the hex file in notepad:
Code: |
:0C18000010270000140E0400000000007F
:041BFC003220EF00A4
:101C0000A3E02000008041001040BA000160EF0016
:101C1000000006000A0D0000426500006E6F000023
:101C200069740000210000000F782400F07F240078
:101C300020A0B7000000000081E0A80034002000D0
:101C4000243A880024012000343A88000E00FC0069
:101C5000301020003174200082072000A3092000EA
:101C6000824878008348780043E7B7004800DE00E8
:101C7000217420006204200073052000824878004F
:101C800083487800804878000028EF00040028008E
:101C9000841188000440200094118800F40E200074
:101CA000C41188002CA3EF002AA3EF00010020003C
:101CB000010078000160EF00FE0D0200000000004E
:101CC0008100E8003322AF00FEFF370034A2B700E6
:101CD000800020000008E600F5FF37006E0E0400CB
:081CE000000000000040FE00BE
:00000001FF
;PIC24HJ128GP306
;CRC=C2E7 CREATED="17-Mar-14 13:05"
|
Notice the 1800 address instead of 0x0C00 like I specified. Now multiply 0xC00 by 2. |
|
![](templates/subSilver/images/spacer.gif) |
jeremiah
Joined: 20 Jul 2010 Posts: 1328
|
|
Posted: Mon Mar 17, 2014 11:45 am |
|
|
If instead you told me you were going to use the example bootloader from CCS, with
Crystal frequency = 36864000, but multiplied to 73728000 by PLL
I would suggest the following:
Code: |
#case
#include <24HJ128GP306.h>
#fuses NONE //stops you from overwriting bootloader fuses
#include <pcd_bootloader.h> //sets up app for bootloader
#use delay( crystal = 36864000, clock = 73728000 )
#use rs232( UART2, baud=9600, parity=N, bits=8, STREAM=MONITOR_SERIAL, ERRORS )
// ---- main program beginning ----
void main()
{
fprintf( MONITOR_SERIAL, "\n\rBenoit!" );
while( 1 );
}
|
Hex:
Code: |
File Summary:
Filename: pic24_test.hex
File Status: Good
Target Chip: PIC24HJ128GP306
File Type: INHX8 (Intel Hex)
Program Size: 61 Instructions (1%)
Program Range: 0800-0000, 07FF-0A71
Checksum: 825E
Config Size: 0 bytes
Created: 17-Mar-14 13:41
Addresses are: Word addresses
Program Memory
000800: 00040A12 00000000
0009FC: 00EF2032 0020A083
000A00: 00418000 00BA4010 00EF6001 00060000
000A08: 00000D0A 00006542 00006F6E 00007469
000A10: 00000021 0024780F 00247FF0 00B7A020
000A18: 00000000 00A8E081 00200034 00883A24
000A20: 00200124 00883A34 00FC000E 00201030
000A28: 00207431 00200782 002009A3 00784882
000A30: 00784883 00B7E743 00DE0048 00207421
000A38: 00200462 00200573 00784882 00784883
000A40: 00784880 00EF2800 00280004 00881184
000A48: 00204004 00881194 00200EF4 008811C4
000A50: 00EFA32C 00EFA32A 00200001 00780001
000A58: 00EF6001 000209FC 00000000 00E80081
000A60: 00AF2233 0037FFFE 00B7A234 00200080
000A68: 00E60800 0037FFF5 00040A6C 00000000
000A70: 00FE4000
;PIC24HJ128GP306
;CRC=555A CREATED="17-Mar-14 13:41"
|
|
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Mar 17, 2014 11:55 am |
|
|
Hi Jeremiah,
I need the "selector" program to be the very first thing to start at power-up. That program should never be overwritten.
What you just explained to me sparked something:
The other alternative could be to use the bootloader delay but I'm starting to think that this is not set to anything by default.... is this possible?
In Microchip's AN1094, <TABLE 4 - Boot Delay Configuration>, it indicates that 0xC00 stores the delay for the bootloader and <TABLE 5 - Valid Delay Values> shows that valid values are from 0 to 255, 0 being <Suspend bootloader and transfer execution to the user application>. After a full hex dump, unless I'm reading this wrong, address 0x0C00 is always 0.... which leads me to think that perhaps I should put a value in there?
[...]
:100BF000FFFFFF00FFFFFF00FFFFFF00FFFFFF0001
:100C0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00F0
:100C1000FFFFFF00FFFFFF00FFFFFF00FFFFFF00E0
[...]
Ideally, when the PIC boots, the entire PIC could be blank except for the end portion that contains the bootloader. At power-up, if I have a bootloader delay of 10 seconds and there is UART activity before 10 seconds, then theoretically, the bootloader code will kick-in and store the main application in the right location.... does this make any sense? That would be the most logical way to do it, right? Therefore if the main code gets corrupted, you can always trust that the bootloader code will always work no matter what (assuming that nobody wrote over it). |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Mar 17, 2014 11:58 am |
|
|
Sorry, I re-wrote after you posted your comments. Let me have a look... |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Mar 17, 2014 12:02 pm |
|
|
Regarding your line:
#rom int16 0x0C00 = {10000} //timeout value
I think this is a key element that would prevent me from having to read my PROG_PIN therefore the bootloader would always be available even if the FW upgrade crashed. However, why the value 10000? Valid values are from 0-255 unless the '1' of your 10000 is little endian (I doubt because it's a decimal value). |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|