Searching \ for '[PIC]Alternative to bootloader concept for smaller' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'Alternative to bootloader concept for smaller'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]Alternative to bootloader concept for smaller'
2005\08\17@204408 by Mike Harrison

flavicon
face
Now that self-programming is available on some smaller PICs (e.g. 16F818), I was thinking about ways
of providing in-system firmware updates with the absolute minimum of code overhead - a typical
'traditional' bootloder takes of the order of 128-256 words, depending on the communications
requirements, which is a significant chunk on a 1K part.

I was thinking particularly about a current design, but it would be applicable to any system where
the main application already has :
a) An external eprom or serial flash etc. memory big enough to hold a code image
b) Some communications link capable of reading/writing to the eeprom.

Instead of the traditional bootloader approach (where the loader handles the comms and the
programming, and has to be able to recover if the comms fail), you copy the code into eeprom using
the existing application code, verify it back, then call a small routine at the top of memory to
copy the eeprom image to the flash.

This has the advantage that because you already have the comms code in your main application, the
only code overhead is the actual eeprom-to-flash copying code - off the top of my head I'd guess
this could easily be less than 64 words, and may be a lot less  if your eeprom is on a hardware SPI
or I2C interface.

It  eliminates the need to be able to recover from comms failure, as you can write and verify the
data before committing to the flash programming operation. The only hazard would be a power failure
during the copying process, a much less likely occurrance.
Depending on how much of a risk you consider this is for your product (and how difficult it would be
to recover from a failure), you could trade off a bit of code space by having the copy routine
rewrite the reset vector to restart the process if interrupted, copying the 'normal' vector back as
the last operation, narrowing the  window time in which a power failure would be fatal to an
insignificantly small few tens of milliseconds.
Alternatively (at the expense of a little more code) it could be set up to always boot into the copy
code, which would check the eeprom to look for a flag to signal a new image to be loaded.

For devices like serial flash on hardware SPI, where one command can read a large number of data
bytes, the main application code could even initiate the eeprom read command, eeprom address etc.,
so the copy code would just have to read the stream of bytes from the SPI port, giving an extremely
low code overhead - maybe 32 words ? (will let you know when I get round to writing it..!)








2005\08\17@232455 by Kenneth Lumia

picon face
Mike,

> I was thinking particularly about a current design, but it would be
> applicable to any system where
> the main application already has :
> a) An external eprom or serial flash etc. memory big enough to hold a code
> image
> b) Some communications link capable of reading/writing to the eeprom.
>
> Instead of the traditional bootloader approach (where the loader handles
> the comms and the
> programming, and has to be able to recover if the comms fail), you copy
> the code into eeprom using
> the existing application code, verify it back, then call a small routine
> at the top of memory to
> copy the eeprom image to the flash.

This basic idea has been used in commercial grade modem designs
for over 20 years.  Of course the processors were different and
they used eeprom since flash wasn't around yet.  What you are
describing is actually more of a downloader than a bootloader.
As far as the comms goes, you can even add a node address
into the protocol so that devices that are connected together
(such as a RS485 network) can be downloaded on an individual basis.

{Quote hidden}

Your last statement is the way to go as it makes the process
completely safe.  All it requires is a very small routine that never
gets overwritten put at the startup location.  Its job is to determine
if the installed code is good, or if it needs to copy code from
the external flash.

The process is usually something to the effect:

1. Download new code to external flash and verify it is ok (CRC).

2. Set an insanity bit in the PICs eeprom.  The idea here is if a
reset occurs, the startup code will know whether the unit is insane or ok.

3. Start copying code to the PICs Flash.  If all goes well, clear
the insanity bit and restart the processor.  The short startup
code checks the insanity bit, all is well and it proceeds to
normal startup.  If a power hit occured, the insanity bit will
still be set from the previous step, telling the startup code
to try and reload from external flash.

For extra credit, if the external flash is large enough, you
could put in several several images and command the unit
to load a specific one.  Think product code, production test
code, special debug code, using one hardware platform for
different products (software defined product), etc.

