mihaigalos / miniboot

🏗️ An I2C bootloader for Arduino.
GNU General Public License v3.0
65 stars 18 forks source link

Application fails to load from external memory #9

Closed dBarmpxkos closed 4 years ago

dBarmpxkos commented 4 years ago

Hello, I'm trying to have a go with miniboot under Windows 10 using bus pirate as isp, but the application fails to load to an arduino nano. I am writing a short step by step both for help and for reference for others possibly reading this.

I am burning the fuses: avrdude -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -cbuspirate -PCOM5 -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m

avrdude: safemode: lfuse reads as FF avrdude: safemode: hfuse reads as DA avrdude: safemode: efuse reads as FD avrdude: safemode: Fuses OK (E:FD, H:DA, L:FF)

I burn miniboot: avrdude -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -cbuspirate -PCOM5 -Uflash:w:"D:\Path_to\miniboot\bin/miniboot.hex":i -Ulock:w:0x0F:m

.. Reading | ################################################## | 100% 4.82s avrdude: verifying ... avrdude: 3732 bytes of flash verified avrdude: safemode: lfuse reads as FF avrdude: safemode: hfuse reads as DA avrdude: safemode: efuse reads as FD avrdude: safemode: Fuses OK (E:FD, H:DA, L:FF) BusPirate is back in the text mode avrdude done. Thank you.

At this point the stock bootloader is replaced, because I can't upload programs via USB from the IDE anymore. I can reverse this by rewriting the stock bootloader* which indeed gives the USB upload feature back. So miniboot should exist on the board.

I upload miniboot_uart_to_eeprom_uploader.hex: avrdude -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -cbuspirate -PCOM5 -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m avrdude -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -cbuspirate -PCOM5 -D -Uflash:w:D:\Drivers\Eeprom\bin/miniboot_uart_to_eeprom_uploader.hex:i My target application which I attach in .ino/.hex/.bin forms is converted using: avr-objcopy.exe -I ihex application.hex -O binary application.bin I am using Arduino 1.8.9 for extracting the .hex (Ctrl+Alt+S). The .hex file is extracted using "Arduino Pro or Pro Mini" board selection from the IDE. I am greeted with the prompt using a serial program, followed by my input:

-- Miniboot EEPROM uploader -- Application unix timestamp (decimal): 1570787025 Current unix timestamp (decimal): 1570787235 CRC32 (hex): b21a3e26 Application size (bytes, decimal): 2180 (I get this from opening the .bin with Notepad++) Header written. Please switch to binary mode and send a file of byte length 2180.

At this point, I tried both TeraTerm on Win10 and YAT on Win7 (can't get it to work on Win10 yikes). I upload the .bin using binary mode and it completes. I then dump the contents of CAT24M01 . Using a hex to ascii converter, I can see "Heminibootblink" in the beginning as you describe in README (address byte followed by "miniboot" and "blink" name from the library). However, the application does not run. When I restart the board, it reruns miniboot_uart_to_eeprom_uploader. I also checked internal EEPROM and it is empty.

Any ideas? I can try different tests but I am kinda lost here. I appreciate your effort and input. If I can contribute somehow, let me know.

As a sidenote, when I clone and run make rebuild under /src I get:

The system cannot find the path specified. ECHO is off. -------- start -------- ECHO is off. Cleaning project: rm -f miniboot.hex process_begin: CreateProcess(NULL, rm -f miniboot.hex, ...) failed. make (e=2): The system cannot find the file specified. make: *** [clean_list] Error 2

Using GnuWin32 and by adding it to PATH.

*for burning stock bootloader avrdude -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -cbuspirate -PCOM5 -Uflash:w:"C:\Program Files (x86)\Arduino\hardware\arduino\avr/bootloaders/atmega/ATmegaBOOT_168_atmega328.hex":i -Ulock:w:0x0F:m

mihaigalos commented 4 years ago

Buna seara,

You have at least a couple of inconsistencies in your approach:

Let me know if this at least gets you going and how I can help further down the line.

mihaigalos commented 4 years ago

Please also verify that:

It might also be interesting to dump the whole flash memory after miniboot runs, or at least after it should have run. If you dump with i.e. Atmel Studio, it outputs a hex file. You can then diff that hex with your original hex and see how much miniboot flashes.

Again, please follow the instructions in the readme down to the letter. If you feel the readme is inconclusive or could be improved, please provide a PR and I will merge it.

dBarmpxkos commented 4 years ago

Thanks a lot for the input.

I hooked up an LED and miniboot was active for some ms at restart. I cross-validated that with a logic analyzer, which shows activity on I2C for some time after boot. Nevertheless, no firmware was changed and it run miniboot_uart_to_eeprom_uploader.hex again.

One remark: for the specific setup (Arduino Nano @ 16MHz) and after I uploaded miniboot with the fuses Uefuse:w:0xFF:m -Uhfuse:w:0xD8:m -Ulfuse:w:0xE2, baudrate for serial is one setting lower than it ought to be: i.e. if set at the program at 9600 it will work at 4800 and so on. miniboot_uart_to_eeprom_uploader.hex works at 300 instead of 600. I suspect that the compiled .hex provided here might cause issues when I try to upload a compiled for nano program.

I will update. Thanks again!

mihaigalos commented 4 years ago

The system cannot find the path specified. ECHO is off.

That's because you haven't switched to linux yet. :) Try running it in cygwin or set a symlink to avr-g++ in your cygwin env.

