GCBOOT - a bootloader for the PIC18F2525 chip - v8 11/13/10 =========================================================== This is a bootloader I made for loading code into my HP21xx USB Disk Adapter. I looked at several existing bootloaders, including AN851 and AN1310 from Microchip, DS30, and "TinyBLD" and found they were unsuitable for what I wanted to do. Specifically they all require a PC app to load the code, and some also require changes to the PIC app being loaded. My primary needs were for the bootloader to accept plain hex code sent over a simple serial port by whatever means with minimal requirements, with little or no change to the PIC program. A secondary need was to be able to load code into the PIC without erasing existing code to permit overlays and multiple apps. Software Stuff -------------- GCBOOT is written using the Great Cow Basic compiler, available from: http://gcbasic.sourceforge.net/ (I used version 0.9 10/9/2010) A Windows exe is provided, for Linux recompile gcbasic.bas using the Free Basic compiler, available from: http://www.freebasic.net/ GPUTILS or MPASM/MPLAB is required to assemble the resulting code: http://gputils.sourceforge.net/ (Windows or Linux) http://www.microchip.com/ (search for MPLAB) GC Basic's internal assembler can be used if assembly.bi is patched to permit assembly past address 0x8000 - for the 0.9 version my fix was to find the comments 'Add high address? (occurs twice) and in the next two lines after each comment change FRA to (FRA - 32767). GC Basic and a compatible assembler is not required if using the gcboot.hex file as-is on a PIC18F2525 chip, it is only needed to modify the bootloader source code to configure for a different PIC18F chip or compile with different options. Although for PIC programming you'll probably want these tools anyway. A programmer is required to initially load the bootloader into the PIC, I used the Microchip Pickit 2 starter package (DV164120, includes MPLAB) with the 28-pin demo board (DM164120-3). Alternatively to save bucks just the programmer (PG164120) can be used with a homemade 28-pin adapter, download the software (Windows or Linux) from the Microchip site (punch in "pickit 2" in the search box for download options). A GUI app is provided for Windows systems. For Linux use PK2CMD from a command line, such as: pk2cmd -P -F gcboot.hex -T -R -M (this leaves the PIC powered for testing). GCBOOT Features --------------- GCBOOT has the following characteristics... Configured for a 28-pin PIC18F2525 with MCLR reset, internal 32mhz clock. 9600 baud serial port connected to the HW serial port using 3 resistors. If no serial port is connected then immediately runs the loaded app. Accepts standard Microchip-format hex files, record len 0 = end of file. Does not support loading the eeprom, configuration and eeprom data is ignored. Menu options to program, examine code/ram, wipe code/ram and execute app. No menu selection needed to load code, just send the hex file (triggers on :) Terminal emulator or sending app must add a short delay after each line. Port B bit 0 configured as an output to flash an LED for status. Bootloader starts at address 0xB000, all app code must be below this. Existing PIC code is not erased when loading new code unless the same address. First two words of the application should not be a relative branch or call. Replaces the first two words with GOTO 0xB000, stores the original at 0xBFF0. Stores a GOTO 2 at 0xBFF4 in the event the first instruction isn't a GOTO. PIC app must not assume particular memory/register contents on startup. Bootloader uses/changes ram from 0x000 to 0x140 and from 0xF00 to 0xFFF. Source-configurable options... PIC chip and MCLR config (must be a PIC18F, only tested with PIC18F2525). Oscillator type and PLL usage (only tested with internal oscillator). Starting location of the bootloader code and where it stores the app GOTO. Pin and polarity used to enable the bootloader or run the app. Serial port baud rate and polarity. Status LED usage and pin. Usage ----- The bootloader is configured to be used with a circuit similar to this... O serial .----------------. O port | MCLR|--1K---*---10K--< +5V RX O--------1K-----------------|TX (C6) | | O | | `------*--100--. TX O----*---18K----------------|RX (C7) Vcc|---*--< +5V | | O | | | | 2.2u O | O `---100K---< +5V | PIC18F2525 | 0.1u _|_ |-- O | | | O | O----. .--|<|---2.2K----|B0 Vss|---* |reset _|_ _|_ LED `----------------' _|_ _|_ The serial port sends 5V signals, this is compatible with the serial port hardware in most PC's. The 18K resistor in series with the RX pin limits current flow from 12V serial outputs, the 100K resistor pulls C7 high when the serial port is not connected to tell the bootloader to run the app. If not using a reset switch, MCLR can be connected to Vcc with a 1K resistor (the resistor is to protect the PIC in the event of misprogramming). Note that if using the gcboot.hex file as-is, the B0 pin must not be directly connected to ground or +5V, or to the output of another chip. The source can be configured to disable the LED output or use another pin. The software used to access the bootloader must be configured to add a small amount of delay after each line end (10mS should be sufficient). There is no hardware handshaking and no byte-by-byte software control, so time must be given to process each line of hex code. The Windows Hyperterminal program has an option for line delay, as does most other terminal emulators. Linux systems can use a simple script to send the hex file even if a terminal emulator is running, and if desired automatically execute the app after loading. Windows does not permit such simple user access to the serial port so generally code needs to be uploaded using a terminal emulator or a custom-written app that sends the hex file lines with an appropriate line delay. When the bootloader runs it flashes the status LED on off on with a 1 second interval to verify timing, then sends the following to the serial terminal... === Terry's Bootloader === v8 11/13/10 Configuration = 32mhz MCLR LED=portb.0 Select... P: Program (or just send) M: Examine ram V: Examine code W: Wipe chip X: Execute app > Enter is not needed when selecting options, just send the key. All options except for X can be cancelled by sending Esc. Entries except for confirms but including hex can be sent as uppercase or lowercase. Option P is mostly redundant, only needed if a hex file has extra comments at the beginning of the file. Otherwise just send the hex file using the terminal emulator's ascii upload function (or for HyperTerminal by copy/pasting the hex code, associate .hex files to Notepad for easy access). Upon reception of each ":" character of the hex file the status LED goes out, and is turned on after the checksum is received, so the LED will blink as the app is loaded. A "." is sent to the terminal for each new 32-word block being programmed. If an error occurs the LED remains off and an error message is sent to the terminal, Esc must be sent to clear the error condition. In the case of an address error the bootloader restarts, including the initial startup delay. Option M prompts for a ram page (0 to F) then lists 256 hex bytes, useful for examining array contents set by the PIC app to assist in debugging. Example... > m HEX digit of block to dump: 1 0100: 6D 29 20 00 FF FF FF FF FF FF FF FF FF FF FF FF 0110: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 0120: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 0130: FF FF FF FF 01 EF 00 F0 FF FF FF FF FF FF FF FF 0140: C1 88 21 88 A0 40 38 05 08 07 C0 06 62 6B 25 9E 0150: C1 10 03 58 02 69 38 8A AE 60 C2 91 B4 20 F8 01 0160: CD 00 51 82 A0 54 02 5E 98 A8 00 40 60 B0 08 EE 0170: 82 58 E4 90 09 1C 00 80 E9 20 20 6E 9C C4 30 83 0180: 32 0C 74 82 21 C0 A2 08 C9 88 78 2F 81 00 0B 9D 0190: 43 D0 0B 11 38 01 04 00 3A 48 53 88 88 D0 41 00 01A0: 4C 65 40 AC 80 46 96 00 05 68 0C 4E A7 E0 39 01 01B0: 86 68 03 02 B2 D4 2C 34 56 8A B6 84 0E 84 04 08 01C0: DC 02 12 22 96 E1 4C 65 2A 42 EC 00 A2 57 00 E1 01D0: 74 81 40 A1 0D A0 48 75 4C A5 4A C6 C8 11 00 A7 01E0: 28 52 A6 61 FA 05 5A 28 E4 51 30 62 4A E0 04 82 01F0: 75 A2 08 6C 84 90 20 08 62 08 46 20 4E F8 01 16 In this example 0x100-0x13F shows the flash buffer for the bottom locations of an uninitialized PIC, with the first 4 bytes set to jump to the bootloader. The remaining memory is random bytes after power-up. Option V prompts for an address (4 hex digits) then lists 128 hex words, useful for examining program space to see what is loaded where. Example... > v HEX Address: BF00 BF00: 1C1C 4548 2058 6964 6967 2074 666F 6220 BF10: 6F6C 6B63 7420 206F 7564 706D 203A 0202 BF20: 203A 0101 0020 0D0D 4548 2058 6441 7264 BF30: 7365 3A73 0020 1212 6553 646E 4520 4353 BF40: 6620 726F 6D20 6E65 2075 0101 002E 1010 BF50: 6E49 6176 696C 2064 6461 7264 7365 2073 BF60: 0D0D 4520 4353 7420 206F 6572 6573 0074 BF70: 0A0A 655A 6F72 7220 6D61 203F 1B1B 655A BF80: 6F72 6E69 2067 6172 206D 7266 6D6F 3120 BF90: 3034 7420 206F 4645 0046 0C0C 7245 7361 BFA0: 2065 6F63 6564 203F 1919 7528 7070 7265 BFB0: 6163 6573 5920 7420 206F 6F63 666E 7269 BFC0: 296D 0020 FFFF FFFF FFFF FFFF FFFF FFFF BFD0: FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF BFE0: FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF BFF0: FFFF FFFF EF01 F000 FFFF FFFF FFFF FFFF This shows the last block of memory, the bootloader just about fills it up so if recompiled with a different version of GCB ensure that the code does not extend past 0xBFEF, otherwise adjust the defines at the beginning of the source to relocate lower. The instruction(s) from locations 0x0000 and 0x0002 will be relocated to 0xBFF0 and 0xBFF2 after loading an application, locations 0xBFF4 and 0xBFF6 contain a JUMP 2 instruction. Note that PIC18F memory is addressed as bytes with the LSB first, each word starts on an even address. For convenience the bytes are swapped to list the hex words normally. With a bit of scripting or program code option V can be used to implement an extract function. Option W permits erasing ram and/or code memory. Normally this isn't needed but can be used when debugging to see what ram locations are changed or to remove previously loaded code so that newly-loaded code extents will stand out. The GOTO 0xB000 at location 0 remains after wiping code memory, but the stored instructions from location 0 are not erased. Option X runs the loaded application by executing a jump to BFF0, where the bootloader stores the application's initial GOTO. If no app has been loaded it executes FFFF's as nops and wraps around to hit the initial GOTO 0xB000, rerunning the bootloader. Whenever the bootloader runs, it checks locations 0-3 to make sure it contains a GOTO 0xB000, if not then it programs a GOTO 0xB000 at location 0 and a GOTO 2 at location 0xBFF4. This ensures that the bootloader will always run upon reset, the GOTO 2 is for compatibility with the Hi-Tech C compiler (use the --rom option to locate the code below the start of the bootloader). Using the bootloader under Linux -------------------------------- No specific Windows section is provided - instructions for using GC Basic under Windows is included with the program, HyperTerminal can be used to send hex code, and since a VXD driver is needed to access the serial port the scripting examples do not apply - writing a dedicated hex sender app for Windows is not trivial and beyond the scope of these docs. Linux makes it particularly easy to access the serial port using scripts or any other program, as it's simply a virtual file (usually /dev/ttyS0). Depending on the system it may be necessary to set up permissions, but I don't recall having to do anything, I can access /dev/ttyS0 as a normal user on my Ubuntu 8.04 system. Multiple programs can access the serial port so it is not necessary to exit the terminal emulator to send hex code with another application, which is handy since simple Linux terminal emulators (like dterm) often don't have a line delay function, thus requiring using a script to send the hex code. The terminal can remain open to monitor for errors, or just watch the LED. I use the following bash script to send hex files to the bootloader... #!/bin/bash serial=/dev/ttyS0 stty -F $serial 9600 if [ ! -e "$1" ]; then echo "Enter name of file to send..." read filename else filename="$1" fi while read line do echo $line > $serial sleep 0.05 done < "$filename" echo "" > $serial I named it "sendhex.sh", must be in "unix" line-end format with executable permissions. Set the serial= line to match the serial port device, the stty line sets the port to 9600 baud if a terminal emulator has not been run yet. If no parameter is given or the file doesn't exist it prompts for the file to send. After each line waits 50 milliseconds (approximately), and sends an empty line after sending the file because often unix/Linux text files don't have a line end after the last line. To automatically execute the loaded app, echo "x" > /dev/ttyS0 at the command line, or add echo "x" > $serial to the end of the script, if an error occurs during loading it will be ignored. From a command shell in the GC Basic directory, assuming myapp.gcb and sendhex.sh are in the same directory, the following commands can be used... ./gcbasic -a:gcasm myapp.gcb [compile my application] ./sendhex.sh myapp.hex [send the hex to the bootloader] echo "x" > /dev/ttyS0 [start the app] If the app doesn't work right then I press the reset switch and try again. To avoid the command line these steps can be put on GUI right-click actions for .gcb and .hex files, also avoids having to be in the compiler directory. To do this I created a directory named "picstuff" and copied into it the gcbasic binary, messages.dat and the include and chipdata directories, and created two scripts named gcb_compile and sendhex... ------- begin "gcb_compile" ------------------------ #!/bin/bash if [ -e "$1" ]; then xterm -e /media/hdb5/picstuff/gcbasic -a:gcasm "$1" fi ------- end "gcb_compile" -------------------------- ------- begin "sendhex" ---------------------------- #!/bin/bash if [ -e "$1" ]; then serial=/dev/ttyS0 stty -F $serial 9600 filename="$1" while read line do echo $line > $serial sleep 0.05 done < "$filename" sleep 0.1 echo "" > $serial sleep 1 echo "x" > $serial fi ------- end "sendhex" ------------------------------ Note that in the gcb_compile script the full path to the gcbasic binary must be specified, edit to specify exactly where it's located at. Also note that the gcbasic command specifies the internal assembler so it can't be used to assemble the bootloader itself unless assembly.bi has been fixed to permit assembling past address 0x8000 as instructed in the "Software Stuff" section above - since this is for Linux, it is assumed that since gcbasic has to be recompiled anyway that the patch has been made. The sendhex script is an adaptation of sendhex.sh that requires a filename parameter and sends the execute command after loading the hex file. Try as I might I was unable to get pk2cmd to work from a GUI right-click, the initial bootloader programming must be done from a command line. In the GUI, associate .gcb (or text) files to the gcb_compile script, and associate .hex (or text) files to the sendhex script. How this is done varies from one GUI and another, for Gnome it's done by right-clicking the file, selecting properties, then using the Open With tab. On my Ubuntu system I used a mime editor to create a separate file type for hex files, but I don't have a separate type for gcb files so the association appears for all text files. With the scripts in place I can simply right-click my gcbasic source and compile, then right-click the resulting hex file to send it to the bootloader to load and run the app. License ------- ' The source code for the program is written by Terry Newton, it is provided ' as-is and without warranty of any kind. Under no circumstances shall the ' author be held liable for damages resulting from the use of the software. ' The source code itself is public domain and may be used for any purpose. ' The hex file that results from compiling this program includes libraries ' from the Great Cow Basic compiler that are Copyright Hugh Considine ' under the terms of the Lesser GNU Public License version 2.1 or later. ' GC Basic and source code is available from: http://gcbasic.sourceforge.net/ In effect this bootloader may only be distributed for applications where it is practical to include the required LGPL notification. ---------------------------------------------- These docs last modified 11/13/2010 Terry Newton (wtn90125@yahoo.com)