Ken
spam_OUTklumiaTakeThisOuTspamadelphia.net


2005\08\17@235614 by Denny Esterline

picon face
> 1. Download new code to external flash and verify it is ok (CRC).
>
> 2. Set an insanity bit in the PICs eeprom.  The idea here is if a
> reset occurs, the startup code will know whether the unit is insane or ok.
>
> 3. Start copying code to the PICs Flash.  If all goes well, clear
> the insanity bit and restart the processor.  The short startup
> code checks the insanity bit, all is well and it proceeds to
> normal startup.  If a power hit occured, the insanity bit will
> still be set from the previous step, telling the startup code
> to try and reload from external flash.

I like this idea, but here's a thought - if the image in the external EEPROM
is hosed, you could end up with a system that continuously reloads until you
hit flash write endurance, then you have a bad day. :-)

Here's another option: have the startup code compare the internal program to
the external, if they don't match - then copy. Instead of your 'insanity
bit', keep a running count of how many times they don't match (reset the
count when they do). If the count is more than a couple, switch to some
failsafe mode.

But from a practical view point, I can't imagine when I could justify the
external memory approach. Isn't the main idea of a bootloader to simplify
field upgrades? Seems to me that the system should have some extra space for
those unspecified future changes. I'd think the money and resources would be
better spent putting in a larger PIC instead of the external memory. But
that's just my opinion.

-Denny

2005\08\18@011546 by Kenneth Lumia

picon face
>> 1. Download new code to external flash and verify it is ok (CRC).
>>
>> 2. Set an insanity bit in the PICs eeprom.  The idea here is if a
>> reset occurs, the startup code will know whether the unit is insane or
>> ok.
>>
>> 3. Start copying code to the PICs Flash.  If all goes well, clear
>> the insanity bit and restart the processor.  The short startup
>> code checks the insanity bit, all is well and it proceeds to
>> normal startup.  If a power hit occured, the insanity bit will
>> still be set from the previous step, telling the startup code
>> to try and reload from external flash.
>
> I like this idea, but here's a thought - if the image in the external
> EEPROM
> is hosed, you could end up with a system that continuously reloads until
> you
> hit flash write endurance, then you have a bad day. :-)

I didn't really intend for people to implement the above in
a thoughtless manner.  The steps were shown just to give
people a starting point.  Of course error checking is
important, keeping track of the number of reloads is just
one of the issues.

> But from a practical view point, I can't imagine when I could justify the
> external memory approach. Isn't the main idea of a bootloader to simplify
> field upgrades? Seems to me that the system should have some extra space
> for
> those unspecified future changes. I'd think the money and resources would
> be
> better spent putting in a larger PIC instead of the external memory. But
> that's just my opinion

Welcome to engineering!  Tradeoffs are dependant on the
situation being addressed.  If it is simple to email a file to an end
user that just runs an app on a local PC to flash the device so be
it.  What happens when the device is far away and not
easily accessible (except remotely through a communications link)?
Failure is not an option.  A larger PIC
is possible, but may not be able to contain both sets of
code.  Of course, if you really wanted to get tricky, you
could break the code into small modules and just
download corrections for the faulty parts.  Then patch
the pointers to the replaced functions in the rest of the
code.  I've seen that done on Z80 systems circa 1984.
There can be many solutions for a given set of product
requirements.  It is your job to figure out the "best" solution.

Ken
.....klumiaKILLspamspam@spam@adelphia.net




2005\08\18@020954 by Wouter van Ooijen

face picon face
> Instead of the traditional bootloader approach (where the
> loader handles the comms and the
> programming, and has to be able to recover if the comms
> fail), you copy the code into eeprom using
> the existing application code, verify it back, then call a
> small routine at the top of memory to
> copy the eeprom image to the flash.

I would consider it a big disadvantage that an cooperation of the
application is required. One erroneous (ill-behaved) application and the
party is over!

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\08\18@034645 by Alan B. Pearce

