Search This Blog

Sunday, January 24, 2010

Baby Steps To a Bootloader

Linux.... the final frontier... these are my voyages as I try yet another thing that takes more manual effort in Linux.  I am playing with a Microchip mid-range 16F88 MCU.  The current goal is to create a bootloader and program that will load new code onto the chip in circuit from a Linux PC.  There are probably some great tools for this.  I decided to get the information I could and just write my own.  I've started with the tinyBootloader's source code as a template.  To keep the size of the bootloader down, it looks like I'll want to use the built-in USART circuits and pins.  That means building an inverter circuit for the serial cable with a Maxim 3232.
    So far, I'm working on an LCD parallel to serial circuit based on Myke Predko's.  On the PC end, I've grabbed the uspp code as a helper package for serial communications in Python ( authors: Isaac Barona Martínez, Damien Géranton, Douglas Jones, J.Grauheding ).  I've brushed up on my rusty Python to parse an Intel hex file:
def readHex():
    file = open( 'blink.hex', 'r' )
    lines = file.readlines()
    file.close()
    for line in lines:
        ni = line[1:3]
        numInstr = int( ni, 16 ) / 2
        addrH = hex( int( line[3:5], 16 ) / 2 )
        addrL = hex( int( line[5:7], 16 ) / 2 )
        recordType = int(line[7:9],16)
        start = 9
        # Record Type 0: data
        # Record Type 1: end of file
        # Record Type 2 & 3: Extended segment addressing.  throw error for us...
        # Record Type 4: signals true 32 bit addressing.  ignore for us
        # Record Type 5: anther extend address thingy.  throw error
        if recordType == 0: # This is a data line
            print 'numInstr: ' + str(numInstr),
            print 'address: ' + addrH + ' ' + addrL + ' ',
            dataList = []
            for i in range( start, len(line) - 4, 4 ):
                dataLH = line[i:i+2], line[i+2:i+4]
                dataList.append( dataLH )
            checksum = line[len(line)-3:]
            print 'data: ',
            for data in dataList:
                print data[0] + data[1],
            print ' checksum: ' + checksum
        elif recordType == 1:  # end of file
            print '\n Complete.'
        elif recordType == 4:   # print inhx32 warning
            print  'Found an indicator line to use 32 bit addressing.  Compile with inhx8s or inhx8m. Ignoring this line.'
        else:
            raise Exception( 'AAAAAAGGGGHHHH!  Found lines with extended segment addressing.  Why are you putting this on a pic??' )     
       
readHex()

Note that this is just a read and spew.  I found a couple of interesting things.  The first is with my compiler.  I use the gputils package. It defaults to 32 bit style ( inhx32 ).  This puts a record type of 4 on the first line.  I plan to ignore any lines that are not record type 0 ( data ) or 1( end of file ) for the first draft. 
    Baby steps.  First I need to get the LCD interface to work with the 16F88.  Then comes the Python program to send the hex code.  Then I'll work on sending it code to load into data eeprom.  The bootloader code will follow.  In the final game, I'd like to replace the DB9 serial with USB.  Then I'd be able to update my chip's code from my laptop instead of my desktop.  I'm also looking forward to the day when I can't find a computer with a serial port :)

No comments:

Post a Comment