Shop OBEX P1 Docs P2 Docs Learn Events
Possible to partially update boot EEPROM? — Parallax Forums

Possible to partially update boot EEPROM?

sccoupesccoupe Posts: 118
edited 2014-06-11 07:00 in Propeller 1
The concept seems pretty straight forward to update the boot EEPROM (32kbyte). Keeping a boot loader at the beginning of the hex file that would never be over written seems to be the tricky part as the compiler may recompile things different with small changes. The thought was to have a boot loader portion of the code that would wait for a serial command to either execute the rest of the code or to go into an EEPROM write mode to start accepting serial data and writing it byte by byte to the EEPROM starting at the address that is at the end of the boot load code. Is this possible? I know that the entire EEPROM can easily be done this way, but if it fails then the device will no longer work. Leaving a boot loader intact would allow for further tries to field update code. Thoughts?

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-06-04 10:24
    Cluso99 does something like this.

    I'm pretty sure this sort of thing (preserving a bootloader) is possible but it's not possible to preserve a section of the lower 32K of the EEPROM.

    IIRC, the systems doing this sort of thing keep the programs on a SD card and the EEPROM program is used to load the desired program from the SD card. It's also possible to have a program stored in upper EEPROM which gets loaded into RAM by the bootloader code.

    To protect the EEPROM the write protect pin is held high (I think). I'm not sure how the program can be changed in the UPPER EEPROM if the WP is high. I don't think it can. I think if you write protect the EEPROM you can only write new programs to the SD card.

    I'm pretty sure Cluso99 has a system which works well for this sort of stuff. I think there are other bootloader systems around. I think any bootloader which protects the part of the EEPROM has to have the whole EEPROM write protected. It's possible to have more than one EEPROM. You can use the address pins to assign it a different I2C address. You bootloader could write the new program to this alternate EEPROM which isn't write protected.
  • sccoupesccoupe Posts: 118
    edited 2014-06-04 10:41
    Thanks Duane,

    I'm not looking specifically to write protect the EEPROM, I'd just like to update part of it and leave a bootloader intact incase there are write issues. So, if I include a boost loader in my code, can this be kept in the first part of the hex file so that I can just start writing hex to the part after the boot loader, unless of course there is some kind of checksum that the propellor requires to be correct of it is to start running the code on the next reboot.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-06-04 10:59
    sccoupe wrote: »
    Thanks Duane,

    I'm not looking specifically to write protect the EEPROM, I'd just like to update part of it and leave a bootloader intact incase there are write issues. So, if I include a boost loader in my code, can this be kept in the first part of the hex file so that I can just start writing hex to the part after the boot loader, unless of course there is some kind of checksum that the propellor requires to be correct of it is to start running the code on the next reboot.

    I'll just add an "I don't know" so you don't think I'm ignoring the question. It seems like something like this should be possible but I'll let someone more knowledgeable on the topic elaborate on how (if it's possible) it can be done.
  • MagIO2MagIO2 Posts: 2,243
    edited 2014-06-04 13:56
    For each object the code and dat sections are kept together. And the objects line up in HUB RAM in the order of the first occurrance. So, if you have your boot-loader in the top file and the rest in a separate object (file), I don't see a reason for the compiler to produce the boot-loader differently because of changes in other files.
    The only thing which changes is where variables end up in the assembled binary. But as you don't need the object feature for the bootloader, you can simply replace var section variables by dat section variables in the bootloader code.

    The challenge might be to find out where the bootloader ends and how to call the real program.

    I think there are already concepts described in the forum of bootloaders which work a bit different. There the upper 32kB of the EEPROM contain the real code. The bootloader simply loads the full 32kB of upper EEPROM into HUB-RAM and starts that code in the SPIN interpreter. In case of an update it simply writes a 32kB image to upper EEPROM. In case of a broken EEPROM it is very likely that the lower part of EEPROM will still work and it is very unlikely that the EEPROM will repair itself ;o) So, in case of a failed write to upper EEPROM the bootloader might finally write thai image to lower EEPROM giving the customer some more time before the EEPROM has to be exchanged.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-06-04 14:31
    You need to describe your application a bit more for us to make useful suggestions. Are you trying to create a system that can be upgraded remotely? It sounds like you want a boot loader that takes up a small amount of space at the beginning of the EEPROM, which then loads your application that resides in the rest of the EEPROM. Your boot program should verify that the application program is valid by using a checksum or some other form of verification. However, you would probably also need a hardware watchdog timer to ensure that the system doesn't hang forever if the application does something bad.

    One nice feature of Spin binaries is that you can relocate them just by adding an offset to the 5 state variables in the header. The boot loader wouldn't even have to load the application from EEPROM since the Prop loader copies the entire 32K from the EEPROM to hub RAM prior to execution. Once you have verified the application program you can just do a COGINIT(0, $F004, app_ptr), where app_ptr contains the starting address of the application program. You would just need to reserve a small amount of space between the end of the boot program and the start of the application program to provide stack space for the boot loader.

    EDIT: Another possibility is to put your boot loader at the end of memory by specifying a very large DAT area. The application would just be written to the DAT area in EEPROM. This would allow the application to reuse the space that the boot code was in for stack space.
  • sccoupesccoupe Posts: 118
    edited 2014-06-04 14:44
    Dave Hein wrote: »
    You need to describe your application a bit more for us to make useful suggestions. Are you trying to create a system that can be upgraded remotely? It sounds like you want a boot loader that takes up a small amount of space at the beginning of the EEPROM, which then loads your application that resides in the rest of the EEPROM. Your boot program should verify that the application program is valid by using a checksum or some other form of verification. However, you would probably also need a hardware watchdog timer to ensure that the system doesn't hang forever if the application does something bad.

    One nice feature of Spin binaries is that you can relocate them just by adding an offset to the 5 state variables in the header. The boot loader wouldn't even have to load the application from EEPROM since the Prop loader copies the entire 32K from the EEPROM to hub RAM prior to execution. Once you have verified the application program you can just do a COGINIT(0, $F004, app_ptr), where app_ptr contains the starting address of the application program. You would just need to reserve a small amount of space between the end of the boot program and the start of the application program to provide stack space for the boot loader.

    EDIT: Another possibility is to put your boot loader at the end of memory by specifying a very large DAT area. The application would just be written to the DAT area in EEPROM. This would allow the application to reuse the space that the boot code was in for stack space.


    This sounds exactly like what I need. Any example of this around as least as far as the 5 state variables you speak of? This sounds as if I can build the boot loader and load it in the EEPROM as one would a usual program. Then create the real program code and just send in the hex file to load the rest of the EEPROM via the boot loader. Once verified, reboot and call up the program with COGINIT(offset). Time to do some playing.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-06-04 15:38
    Here's a boot program that runs the hello program that's stored in it's DAT area. It adds the address offset to the Spin header, clears the VAR section and initializes the stack prior to calling coginit. The coginit PAR address is app_addr + 4 instead of just app_addr. I had forgotten about the +4 offset that is needed.

    Compile hello.spin to hello.binary using the F8 key prior to compiling boot.spin.
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-06-04 21:59
    I have only skimmed this thread.
    There is a checksum (simple xor IIRC) at hub (=eeprom) $0005 IIRC.

    You could either use the upper 32KB ofa 64KB eeprom, or the end section of the lower 32KB and then recalculate the checksum and rewrite it.
    There a couple of threads that may have some info for you...
    I posted a thread about using an 8KB 24C64 eeprom. It recalculates the checksum.
    I posted a PropOS and it has a programming eeprom module, either lower or upper 32KB.
  • ksltdksltd Posts: 163
    edited 2014-06-11 07:00
    There is a checksum in the header, but its not used by the loader. These things are always misguided because there's nothing to do with a checksum failure except sit there. The checksum is too weak to catch many problems. I use that byte for other things.

    I use 1mb eeproms for the boot eeprom - they're electrically and programmatically compatible with the 256kb flavor when only reading or writing the first 25% so the device boots perfectly well. I use the other 756kb for persistent storage.

    Depending on your application, I'd think carefully about writing directly over the program image in real-time as power failures may cause the entire EEPROM "page" to become corrupt if you get unlucky with timing.

    I do firmware updates over the wire by writing the "new" firmware into the upper half of the EEPROM until it's all arrived and checksummed. Then I copy it from the upper half to the lower half in one thoughtfully coded loop. I do this for two reasons - first, there's no place to store the new firmware in memory because the memory is full of the current version of firmware; second, it completely solves problems with dropped communication half-way through the update; finally - this approach drastically minimizes the window during which I'm vulnerable to power failures that would cause my product to become a brick, although the process still requires around 1.5 seconds just for the writes, which happen at 3ms per 128 bytes.

    I don't understand why you believe you need a separate boot loader at all?
Sign In or Register to comment.