face picon face
>Of course, if you really wanted to get tricky, you
>could break the code into small modules and just
>download corrections for the faulty parts.  Then patch
>the pointers to the replaced functions in the rest of the
>code.  I've seen that done on Z80 systems circa 1984.

Ahh, memories of BIOS jump tables in CP/M ...

Raises images of jump tables at page boundaries in a PIC, and having the
modules as page sized chunks ...

As to the earlier suggestion of multiple images in the external eeprom, I
have seen this done on spacecraft instruments, with a flag to identify which
one to load on instrument power up. However if the image is corrupted then
there is a facility to tell the ROM code to select a different boot image.
You cannot exactly go a service call to re-flash the image prom ...

2005\08\18@040735 by Mike Harrison

flavicon
face
On Thu, 18 Aug 2005 08:07:51 +0200, you wrote:

>> Instead of the traditional bootloader approach (where the
>> loader handles the comms and the
>> programming, and has to be able to recover if the comms
>> fail), you copy the code into eeprom using
>> the existing application code, verify it back, then call a
>> small routine at the top of memory to
>> copy the eeprom image to the flash.
>
>I would consider it a big disadvantage that an cooperation of the
>application is required. One erroneous (ill-behaved) application and the
>party is over!

As I said, it's a compromise. You have to decide the risks of failure and costs of recovery versus
code usage.
If it's a choice between not having field upgradability (due to lack of code space) or having a
small risk of failure, then in many cases the benefit would outweight the risk.

True, loading bad app code could render the system un-reprogrammable, but this can be controlled by
careful testing and administration.  
The big difference is that the risk of a partially-programmed image is vastly reduced as there are
no comms to go wrong part-way through.

What got me thinking about this was my earlier thread about not being able to bulk-erase chips below
4.5v, and the problem this causes for 3v-only systems. In this situation an ultra-small, but not
necessarily bullet-proof loader, for use only at the factory, would provide a good solution, as any
misprogramming could be recovered relatively easily..

2005\08\18@045125 by Wouter van Ooijen

face picon face
> As I said, it's a compromise. You have to decide the risks of
> failure and costs of recovery versus code usage.

I seriously think in most cases a switch to a larger PIC would be a
better choice than risking a field problem.

> but this can be controlled by
> careful testing and administration.  

Hmmmm. Murphy will be smiling.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\08\18@054136 by Mike Harrison

flavicon
face
On Thu, 18 Aug 2005 10:49:22 +0200, you wrote:

>> As I said, it's a compromise. You have to decide the risks of
>> failure and costs of recovery versus code usage.
>
>I seriously think in most cases a switch to a larger PIC would be a
>better choice than risking a field problem.

In cases where you are using it for field upgrades, and where field upgradability is a significant
design goal, I'd entirely agree.

However I'm  thinking more along the lines of situations where in-system upgradability is a 'useful
addition' but only if it can be done for little code cost, and in that context there are many
situations where it could be very appropriate.
e.g. in the factory - if it means you can upgrade without taking the product apart for the price of
a small amount of code, and if it occasionally fails the consequence is that you have to unscrew a
cover, then it is a definite benefit.
Similarly in the 3v-supply situation - it allows in-circuit reprogramming of code-protected parts,
but if it fails, you fall back to cutting a link or whatever to apply 5V to reprogram.

However it should be remembered that if properly implemented, the risks of failure can be reduced to
pretty minimal levels.

You have to balance the extra cost you add to every unit by including a more robust upgrade method
against the cost of dealing with the probability  that (a) an upgrade is needed, and (b) that
upgrade failing and (c) the cost of dealing with a failed upgrade. In many cases (a)*(b)*(c)  will
be small that any extra initial cost is not justified. In others it won't, so you do it the more
traditional way.



2005\08\18@075031 by olin piclist

face picon face
Mike Harrison wrote:
> Instead of the traditional bootloader approach (where the loader
> handles the comms and the programming, and has to be able to recover if
> the comms fail), you copy the code into eeprom using the existing
> application code,

