Spare Time Labs 2.0



jDraft 2.0




Ten-Buck Furnace

H8S Bootloader

Camera Calibration


Myford VFD

Fun with HC08


printf II

Java Goes Native





New Furnace

New Furnace
Part II

Linux 101



Gas Fired Furnace

Down Memory Lane


Wheel Patterns






JNA Benchmark

Contact Info
Created 7.3.2008

bl08 - a Free bootloader for MC68HC908 Micro Controllers

This page is about bl08 which is part of my Free HC08 tool chain for writing software for HC08 microcontrollers. It is a bootloader software that downloads via serial port a program file to a HC08 microcontroller and programs it into the Flash memory there.

Looking for the source code? You can browse it on this page or you can download a zip-archive that contains the code and Mac OS X binary.


Breaking News!

Jaromir Sukuba has improved the code a lot and you can find his contribution in github .

Today the git repo of Tormod Volden linked to below is longer available, so please try the link above for Jaromir Sukuba's github link for the latest and greatest source code.

This note added 6.7.2010

Since this page was published in 2008 I've received a few contributions and the code has been enhanced quite a bit. Robert Larice has contributed a new cpu type and some improvements related to the how the programming code returns to the on chip monitor. Tormod Volden has cleaned up the code, fixed a few issues and improved the code. He has also gone through the trouble of setting up a GIT repository to help in tracking changes, so I recommend you get the latest code from the git repository, just click on the 'snapshot' on the latest version.

