I wasn't going to write code, I was going to write data in the upper areas of flash, away from where the code is.
There is no reason that this cannot be done. Your program simply needs a small "stub" of code located in the boot section. Your update routine would work something like this:
- User sends a certain serial command to initiate an update.
- Your code replies with an acknowledge code.
- User sends data that you store in a ram buffer (i.e. an array).
- Your code sends the address of the array to the small stub program located in the boot area and calls the stub.
- The stub writes the data to the designated flash in the application area (which works because this code is in the boot section).
- The stub finishes and returns to your main program.
- You send an "update complete" response to the user.
- If there is more to write you repeat this whole sequence.
Of course you will need to send and receive some sort of checksums or CRCs to insure data integrity, but the above is the basic idea how to make it work.
Hope this helps
Edit to add: You know that writing to flash requires that an entire page be written, right?
To modify bytes within a page, you need to program the flash this way:
- Read a complete flash page to a buffer.
- Modify the appropriate byte(s) in the buffer.
- Erase the flash page.
- Write the buffer back to the flash page.
- (optional) Compare the flash page with the buffer to be sure it wrote OK.
Some thing I do in my bootladers is to set OSCCAL to 0x00 before writing EEPROM or flash.
Since the programming time is controlled by the internal R/C oscillator, I like to set it to the slowest speed in order to "cook" the write a bit more.
Then, OSCCAL can be set back to the proper value (not needed if you reset since OSCCAL is set back to normal with each reset).