Yup, I'm working on a 30F6012 design that will use exactly this method.  The
reason in my case is that field upgrades will come over TCP, so a bootloader
would take up much too large a fraction of the code space.  I haven't
actually written the code for any of this yet, but the hardware has a
64Kbyte serial EEPROM there mostly for that purpose.  This will probably be
one of the last features I'll add, and it may be a month or two before I get
to it.

> verify it back, then call a small routine at the top
> of memory to copy the eeprom image to the flash.

I plan to just restart the system after a new image is loaded in EEPROM.  On
startup a small piece of code at the end of program memory will checksum the
EEPROM and the app part of program memory and check their version numbers.
If the EEPROM checksum is correct and the current app is either corrupt or
is a different version, then the new app is copied from EEPROM to program
memory.  The code then does another restart.  At this point both should be
the same version, but if something went wrong with the copy then the app
checksum will be wrong and another copy attempted.

This process should tolerate a power failure at any point.  The worst result
is that the app is not updated to the desired new version.  This can be
determined by the host and another upload attempted.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\08\18@101312 by sergio masci

flavicon
face


On Thu, 18 Aug 2005, Mike Harrison wrote:

{Quote hidden}

If you're going to add an extra chip why not simply add a second PIC and
use that to program the first in LVP mode? There would be lots of benefits
in this including the ability to program the config words.

Regards
Sergio Masci

http://www.xcprod.com/titan/XCSB - optimising PIC compiler
FREE for personal non-commercial use




2005\08\18@111916 by Mike Harrison

flavicon
face

>>
>> I was thinking particularly about a current design, but it would be applicable to any system where
>> the main application already has :
>> a) An external eprom or serial flash etc. memory big enough to hold a code image
>> b) Some communications link capable of reading/writing to the eeprom.

>If you're going to add an extra chip why not simply add a second PIC and
>use that to program the first in LVP mode? There would be lots of benefits
>in this including the ability to program the config words.

If you read my original post, I said it was applicable to systems where the external EEPROM was
ALREADY present in the product. it would not make sense otherwise.


2005\08\18@143712 by Mike Harrison

flavicon
face

I've now implemented this scheme on the current project.
A limit on the sizing of the 'resident' eeprom copying routine is the 32 word row erasability
boundaries, so if the code can't be squeezed below 32 words, there is no benefit in using any less
than 64, so this could be used to add some of the various 'protection' options I outlined in my
original post, or to move the setup code into the resident area to free space in the application
area.

My first attempt put the resident part at 37 words, so i just HAD to do some squeezing to get it
down to one row, just to prove it could be done...!

The total code overhead for enabling the in-system reprogrammability came to  50 (decimal!) words,
18 words setup within the application code and 32 for the copy code which lives in the top row of
program space.

Having all the setup within the application code area instead of the fixed 'resident' section
maximises the possibility for future code squeezing/sharing if things start to get really tight, but
care must be taken to ensure that it will work correctly in all circumstances.

Flash-program time for the 16F818 is about 0.7 seconds, so even without  any additional protection
mechanisms, the 'potential disaster' window is pretty short.

..and for those of you that didn't read/understand the original post, this technique is only
seriously advantageous for systems that ALREADY HAVE a suitable external eeprom/serial flash, and
communications system as part of the main application, and where in-system reprogrammability can be
regarded as a useful addition rather than a mission-critical necessity!!!

-----------------------------------------------------------------------------------------------------------------
here's the code - obviously will need tweaking to suit other apps, but the 'get byte' is a seperate
routine and should be fairly easy to modify (once you understand the strange bits done to save
space..!)

; 16F818 eeprom-copy flash loader
; (C) Mike Harrison 2005
; copies from external ST M25Pxx serial flash, address 000000, LSB first

wordcount equ 070 ; variables in shared bank to allow access regardless of page bit settings
rowcount equ 071

; setup code - resides in application area

