View previous topic :: View next topic |
Author |
Message |
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
eeprom bootloader |
Posted: Sun Oct 04, 2020 10:00 am |
|
|
Hi all
I'm at a stage in my product where I have too many on the field and manually updating firmware is no longer possible/too much hassle.
I developed a new board, and included 2 eeproms for eventual storage of the new firmware, i have onboard WiFi and GPRS.
I was thinking something like having the devices download the new firmware from an FTP server (open to suggestions), save it on the local eeprom, bootload from eeprom after all pertinent data integrity checks have been made.
The problem is, i have zero experience with boot loaders.
Reference material to read would be much appreciated. Maybe a "hello world" of bootloaders exists so that i may get my hands dirty.
Thanks. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1358
|
|
Posted: Sun Oct 04, 2020 7:14 pm |
|
|
Can you be a bit more specific about what you want to learn about bootloaders? The reason I ask is that the CCS compiler comes with "hello world" style examples for bootloaders already, so I am guessing they are missing something you are looking for.
If you haven't seen the examples, look for ex_bootload.c, ex_bootloader.c, ex_pcd_bootload.c, and ex_pcd_bootloader.c. The reference a driver in the drivers subfolder. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1911
|
|
Posted: Sun Oct 04, 2020 9:05 pm |
|
|
Look at Brush Electronics. They have a number of proven bootloaders.
No affiliation, just a satisfied customer. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9249 Location: Greensville,Ontario
|
|
Posted: Mon Oct 05, 2020 4:26 am |
|
|
I haven't used bootloaders since my 68HC11 daze, but think that 2 EEPROMs (or one with 2 'banks') would be necessary. One would store the old, current version, the other the new,downloaded one. That way if for any reason the 'new' version didn't function properly, you could go back to the 'old' version.
I think this is how PC BIOS EEPROMs work. They can be upgraded ove rthe Internet but yeesh ANYTHING could corrupt the data or worse case a power failure.
Whatever method or tech you use, bench testing is vital .
Obvious that the software version number needs to be embedded in the code,perhaps displayed during the products reboot 'flash' screen ?
Jay |
|
|
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Mon Oct 05, 2020 1:37 pm |
|
|
Hi Thanks for the replies.
How do i know how much memory i need to separate for the bootloader?
From the Main() i need to call another function which will act as the applications main instead of the real main?
What file from my compilation do i need to send it? Just straight .hex?
The hex file on my computer is 248kb yet my pic is a 128kb chip... how does that work?
Do i need to give the new program file a specific format? do i need software to prep the hex file into a bootloadable file?
Just imagine being me, with a brain paralyzed with ignorance and fear of the unknown when it comes to approaching bootloaders.
Thanks. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1358
|
|
Posted: Mon Oct 05, 2020 6:13 pm |
|
|
Are we talking PIC24, PIC18, etc.? Did you check the examples that come with CCS as well. Any reservations based on what you see there?
Gabriel wrote: | Hi Thanks for the replies.
How do i know how much memory i need to separate for the bootloader?
From the Main() i need to call another function which will act as the applications main instead of the real main?
What file from my compilation do i need to send it? Just straight .hex?
The hex file on my computer is 248kb yet my pic is a 128kb chip... how does that work?
Do i need to give the new program file a specific format? do i need software to prep the hex file into a bootloadable file?
Just imagine being me, with a brain paralyzed with ignorance and fear of the unknown when it comes to approaching bootloaders.
Thanks. |
I'll try to address each of these the best I can:
* For how much memory I need for a bootloader, I start with a #org statement and guess and the compiler tells me if I am too little. Notice the two "wrapper" #org statements and their relation to #use and functions.
Code: |
#include <24FJ1024GB606.h>
#org 0x200,0x2ff default
#use delay(clock=8MHz)
#use rs232(ICD,DISABLE_INTS)
void main() {
delay_ms(1000);
printf("hello world\r\n");
while(TRUE);
}
#org default
|
* For how to call the application, I just looked at the CCS example and they used:
Code: |
#org APPLICATION_START
void application(void)
{
while(TRUE);
}
void main(){
// bootloader stuff
application();
while(TRUE);
}
|
Alternately you can just use assembly:
Code: |
#asm
CALL APPLICATION_START
#endasm
|
* It uses hex files normally, but you are certainly able to use any format you want as long as you code it to accept that format. All the examples you find will most likely be hex files.
* For hex file size, keep in mind that the hex file is a text file, so it is much bigger than the binary data it represents. The file size is probably fine. Your loader will hopefully eventually be able to catch if a file is too big when trying to save it to eeprom.
* You shouldn't need to prep the hex file at all, you can probably do everything you need using CCS preprocessor directives (see #build for a lot of them). This is a bigger discussion topic, so maybe we can whittle this into specific parts as the thread continues. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1358
|
|
Posted: Mon Oct 05, 2020 6:35 pm |
|
|
Here's a simple example of all that from above. It is PIC24 specific. It doesn't include any of the code that reads in the HEX or stores it, but shows a basic bootloader skeleton with comments:
bootloader.c
Code: |
#include <24FJ1024GB606.h>
// Important constants that both the bootloader and any client applications
// need to know
#define APPLICATION_START 0x800
#define BOOTLOADER_START 0x200
#define BOOTLOADER_END (APPLICATION_START - 1)
#fuses NODEBUG, NOWDT
// Start of the bootloader. All H files, #use, #device, #build, etc
// should go below this line and before the closing #org default at the end.
// This places all code between BOOTLOADER_START and BOOTLOADER_END
#org BOOTLOADER_START,BOOTLOADER_END default
// Bootloaders can use any parameters here, application code wants to
// only do #use delay(clock=8MHz) to avoid having it generate fuses.
#use delay(internal=8MHz)
#use rs232(ICD,DISABLE_INTS)
// This is for the allowing the application to use interrupts. It points
// to a jump table to the application. The application will use #build
// to set this up on the application side.
#INT_DEFAULT FAST
void isr_relocate(){
jump_to_isr(APPLICATION_START+4);
}
void main() {
delay_ms(1000);
printf("hello world\r\n");
// need some sort of code to read in your HEX file, check it for
// validity, and then store it as you desire.
// If everything goes well start the application
#asm
CALL APPLICATION_START
#endasm
while(TRUE);
}
#org default
|
and an application designed to use it:
application.c
Code: |
#include <24FJ1024GB606.h>
// Important constants that both the bootloader and any client applications
// need to know
#define APPLICATION_START 0x800
#define BOOTLOADER_START 0x200
#define BOOTLOADER_END (APPLICATION_START - 1)
#FUSES NONE //NO FUSES!
#use delay(clock=8000000) //Make sure #use delay doesn't put any FUSES either
// Tell compiler to put code and interrupts in application space
#build(reset=APPLICATION_START,interrupt=APPLICATION_START+4)
// Tell compiler not to use bootloader space
#org 0,BOOTLOADER_END{}
void main(void){
while(TRUE);
}
|
These generate the following hex files:
bootloader:
Code: |
File Summary:
Filename: D:\__workspaces\PCWHD\Test_PCWHD\main.hex
File Status: Good
Target Chip: PIC24FJ1024GB606
File Type: INHX32 (Intel Hex)
Program Size: 241 Instructions (1%)
Program Range: 00000-002E3
Checksum: 4B1C
Config Size: 96 bytes
Created: 05-Oct-20 20:37
Addresses are: Word addresses
Program Memory
000000: 0004026E 00000000
000006: 00000808
000008: 0000080C 00000810 00000814 00000818
000010: 0000081C 00000820 00000824 00000828
000018: 0000082C 00000830 00000834 00000838
000020: 0000083C 00000840 00000844 00000848
000028: 0000084C 00000850 00000854 00000858
000030: 0000085C 00000860 00000864 00000868
000038: 0000086C 00000870 00000874 00000878
000040: 0000087C 00000880 00000884 00000888
000048: 0000088C 00000890 00000894 00000898
000050: 0000089C 000008A0 000008A4 000008A8
000058: 000008AC 000008B0 000008B4 000008B8
000060: 000008BC 000008C0 000008C4 000008C8
000068: 000008CC 000008D0 000008D4 000008D8
000070: 000008DC 000008E0 000008E4 000008E8
000078: 000008EC 000008F0 000008F4 000008F8
000080: 000008FC 00000900 00000904 00000908
000088: 0000090C 00000910 00000914 00000918
000090: 0000091C 00000920 00000924 00000928
000098: 0000092C 00000930 00000934 00000938
0000A0: 0000093C 00000940 00000944 00000948
0000A8: 0000094C 00000950 00000954 00000958
0000B0: 0000095C 00000960 00000964 00000968
0000B8: 0000096C 00000970 00000974 00000978
0000C0: 0000097C 00000980 00000984 00000988
0000C8: 0000098C 00000990 00000994 00000998
0000D0: 0000099C 000009A0 000009A4 000009A8
0000D8: 000009AC 000009B0 000009B4 000009B8
0000E0: 000009BC 000009C0 000009C4 000009C8
0000E8: 000009CC 000009D0 000009D4 000009D8
0000F0: 000009DC 000009E0 000009E4 000009E8
0000F8: 000009EC 000009F0 000009F4 000009F8
000200: 00EF2054 002020C3 00418000 00BA4010
000208: 00EF6001 00060000 00006568 00006C6C
000210: 0000206F 00006F77 00006C72 00000D64
000218: 0000000A 00FEA000 00FE8000 00064000
000220: 00E00000 00AF2042 00370004 00090F9B
000228: 00000000 00E90000 003AFFFC 00060000
000230: 00781F85 00BFC042 00B7E00A 00A9E081
000238: 00200E04 00880214 00A8E081 00A90676
000240: 00A9067A 00200083 00090064 00000000
000248: 00D7E802 00AF0042 00A8067A 00AE0042
000250: 00A9067A 0009005F 00000000 00E90183
000258: 003AFFF7 00A8067A 00090066 00000000
000260: 00A9E081 00F80042 009FFFE5 00F90042
000268: 00A8E081 007802CF 00060000 0027F80F
000270: 0027FFF0 00B7A020 00000000 00A8E081
000278: 00200000 00882640 002FFFF0 00882650
000280: 00EF210C 00EF2102 00FC000E 00201000
000288: 00201011 00200782 002009A3 00784882
000290: 00784883 00B7E101 00DE0048 00201001
000298: 00200462 00200573 00784882 00784883
0002A0: 00784880 00A90676 00A8067A 0020FA00
0002A8: 00020220 00000000 00EF267E 00EF2692
0002B0: 00EF26A6 00EF26BA 00EF26CE 00EF26E2
0002B8: 00203E80 00020220 00000000 00200001
0002C0: 00780001 00EF6001 00020200 00000000
0002C8: 00E80081 00781F81 00B7E802 00020230
0002D0: 00000000 007800CF 002000C0 00E60800
0002D8: 0037FFF3 00020800 00000000 000402DE
0002E0: 00000000 00FE4000
Configuration Words
0ABF00: 00FFFFFF 00FFFFFF 00FFFFFF 00FFFFFF
0ABF08: 00FFFFFF 00FFFFFF 00FFFFFF 00FFFFFF
0ABF10: 00FFFFFF 00FFFFFF 00FF7FFF 00FFFFFF
0ABF18: 00FFFFF8 00FFFFFF 00FFFFF3 00FFFFFF
0ABF20: 00FFFF9F 00FFFFFF 00FFFFFF 00FFFFFF
0ABF28: 00FFFFDF 00FFFFFF 00FFFFFF 00FFFFFF
Program Memory
;SETTINGS MONITOR=38400
;PIC24FJ1024GB606
;CRC=486C CREATED="05-Oct-20 20:37"
|
application.c
Code: |
File Summary:
Filename: D:\__workspaces\PCWHD\Test_PCWHD\main.hex
File Status: Good
Target Chip: PIC24FJ1024GB606
File Type: INHX8 (Intel Hex)
Program Size: 20 Instructions (1%)
Program Range: 00800-00A1F
Checksum: 4829
Config Size: 0 bytes
Created: 05-Oct-20 20:34
Addresses are: Word addresses
Program Memory
000800: 000409FC 00000000
0009FC: 0027F80F 0027FFF0
000A00: 00B7A020 00000000 00A8E081 00200000
000A08: 00882640 002FFFF0 00882650 00EF267E
000A10: 00EF2692 00EF26A6 00EF26BA 00EF26CE
000A18: 00EF26E2 00040A1A 00000000 00FE4000
;PIC24FJ1024GB606
;CRC=B307 CREATED="05-Oct-20 20:34"
|
|
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
Re: eeprom bootloader |
Posted: Mon Oct 05, 2020 10:46 pm |
|
|
Gabriel wrote: | Hi all
I'm at a stage in my product where I have too many on the field and manually updating firmware is no longer possible/too much hassle.
I developed a new board, and included 2 eeproms for eventual storage of the new firmware, i have onboard WiFi and GPRS.
I was thinking something like having the devices download the new firmware from an FTP server (open to suggestions), save it on the local eeprom, bootload from eeprom after all pertinent data integrity checks have been made.
The problem is, i have zero experience with boot loaders.
Reference material to read would be much appreciated. Maybe a "hello world" of bootloaders exists so that i may get my hands dirty.
Thanks. |
Hi Gabriel,
A few other things to consider.
When the user application is part of the bootload process, in your example downloading the file from an FTP server, what happens if you have a bug in the application you are bootloading that prevents you downloading a new image? In this scenario your target could potentially be bricked requiring a return for support.
There are many ways to deal with this type of problem, the approach I have taken for a network bootloader is to split the bootload process between a PC application and the bootloader code on the PIC. The PC programmer application is the master and is responsible for error recovery. The PC programmer application forwards a record to the PIC bootloader to program and waits for a successful acknowledgment before sending the next record. In the event of an error message being returned or no return at all, it repeats the last record until all records have been successfully programmed. Another characteristic of this bootloader is that the PIC will remain in bootloader mode until it has successfully finished the bootload process. In the event of a power failure, on recovery of the power, the PIC will boot up and remain in bootloader mode. This way it is really difficult to brick this type of bootloader.
In your specific example with two EEPROMs, you can implement a fall back approach provided you add sufficient intelligence into the bootloader to not enable programing one bank if the other bank does not have a valid image. This avoids having two dud images. However you still have to deal with the case that the new image is valid but has a bug, how can you then bootload the alternative image?
One issue with using a hex file is it is very large, between 4 and 10 times the size of a standard hex file. This is very easy to see, when you compile the application, look at the amount of program memory used by the application and compare it to the size of the hex file. As a result, storing hex files in EEPROM is inefficient. It also means the process of transferring the file takes much longer because the file size if larger than a binary image and therefore you are more exposed in this process. You might want to consider transferring binary data as opposed to a hex file.
Another thing to consider is do you use a bootloader that performs an entire program memory bootload or only partial bootload. For example if you had configuration data you wanted to update but the application does not require being upgraded, then you want a different type of bootloader. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9249 Location: Greensville,Ontario
|
|
Posted: Tue Oct 06, 2020 4:52 am |
|
|
hmmm. I'm wondering if there should be some kind of 'timer' for the download. Say 'worse case' is 5 minutes to download the new program. Have the 'timer' abort the download after 6 minutes. After 3 unsuccessful tries in say 1/2hr abort the download process until 'later'....
This would get you out of an infinite loop of trying to download the new program. |
|
|
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Tue Oct 06, 2020 4:28 pm |
|
|
Thank you all for your help.
This is for PIC18.
I still do not understand what file i need to load on the eeprom (in my case).
In my folders i do not see any binary files, just the .hex and other MPLAB files.
Which brings me back to my question of how a 248k byte hex file fits in a 128kb flash. I'm missing a key point, a simple point im sure, but I'm missing it.
Thank you. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 06, 2020 6:21 pm |
|
|
See this page for the hex file format:
https://www.keil.com/support/docs/1584/
The hex file consists of ASCII bytes. It takes two ASCII bytes to
represent one byte of actual data. That's the main part of the answer.
In addition to that, it takes several more ASCII bytes to describe the
data in each line of the hex file. This is described in the link above. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1358
|
|
Posted: Tue Oct 06, 2020 6:38 pm |
|
|
Gabriel wrote: | Thank you all for your help.
This is for PIC18.
I still do not understand what file i need to load on the eeprom (in my case).
In my folders i do not see any binary files, just the .hex and other MPLAB files.
Which brings me back to my question of how a 248k byte hex file fits in a 128kb flash. I'm missing a key point, a simple point im sure, but I'm missing it.
Thank you. |
The hex file is a text file. You can open it in notepad. A single binary byte in a binary file can hold 0-255 in it using 8 bits. To represent 255 in a text file you need 3 characters each 8bits in size for 24 total bits (or 2 bytes to store the hex version of FF). Text is bigger than binary even if they contain the same notional data.
Most bootloaders I have used just read in the hex file and convert it to the smaller binary representation as part of the process. |
|
|
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Wed Oct 07, 2020 6:02 am |
|
|
Thank you for your replies, i should have known better regarding the ascii hex representation vs the actual hex.... this is what happens when your brain locks up.
That hex file explanation link was awesome! Thanks!
So, i guess my next step is to figure out how the flash writing routine works. I have a clearer picture now.
I'll have more questions soon enough! _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19554
|
|
Posted: Wed Oct 07, 2020 9:27 am |
|
|
If you look at the standard bootloader code, it has the routines that extract
the hex into a buffer and decode this, then write this to the program memory. |
|
|
|