Search This Blog

Sunday, November 21, 2010

Working Bootloader

Finally! I got my bootloader code working.  It's pretty quick, too.  The basic outline ended up looking like this:
The Pic code is written in Asm.  The PC code is written in Python, making use of USPP as ascribed earlier.  The tinyBld code I looked at was an ok starting point.  I ended up rewriting a lot of it.  It ended up using 224 bytes of space for a 198 word program.

The startup sequence goes like this: On power up or reset, the first four words pageselect and go to the bootloader at the bottom of the program space.  This space initializes the USART and immediately sends a start signal ( 0xC1 ) at 9600 baud.  It waits for a little over a one second.  If it does not receive the start signal back, it drops to one byte before the user's first four space.  This is in the last 32 bytes of program space and holds the first four words of the last loaded program.  The byte before the user's space does a pageselect back to page zero.  The loaded program then executes.

Assuming you want to load code, you wire up TX, RX, VCC, and GND from an RS232 shifter hooked to the PC.  I use a USB cable hooked to a serial to USB converter to the shifter.  Fire up the board.  Wait 2 seconds. Launch the PC program, called icsp.py.  I found I had to set the userid bit on python for this to work.  ( Yes, I know the risk and unset it when done ).  The icsp program takes a few arguments.  The first is the path to the serial port.  For my linux machines with the serial to USB, this is /dev/ttyUSB0 ( or one, or two, etc ).  The second argument is the location of the hex file you wish to load.  The last argument is the debug.  This prints out verbose logging as to what is occurring.

The program will load the file and create packets for transmission.  This involves "undoubling" a lot of the values the hex file creates.  It computes a new checksum value for each line/packet.  It keeps the user's program from overwriting the bootloader.  It intercepts the first four instructions if they are in 0x00-0x04.  It rewrites them in the user's first four area.  If there are additional instructions on this line, it creates a new line with address 0x0004 and a new checksum.  When this load is complete, the command line lets you know it is listening for the start signal from the Pic.

Hit the reset button ( or power off and on ).  The Pic will jump to the bootloader code and send the start signal.  The icsp receives this, echoes it back, and goes into and endless wait for the 'Ok' signal ( 'k' ).  The Pic, meanwhile, prepares for a new program.  It copies the first four instructions from its program space to a buffer.  This is the code that jumps to the bootloader.  It then erases the program space up to the bootloader. It also rewrites the 32 bytes from the user's first four space.  The 16f88 I'm working with has to erase blocks of 32 and wastes 28 bytes of space because of it.  Once the erase is done, it rewrites the bootload first four to 0x00-0x04.  It then sends the 'k' to the PC and goes into a one second receive delay, waiting for the first line.

The PC loops through the list of packets and sends each to the Pic.  The Pic receives each byte, storing the address in the EEADR and EEADRH registers.  It stores the data in a buffer.  It knows how many data packets are coming because the number of instructions is sent as part of the packet.  When the read is complete, it writes the packet to the program space at the address indicated.  Wash, rinse, repeat.  The pic calculates the checksum.  If it doesn't match the sent checksum, it sends a 'n' to the PC for another attempt.  The PC will retry three times per line.  When the last line has been sent, the Pic will time out waiting for the next line and go to the pageselect and user's first four.

Now I can reprogram my robot in circuit without a lot of rewiring!!! Huzzah!

I'll post code after I convert it.

No comments:

Post a Comment