I hooked up an LED and miniboot was active for some ms at restart.

Should blink on every page write, see this line. Your only few ms of blink at start comes from this line. From what you observe, this if is not successful. It might be that your crc is not computed correctly or the reflash is not necessary (i.e.: the eeprom is not 0xFF). I tend to think there is a problem with the crc still. Perhaps the length of the bin is wrong.

mihaigalos commented 4 years ago

you should really dump the contents of the I2C external flash (don't know if I have anything in drivers you could use). Then, just diff that against the original hex.

If you have a single bit error in the whole putting of your hex in the external I2C, the crc will fail when miniboot runs. This might be the case if you mismanaged the baudrate you were talking about.

dBarmpxkos commented 4 years ago

OK. I started over from the beginning. Empty ATmega328, empty external memory. With an LED hooked up, I burn the fuses, followed by burning miniboot; LED stays ON at all times. I proceed in flashing miniboot_uart_to_eeprom_uploader and it does not run. LED stays constantly on and application does not start.

I tried to merge the hex files as instructed in the doc (one-step process) but no luck, LED stays on and bootloader does not exit to application.

For sanity check, if I burn stock bootloader things work so its not hardware (I guess). Obviously this is before all the fancy write to external flash and so on, it has something to do with how and why the bootloader exits; I am trying to get my head around this (I was lured to that comment by the code flow and I loled 😝)

I'm trying with another programmer tomorrow just in case and I will let you know.

you should really dump the contents of the I2C external flash (don't know if I have anything in drivers you could use).

I use this for dumping. Also, I'm giving it a go under Linux tomorrow.

dBarmpxkos commented 4 years ago

Update! All works OK. Burnt fuses, burnt miniboot, burnt miniboot_uart_to_eeprom_uploader. Opened TeraTerm, 300 baud, with terminal newline settings: RECEIVE -> AUTO / TRANSMIT -> CRLF. Added sauce for the header (timestamps, crc, size of bin), file -> send file, check binary checbox and sent .bin file converted with avr-objcopy.exe.

I have a catch as well: What happens if I2C fails (maybe here)?

If everything is OK for I2C, that's the activity; also, miniboot's LED does its thing and bootloader escapes to application (don't mind its actual functionality, either after flashing new app or just exiting to an existing app). good

If I2C fails to init (bad pullups in my case) miniboot LED always stays on, and is stuck not exiting to application whatsoever bad

If i find some time I will try to break these while loops in I2C init if something goes bad. Thanks again for the very interesting resources and the help.

mihaigalos commented 4 years ago

All works OK.

Awesome. That wasn't so difficult, was it? :)

What happens if I2C fails (maybe here)? [..] If i find some time I will try to break these while loops in I2C init if something goes bad.

This is an external i2c lib. You are very welcome to contact the developer there or to use your custom rolled version of the lib. As long as you adhere to the interface signatures, you may use miniboot without any further modification.