LabVIEW HEX File to ATmega8 Requires a Serial Bootloader

Brian Holt7 min read
Industrial NetworkingOther ManufacturerTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

An ATmega8 will not accept a HEX file pushed down an RS232 line from LabVIEW unless a bootloader is already resident in its flash. That bootloader decides whether the ASCII HEX text can go down as-is or must first be parsed into binary. Reading the file with Read from Text File and getting a string is the easy part. What that string has to become depends entirely on the code waiting at the other end of the wire.

Stop writing the HEX string straight to VISA Write

The first fix everyone tries is to wire the string from Read from Text File into VISA Write and hope the chip programs itself. It fails for three reasons:

  • Nothing is listening. The AVR UART is a peripheral. It only receives bytes when firmware configures it and reads it. With no bootloader, the bytes land nowhere and flash is untouched.
  • Flash is not written by the UART. Self-programming requires code running from the boot section. That code erases pages, fills the page buffer, and commits each page. A raw serial stream cannot do any of that.
  • Most bootloaders do not take raw Intel HEX text. Many expect binary page data wrapped in command bytes, with an acknowledge after each block. Blasting the whole file with no handshake overruns them even when they do parse ASCII.

The second common wrong fix is to run the string through String To Byte Array and send the result as "binary." That produces the ASCII codes of the characters. The text :10See the parsing section for the correct conversion.

Check 1: Does a bootloader answer on the serial port?

Reset the ATmega8 and, inside the bootloader's startup window, send its sync or identify command from a terminal or a small VISA test VI.

  • Valid reply: a bootloader is resident. Go to Check 2 only if replies are intermittent. Otherwise go to Check 3.
  • No reply, and the link passes Check 2: the chip has no bootloader, or the fuses do not start it. Stop here for tonight. This cannot be fixed over RS232.

The permanent repair for the no-reply case needs an external in-system programmer on the ISP header. Use it to:

  1. Write the bootloader image into the boot section.
  2. Set the boot-size and boot-reset fuses so the reset vector points at the bootloader.

Read the fuse bit names and boot section sizes from the ATmega8 datasheet's boot loader support chapter. Record the fuse values you programmed on the fixture label so the next board is built the same way.

As a temporary restore, the same ISP programmer can flash the application HEX directly. That gets the line running while the serial path is built.

Check 2: Prove the RS232 link and reset timing

If the bootloader answers only sometimes, or not at all on a board you know is loaded, check the physical path before blaming code.

  1. Loopback. Jumper TX to RX at the MCU end of the cable. Run VISA Write followed by VISA Read. Echo means the PC side and cable are good. No echo means fix the cable, adapter, or COM port number first.
  2. Port settings. Match baud, data bits, parity, and stop bits to the bootloader build. Set flow control to none unless the bootloader documents otherwise.
  3. Reset window. Most bootloaders listen only for a short time after reset, then jump to the application. Either wire DTR or RTS through a capacitor to the reset pin and toggle it from VISA, or press reset and start the transfer immediately. Read the window length from the bootloader's documentation.

Check 3: Identify the format the bootloader expects

This check answers the original question of whether the string needs conversion. Read the bootloader's protocol description, then pick a branch from the table.

Bootloader accepts What LabVIEW sends Conversion needed
ASCII Intel HEX, line by line One record per write, wait for its ACK before the next None beyond splitting lines and pacing
Binary pages with command framing Command byte(s), address, page data, then wait for ACK Full HEX parse into a flash image
A protocol AVRdude already speaks Nothing directly; call AVRdude with System Exec.vi None; AVRdude reads the HEX file itself

The AVRdude branch is the fastest route back to production. XLoader loads HEX files onto Arduino-class boards over serial using the same approach. Build the AVRdude command line, run it through System Exec.vi, and parse its standard output for the verify result. Only write your own transfer layer if the bootloader is custom.

Parse Intel HEX in LabVIEW into a flash image

Every line of an Intel HEX file is one ASCII record:

:LL AAAA TT DD...DD CC
 LL   = data byte count
 AAAA = 16-bit load offset
 TT   = record type (00 data, 01 end of file,
        02 extended segment address, 04 extended linear address)
 DD   = data bytes
 CC   = checksum: sum of all bytes LL..CC is 0 mod 256

For the binary-page branch, build the image this way:

  1. Read the file with Read from Text File and split it on end-of-line into an array of lines. Strip any trailing CR.
  2. Reject any line that does not start with :.
  3. Take each two-character pair after the colon and convert it with Hexadecimal String To Number into a U8. This is the step that String To Byte Array gets wrong.
  4. Sum all record bytes including the checksum. If the low byte is not zero, abort and report the line number.
  5. For each type 00 record, replace the array elements starting at the record address, adding any extended address from a type 02 or 04 record. Stop at type 01.
  6. Refuse to send any data that lands at or above the boot section start. Writing there overwrites the bootloader.
  7. Send each page in the bootloader's framing and wait for its ACK with a VISA timeout. Retry a page a limited number of times, then abort.

The ECU Measurement and Calibration Toolkit ships an example that parses HEX or S-record files into an array of chunks. The parsing VIs run from the trial install without a license, which makes them a quick reference. The license covers programming an ECU over CAN. That transport does not apply here, so reuse only the parser.

Confirm the ATmega8 runs the new image

  1. Read back. Use the bootloader's read-flash command, or AVRdude's verify, and compare against the parsed image byte-for-byte within the application range.
  2. Checksum log. Log a checksum of the image sent and the image read. It gives the next shift a record to compare against.
  3. Cold start. Power-cycle the board. The bootloader should time out and jump to the application, and the application should run its known startup behavior.
  4. Second load. Repeat the load without the ISP programmer attached. If the second load fails, the application or a fuse change damaged the boot section. Recheck the lock bits and boot fuses with ISP.

Watch for these recurring failures:

  • An application built too large for the space below the boot section.
  • A "convert EOL" option that mangles line endings.
  • A leftover termination character setting in a shared VISA configuration VI.
  • A USB-serial adapter that re-enumerates on a new COM number after a replug.

FAQ

Why does my ATmega8 ignore the HEX file I send from LabVIEW VISA?

With no bootloader in the boot section, no code reads the UART or writes flash, so the bytes are discarded. Install a bootloader once with an external ISP programmer and set the boot-reset fuse, then serial loading works.

Why does String To Byte Array give the wrong data from a HEX file?

It returns the ASCII code of each character, so :10Convert each two-character pair withHexadecimal String To Number to get the real byte values.

Why does the transfer stop partway through a page over RS232?

It also happens when LabVIEW sends the next block before the bootloader's ACK. Disable the termination character and wait for each ACK with a timeout.

Can LabVIEW flash an AVR by calling AVRdude?

Yes. If the bootloader speaks a protocol AVRdude supports, run AVRdude through System Exec.vi and let it read the HEX file and verify. Parse its output for the verify result instead of writing your own transfer code.

Stop and escalate if ISP cannot read the chip signature or the fuses read back differently from what you programmed. Treat that as a hardware or lock-bit problem that no LabVIEW change will fix. Take the part number, fuse readings, and programmer log to Microchip's official AVR support channel, or to the vendor of the bootloader you are using.

Back to blog