copyflash ; copy ext serial flash to program memory. SPI already set up, ints disabled
; setup for SPI eeprom read
 clrf intcon ; ensure ints off

movlw 3 ; serial flash read command
call sendspi  ; uses spi routine which is already parts of main app code (asserts /CS)
call sendspi_0 ; address bytes 2..0, sends 0
call sendspi_0
call sendspi_0

movlw 1<<rp1
movwf status ; ensure rp0 and irp clear
movlw sspbuf
movwf fsr ; use indf/fsr to allow access to sspbuf without page switching.

clrf eeadr-100   ; zero PIC flash address
clrf eeadrh-100
movlw loaderstart/d'32' ; number of rows to program
movwf rowcount

goto loaderstart

end of application code
;------------------------------------------------------------------------------------------------


org 3e0

; start of resident loader section.

loaderstart
eraseloop ; erase and program one row of 32 bytes
 movlw (1<<EEPGD)+(1<<FREE)+(1<<WREN) ; select program memory, row erase, write enable
 call flash_write  ; erase row
 movwf wordcount ; 32 words to program ( value 32 returned by flash_write retlw)
wordloop
   call get_ssp                ; get LSbyte from eeprom
   movwf eedata-100
   call get_ssp                ; get MSbyte from eeprom
   movwf eedath-100
   movlw (1<<EEPGD)+ (1<<WREN) ; program memory write
   call flash_write
   incf eeadr-100 ; increment flash address
   skpnz
   incf eeadrh-100 ; address msb
   decfsz wordcount
   goto wordloop
   decfsz rowcount
   goto eraseloop

  goto force_pc ; exit address to force re-entry to PC mode

; the exit address would typically be a well-defined, non-movable address in the app.code, e.g.0002
; an alternative would be to use "goto $" to loop infinitely and  force a reset when the watchdog
; times out.

get_ssp ; get byte from spi

movwf indf ; (fsr-> sspbuf), initiate SSP read
call sspdelay ; delay to allow spi to happen ( SPI clock is osc/4, so takes about 8 instruction
times)
movf indf,w
return

flash_write ; do flash erase or write sequence, w = eecon1 value, assumes rp1 set
 
bsf status,rp0 ; page 3
movwf eecon1-180 ; select program memory, row erase, write enable
movlw 055 ; write sequence
movwf eecon2-180
movlw 0aa
movwf eecon2-180
bsf eecon1-180,wr  ; start write/erase

sspdelay        ; entry point used for SPI wait delay
goto $+1        ; long NOP, used to extend ssp wait delay.
clrwdt                ; avoid watchdog spoiling your day. placed here to maximise ssp delay time
                       ; wont be executed after flash write but will be when ssp is read
bcf status,rp0
retlw 020        ; number of words per row, used after erase



2005\08\18@163443 by Bob Axtell

face picon face
Mike Harrison wrote:

>I've now implemented this scheme on the current project.
>A limit on the sizing of the 'resident' eeprom copying routine is the 32 word row erasability
>boundaries, so if the code can't be squeezed below 32 words, there is no benefit in using any less
>than 64, so this could be used to add some of the various 'protection' options I outlined in my
>original post, or to move the setup code into the resident area to free space in the application
>area.
>  
>
Actually, I squeeze the 32 14-bit words into 32 pairs of 7-bit
characters, a MS and an LS 7-bit character. I then add d'14'
to each one to ensure that those characters are not confused with <CR>
(or whatever terminator is used). This makes
serial transmission of the downloader easier.

One can also squeeze 64 7-bit characters (448 bits) can be reduced to 56
8-bit bytes, for the purpose of squeezing
4096 14-bit words into  3584  16-bit words.

{Quote hidden}

--
Note: To protect our network,
attachments must be sent to
attachspamKILLspamengineer.cotse.net .
1-866-263-5745 USA/Canada
http://beam.to/azengineer

More... (looser matching)
- Last day of these posts
- In 2005 , 2006 only
- Today
- New search...