(Discrepancy alert: note that the code, as published, defaults to using serial port '/dev/tty.usbserial-FTOXM3NX', which is my USB serial port adapter. This is contrary to what I've written on this page, which says that it defaults to '/dev/ttyS0'. I may change that eventyally on this page but for now, you can change the source code yourself, or override the setting with the '-c' parametes.)

The code is heavily based on an earlier program called bload that I wrote some years ago for Hitachi/Renesas H8S controller.


Tools like this exist and I did do my homework and searching and evaluating several options but none of them fullfilled my self imposed requirements. I wanted to have a tool that was free as beer and one that could be run on Mac OS X. Yes, I know, it is just stuppid to try to do this (write programgs) on Mac OS, but , Mom, I want to!

One of the programs I found was sprmr08 but this was ridled by the usual dependency hell of Free(dom) software requiring the use of even more Free/Linux stuff like asl and pctts, not to mention some Linux specific headers and libries. So, over 60 files in the spgmr08 project alone and three opensource projects to compile, each of which can take hours to port to your favourite operating system, and you may well find yourself asking, like I did:

All this just to Flash a few bytes to a microcontroller through a serial port?

I also disliked some of the design decisions, like having a built in shell and a graphical user interface . Like there weren't enough similar but different shells in the world and to incorporate a simple tool like this to a sane build/debugging process/enviroment all you need and want is a command line interface.

So it was time to roll my own.

And the result is a single file C-program that should compile in any POSIX compatible operating system without modifications. It only uses standard headers and libries that all POSIX compatible system should have out-of-the-box. In Windows you need to use MinGW or Cygwin, but hey, in Windows you have plenty of choice anyway, so go ahead and hitch your wagon to your choise of HC08 development tools.

SpareTimeLabs proudly presents bl08 with the following features:

  • Fast Flash programming directly from S-record files
  • Executing code on the target makes trying out your code a breeze
  • Automatic RESETing speeds development cycles
  • Builtin terminal emulator helps with debugging
  • Download feature enables examining target code
  • Light Weight - just one file to compile
  • Easy to Port - Only POSIX APIs used
  • Compiles cleanly with: gcc -Wall -std=c99 -pedantic
  • Command Line Interface - easy integration with IDEs
  • Free as in Freedom and beer
  • Installation

    To install the bl08, just save the source from this page to a file 'bl08.c' and compile it with:

    cc -o bl08 bl08.c

    To test it, type:


    which should produce the following standard help text:

    bl08 burns MC68HC908 Flash memory from S-record file(s) using Monitor mode Usage: bl08 [-abcdefhiklmnpqrstuvx] [filename...] -a address Set dump memory address (needs -s option too) -b baudrate Set baudrate for target communication -c device Set serial com device used to communicate with target typically /dev/ttyS0 -d dumpformat Set dump format, supported formats are: 'srec' -e Erase target using mass erase mode, clearing security bytes -g address Go execute target code from address or use '-g reset' -f Use fast programming method -h Print out this help text -i Read input (S-records) from standard inputi -k Kill previous instance of bl08 -l verbosity Set verbosity level, valid values are 0-4, default 1 -m Terminal emulator mode -n Print bl08 version number -o param=value Override target parameter value param = ROMBASE,FLASH,PUTBYTE,GETBYTE,RDVRRNG,MONRTN ERARRNG,PRGRNGE,FLBPR,MONDATA,PAGESIZE,EADDR -p Use page erase when programming flash -q Run quietly, same as -l 0 -s size Set dump memory size -r pulse Pulse DTR for pulse milliseconds -t cputype Set CPU type, valid values are: 'gz16' -u Upload only (do not program flash) -v Verify when programming -x cpuspeed Set CPU speed, typically set for Fbus (in MHz) x 4 addresses and sizes in decimal, for hex prefix with '0x'

    Noticed the './' infront of the command bl08? That is because your current directory typically is not in your path and we did not give execution rights to the file anyway. You can of course copy the file to some directory that is in your path and 'chmod a+x bl08' it to make it executable.

    Usage examples

    To use bl08 you need the application you want to program into the target in S-record format. You also need a serial port, the target MCU and a monitor mode adapter to put the target into Monitor Mode. For info on that and writing HC08 code see my page on Having fun with HC08,but for now, assume you have your code in file hello.s19.

    To download your application to the target you RESET the target to Monitor Mode and just type:

    ./bl08 hello.s19

    The above assumes that you are using MC68HC908GZ16 with Fbus frequency of 4 MHz and that your serial port is at '/dev/ttyS0'. If your setup is different, you need to pass some more parameters to the bootloader. The bootloader does not support, out of the box, all HC08 variants so you may need to add support for your CPU or pass even more parameters to the loader, more on this later.

    Here is an example that specifies the MCU variant and clock frequency of 4 MHz (note that clock frequency is passed in MHz times two for gz-variants, for most others it is times 4):

    ./bl08 -t gz16 -x 8 hello.s19

    I'm a great believer in continuous integration, refactoring and confidence building. I'm also fond of debugging things with 'printf' and I'm a lazy and impatient bugger. So once the code is downloaded I want to execute it and see how it is doing. To do that I would need to RESET the target CPU and start a terminal emulator to talk to it. (Note that you cannot keep the terminal emulator running all the time as this would tie the serial port down prohibiting bootloading). What a bore, all that resetting and launching and quitting applications. Fortunately (or was it my laziness) bl08 incorporates a built in terminal emulator and the possibility to start executing the code on the target.

    So here is an example that downloads your code, flashes it using a fast programming algorithm into the Flash ROM, executes it and then the enters terminal mode to display what the code outputs using the serial port, and RESETs the CPU on the fly for good measure!

    If you are using Eclipse then you can see the output directly in your console view!

    ./bl08 -r 100 -m -f -g reset hello.s19

    And for good measure here is full blown command line that for flashing and running the 'hello' code in HC908JB8 variant running from 3 MHz crystal (with PT3=1) and using my USB-serial port cable/adapter on my Mac OS X:

    ./bl08 -t jb8 -x 6 -c /dev/tty.usbserial-FTOXM3NX -b 4800 -m -f -g reset hello.s19

    Quite a mouthfull, isn't it! At this point you may well think that who's going to type all these parameters and remember them.

    Of course nobody is going to do that, what you do is you create a script that contains the command line and execute that script. Just create a text file with your favourite text editor and copy/paste a command into it from this page with all the parameters you need and save it to a file bl. Then you can execute the command by just typing './bl' or better yet, you can incorporate into your Makefile so that after a succesfull compilation of your HC08 application the code is automatically downloaded and executed!

    It is also easy to incorporate this to many integrated development enviroments like Eclipse/CDT.

    Parameters in Hex or Decimal Format

    Many of the command line options take numerical arguments which for convenience can be decimal or hex. To use hexadecimal values precede them with '0x'. For example the following two lines are equivalent:

    -a 0x1000
    -a 4096

    On Programming

    As stated the main function of this bootloader is to read in the contents of a S-record file and program it into the Flash memory of the target HC908 device. Programming is performed using the built in programming routines that are in the internal ROM of most, but not all, devices.

    For memory addresses for which the S-record contain no data a value of 0xFF is used to fill the gaps.

    Data outside the 0x0000-0xFFFF (16 bit addressable range) is silently ignored.

    On Security

    HC908 microcontrollers implement Flash content protection which disables reads from the Flash if invoked. When reset into the Monitor Mode eight bytes are sent to the device and if they do not match the contents of Flash at 0xFFF6–0xFFFD then the security is invoked and all reads from Flash return 0xAD.

    The bootloader always sends the secutiry bytes as eight times 0xFF which means that if the security bytes have been set to some other value, the device will be locked and you cannot read the Flash. However, the device can always be programmed using the default mass erase feature.

    Note that in my experience some devices need a proper power cycling (turning the device power off down to a millivolt level) after mass erasing before you can program them.

    Serial Port Settings -c devname -b baudrate

    By default bootloader uses the serial port named '/dev/ttyS0' which is many systems have by default. However modern Mac computers have no serial ports and if you use a USB serial port adapter then the device will called something different. To find out the name you do ls /dev and take your pick (by guessing!) from the numerous options listed. You then pass this device name to the bootloader with the -c devname option.

    The character size is by necessity 8 bits with two stop bits no parity and cannot be changed. The baudrate defaults to 14400 but this can be set with the -b baudrate option.

    For the correct baudrate you need to consult the datasheet of your HC08 variant and your schematics as the baudrate depends on at least the CPU variant, clock frequency and some I/O pin settings.

    The baudrate is passed directly to the serial device using POSIX termios.h call cfsetispeed() so all standard and most non standard baudrates supported by the device should be usable.

    CPU Speed -x freq

    Flash programming in HC08 is actually quite simple compared to some other MCUs but it still requires some carefull timing. The timing calculations, like everything in a microprosessor realy, depends on the master clock called Fbus clock. This is the internal clock speed at which the CPU runs. This is typically the external clock or crystal frequency divided by four on HC08 family parts, but check your datasheet! Once you know the frequency in MHz units you multiply it by four and pass it to the bootloader with the -x freq command line option.

    What to do if your clock frequency is very low, like 32768 kHz? I honestly don't know, never tried it, but I guess that because the delays used in the Flash programming are rather small, you may have to use a higher frequency during programming the flash.

    Fast Programming -f

    By default (or rather by historical accident) the bootloader programs the flash by writing the data one page at the time into the target RAM and then calls the flash programming routine. This is somewhat waste full, especially with certain USB serial ports that exhibit longish read latency, so I've created a fast option invoked with '-f' which uses a helper code in the target RAM that reads the whole area to be programmed into the Flash and programs it on the fly, which considerably reduces the serial line trafic, making the whole programming process faster. Especially on Mac OS X with FTDI USB Serial Port Adapters.

    Verifying Programming -v

    For verifying that the transfer and programming of data has been done correctly you can use the '-v' option to enable verification. Verification is not compatible with the fast ('-f') option so it is ignored if the fast programming is used.

    Because verification prohibits the use of the fast option I do not use it except for final production burns and I've never even suspected having problems related to serial communication failures or flash programming errors. With an electrically reasonably clean set up including short cables, proper layout, bypasses and power supply, the whole process is very robust, so there is little need for verification.

    Not Programming -u

    Sometimes you just want to upload some data but not program it into the Flash. By default, if a file name is given on the command line, the loader will attempt to flash it into the Flash memory. To prevent that you can use the '-u' command line switch.

    Just Erasing -e

    Sometimes you just want to erase a device. Erase is automatic if you specify a file to be flashed but if you just want to erase without programming anything you can use the '-e' command line switch.

    Executing Code -g address

    Once your target application has been downloaded and flashed you of course want to try it. So you disable the Monitor mode by turning a switch and reset the target by pressing a button. Rather tedious I think. Instead you can use the command line option -g address which will cause the target to start executing code from the given address. Or better yet, you can use the -g reset option to start execution using the address stored in the reset vector at 0xFFFE.

    Note that being able to execute code on the target in this fashion enables all sorts of interesting options as instead of Flashing the code you can just as easily dowload some code into the RAM and execute it from there. With some precompiled pieces of HC08 code in S-record files and some clever scripting I can envison a lot interesting things.

    Terminal Mode -m

    As I mentioned I like using 'printf' to debug my code. In an embedded application there seldom is a real console on which the printf could output its thing, but it is often possible to just dump the output through the serial port to an attached data terminal. Of course nobody uses a real terminal anymore but a terminal emulator like Z-term or some such. That's fine but the problem is that to bootload the code the serial port must be free for the bootloader to use, which meas quitting the terminal emulator every time you bootload the code. And then re-start the emulator again.

    For this reason bl08 has a built in terminal emulator mode which can be invoked with the '-m' command line switch. This is a very simple terminal emulator that basically just passes data from serial port input to stdout and from stdin to serial port output. Nothing fancy, but I've found it very usefull.

    Page Erase -p

    MC68HC908 family of microcontrollers support a security mode that prevents reading the contents of the Flash memory if the security has been set. The security is set if the eight bytes starting address 0xFFB6 do not all contain 0xFF. If the security is set you have to mass erase the whole Flash before you can program it. By default bl08 uses mass erase so this is not an issue.

    However if your target application requires some non volatile storage for end user settable parameters you may want to store those parameters into the Flash memory as well, as HC08 variants do not come with internal EEPROM. When developing an application like that it maybe inconvenient to erase those parameters everytime you update the software in the target. But that is what happens if you use mass erase.

    This is where the page erase option '-p' comes in handy. Please note that the security bytes are also interrupt vectors so if you use those interrupts you are out of luck and need to mass erase every time.

    By the way, from my personal experience and from surfing the net, it seems that for some HC08 variants at least it is necessary to actually power cycle the device after erasing the security bytes. Also it seems that for some variants you can program the device after erasing the security bytes without resetting the device inbetween but you cannot read the flashh or verify the programming before you RESET the device. I have not found anything very definite or official about this but thouhgt I'd mention it here.

    Killing Previous Session -k

    Working with the terminal emulator mode and multiple command line shells can be fun and effective but then you easily run into situation where when you invoke the bootloader it will fail on opening the serial port which is busy because a previous instance of the bootloader is using it. Worse, if your are running the bootloader as an external tool in an IDE enviroment like Eclipse there maybe no easy way to kill a zombie external tool. What you are left with is to do 'ps' to find out the 'pid' of the bootlaoder then do 'kill pid'.

    I found myself doing that too often so I added the '-k' option that kills the previous instance of itself. This works by recording the process id (pid) of the running instance in a temporary file named 'bl08PIDfile.temp'. If this file is left dangling it is safe to delate it.

    Reading Memory -a -s -d

    It is also possible to use the bootloader to download memory contents from the target with the command line option -a address -s size which will read the memory and dump it out to console in the selected format. You can set the format with the '-d format option. At present the only supported formats are 'srec' for Motorola S-records and 'hex' which is a simple hexadecimal dump, which format is also the default.

    RESETting -r pulselength

    By this time you have probaply noticed that many features of the bootloader are designed to smooth the development cycle. You know the drill: edit source, make code, close terminal, switch to monitor mode, reset target, download code, switch to user mode, reset target, start terminal -- ad nauseam. At one time I had my Makefile write out the build start times and I later anyzed the results with a spreadsheet and on average I actually built and downloaded the code at ten minutes interval, eight hours a day, for three months in a row!

    So time to introduce my friend the auto reset. With the command line option '-r pulselength and a circuit something like below you can automate the resetting so that the CPU is always reset before download is attempted. Combine this with the '-g reset' switch, put it all into your Makefile and you've automated your build cycle to just 'edit & make'. Not bad.

    The RESETting is done by pulssing the DTR line of the serial port for the duration of pulselength which is in msecs. When designing your reset circuit remember that normally DTR idles at negative voltage between -3 and -15 volts and that when pulsed ON it is between +3 and +15 volts. Your maximum load on the DTR line should not be lower than say 7000 Ohms to be on the safe side.

    Running Quitly -q

    I know, it goes against the tradition that a comman line tool output something when things go well: no news is good news! But as the bootload process does take some seconds to complete I want see that it is progressing so by default the verbosity level ('-l' option) is set to 1 to give out some reasonable amount of feedback of the progress. If you want the bootloader to run quietly you can use the '-q' option.

    Trouble Shooting -l verbositylevel

    Bootloading is rather simple and robust, just make sure you enter Monitor Mode succesfully and that your serial communication works both ways. But at times you may have to trouble shoot things so you can set the amount of feedback the bootloader gives with the -l verbositylevel option.

    At level 0 it prints out nothing (as long things go smoothly) and this equivalent to the '-q' option. At level 4 it prints out every byte sent and received through the serial port and then some. That is a lot of output and will slow down things considerably. Level 1 is the default and gives what is my idea of what sort of output I want to see an a daily bases.

    Expanding bl08 -o param=value

    At present the bootloader includes support for a limited number of variants of the HC08 family. I plan to add support for more as time permits, but to add support for a particular variant I need access to that variant as I do not want to do it blindly. So you may encounter a variant which is not directly supported by bl08, at which point you have two options. You can either modify the source code to add the support or override some internal parameters via the command line interface. Both of these require you to have some understanding of how the bootloader internally works.

    bl08 works by taking advantage of the Monitor Mode and the built in Flash programming routines in the internal HC908 mask ROM. For description of the Monitor Mode refer to the datasheet of the HC08 variant you are working with. For description of the internal Flash programming routines, see the following application notes.

  • AN2635
  • AN2874
  • AN1831
  • AN2545
  • It is worth noting that it always pays to check the data sheet for your variant inspite of what the application notes say. Also, in my experience, not all the nitty gritty details are explained anywhere, sometimes you just have to experiment to find out what works.

    Remember, bootloading is pretty simple stuff, but get one detail wrong and it won't work. Devil is in the details...

    The internal ROM contains routines to peek and poke the internal RAM memory and execute code from a given address. It also contains routines to program the flash memory as well as code to communicate through as single wire interface using standard async protocol. The later is note worthy in that not all HC08 variants support serial port but all support monitor mode where the serial communication is done with bitbanging. Borrowing this four your own purposes can be handy at times.

    Programming the flash works by writing some small helper code into the target HC08 internal RAM and executing this code. This litle helper code is needed because it is not possible to directly invoke the flash programming routines with the Monitor Mode. The helper code is hand assembled into the bootloader source code so that porting the bootloader does not require porting an assembler too.

    The addresses of the flash programming routines vary between the variants of the HC08 family. The bootloader 'knows' the addresses of these routines for the supported variants but you can override them on the command line if you know better! For example to set the address of the GETBYTE routine to 0x1C00 use on the command line the following fragment:

    -o GETBYTE=0x1C00 
    Refer to the application notes for the names and addresses of these routines. Note that the addresses of PUTBYTE and MONRTN re-entry point seem to be well kept secrets: I had to disassemble th monitor mode code from the internal ROM to find them out! PUTBYTE is routine that sends out a byte through the serial port and MONRTN is and entry pointa allows returning to the Monitor Mode from the helper code.

    The bootloader uses the following names for these routines which are also the names of these routines in the application notes:


    In order to erase/program the flash it is necessary for the bootloader to know the address of the flash protection registers. Again the bootloader knows this, but you can override it using something like:

    -o FLBPR=0xFF7E 
    The mass erase routine needs to access an address within the Flash memory address range to erase the Flash. If the Flash protection is implemented using Flash memory cells, then this is not enough, the erase routine must access the very address of the FLBPR when erasing the memory. However, if the Flash protection is RAM based, then the FLBPR is not within the Flash address range and you need to specify an address that is. For this purpose the mass erase address is specified separately from FLBPR and can be overriden with:
    -o EADDR=0xDC00 
    The flash programming routines also use some RAM to pass some parameters and the address of that RAM block maybe different in different cpu variants and can be overriden with:
    -o MONDATA=0x0048 
    It is also necessary for the bootloader to know the starting affress of the Flash memory in the target device and this can be overriden with:
    -o FLASH=0xE000 

    BTW the last digits of a HC908 part number tell the Flash memory size on that device, thus MC68HC908GZ16 is a 16k device. 16 k is 16 x 1024 or 0x4000 and as the Flash is always at top of the memory map the start address becomes 0x10000-0x4000 = 0xC000. And so on.

    The Flash page size can be overriden with:

    -o PAGESIZE=64
    If, instead of overriding these parameters (and there are quite a few as you have noticed) you want to modify the source code, feel free to do it, it is pretty straight forward, just look for the setCPUtype() routine in the source code and taking your cue from already implemented ones you should have little trouble.

    If you add more cpu types I'd be happy to incorporate them into my 'official' distribution here, so please mail me.

    That's All, Folks

    Hope this helps someone out there to have fun with embedded software development and please stay tuned for something completely different next time.

    br Kusti