Go Down

Topic: Standalone Arduino as serial programmer (Read 703 times) previous topic - next topic

franck102

Mar 13, 2018, 04:26 pm Last Edit: Mar 13, 2018, 04:38 pm by franck102
Hi all,

This must have been discussed before but I can't nail down the right search terms...

I am wondering how hard it would be to set up an Arduino (Uno or similar) to read .hex sketches from an SD card and upload them to another Arduino over Serial?

Is there any such sketch around? My idea is:

- Use the computer to compile and to copy the .hex file  to the SD
- Plug the SD card into the programmer Arduino
- Connect the two arduinos
- Start the programmer sketch to program the target

The target will have a bootloader installer.


Any pointers? Thanks!
Franck

Edit: before anyone asks, the reason is that I need to upgrade a number of sensors around the house and carrying the laptop around everytime, and in weird locations sometimes, is a real pain...

CrossRoads

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

franck102

#2
Mar 13, 2018, 04:54 pm Last Edit: Mar 13, 2018, 04:56 pm by franck102
Right, I was that option. My two concerns are:

- the risk of bricking the target board if something goes wrong (fuses...)
- I'd rather build this from the standards parts I have (pro mini or mini mega and SD modules)
- Probably lots of options to manage on the programmer

With Serial I just need to get the baud rate right, and no risk of bricking the target board.

Franck

franck102

Am I missing something w.r.t. the complexity of the project?

Is it not just a matter of using a digital pin to trigger the reset, the streaming the .hex file over Serial?


Franck

sterretje

Am I missing something w.r.t. the complexity of the project?

Is it not just a matter of using a digital pin to trigger the reset, the streaming the .hex file over Serial?


Franck
I have my doubts; look at the code for optiboot (used in newer Unos and Nanos). You will have to provide the reverse using a programmer if you want to use USB/Serial. And next consider that there are different bootloaders (older Nanos used e.g. something else).

Your best bet might be a Raspberry Pi in some elementary form (few buttons, 16x2 display) that can run avrdude commands.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

franck102

I have my doubts; look at the code for optiboot (used in newer Unos and Nanos). You will have to provide the reverse using a programmer if you want to use USB/Serial. And next consider that there are different bootloaders (older Nanos used e.g. something else).

Your best bet might be a Raspberry Pi in some elementary form (few buttons, 16x2 display) that can run avrdude commands.
Hmmm, good point, looking at the code it seems the only info the bootloader is giving to avrdude is minor & major version - so isn't the protocol always the stk500 seen in the sketch above?
I mean the IDE doesn't know what bootloader is running on the board, right, so there must be a universal protocol that works?

Franck

franck102

Just found a thread that seems relevant:

http://forum.arduino.cc/index.php?topic=346888.15

... I'll check that out tomorrow.

Franck

franck102

I have a first rough version of a Serial uploaded working, and a question about the protocols:

I would like to auto detect whether the bootloader expects stk500 or stk500v2, however I don't see anything obvious in the specs to reliably make the call?

The stk500 bootloaders i looked at don't seem to implement the stk500 get_signon 0x31 command. And there isn't a single command that's common to the two protocols?
Best bet at this stage would be to try and get the stk500v2 signature bits and revert to v1 if that fails... any better suggestion?

Thanks!

franck102

#8
Mar 15, 2018, 03:35 pm Last Edit: Mar 15, 2018, 05:14 pm by franck102
I have attached a first shot at that serial uploader, I could use some feedback on the protocol implementation from people experienced with bootloaders.

At this point the programmer needs two serials (e.g. mega2560); I have only tested uploading to a UNO, with the default IDE bootloader ( uno.bootloader.file=optiboot/optiboot_atmega328.hex ).

Here is a sample output from the uploader:
Code: [Select]
Serial uploader starting...
Found sketch binary: TESTTY~1.HEX
Resetting target board... done.
AVR device initialized and ready to accept instructions.
Device signature:  0x1E 0x95 0xF
Bootloader version: 4.4
Writing flash...
2030 bytes of flash written.
Verifying flash memory against the sketch...
2030  bytes of flash verified.
Programming done, thank you.

Franck

franck102

I have uploaded the code to GitHub, feedback welcome:
https://github.com/franck102/SerialUploader

Code: [Select]
Serial upload sketch for Arduino.

This sketch turns your Arduino into a standalone serial programmer.
How to use:

1. Prepare a programmer board with an SD card
2. Set up preferences in SerialUploader.h
3. Upload the SerialUploader.ino sketch to your programmer board
4. Compile the sketch you want to program (e.g. using the Arduino IDE)
   (_Remember to adjust the IDE board settings for the target board!_)
5. Locate the generated <sketch>.ino.hex file on your file system, and copy it to the SD card
6. Move the SD card over to the programmer board
7. Connect the programmer board to the target board:
    - programmer            -> target
    - Vin                   -> Vin
    - Gnd                   -> Gnd
    - PIN_RESET             -> Rst
    - SERIAL_TARGET Rx pin  -> target's Tx pin
    - SERIAL_TARGET Tx pin  -> target's Rx pin
8. Reset the programmer to start the upload sketch

The built-in led on the programmer will show:
- steady light while the upload is in progress
- sequences of 2 quick blinks if the upload succeeded
- sequences of 5 quick blinks if the upload failed

The sketch will try standard upload speeds down from 115200 bps. This works well, but as an alternative you can add a
boards.txt file on the SD card: the sketch will find the first occurence of "upload.speed=" in the file, and will use
the upload speed specified there.
Sample file:
    # Upload speed for serial uploader
    optibootm32.upload.speed=38400

The sketch appends to an upload.log file on the SD card: you can check that on the computer to see what happened.

Tested configurations:
- mega2560 clone programmer uploading through Serial1
- (coming next) Uno programmer uploading through Serial
- Uno target board, optiboot, 115200
- Pro mini target board @ 8MHz, minicore, 38400

sterretje

Great; when I ever find the time, I will have a look at it and try it out. Thread bookmarked ;)
Karma added for the effort and persistence.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

westfw

Quote
I would like to auto detect whether the bootloader expects stk500 or stk500v2, however I don't see anything obvious in the specs to reliably make the call?
Doesn't v2 have a whole "message format" wrapped around each command?  If you send "1 " to a v1 chip ("get signon") you should get a STK_INSYNC (0x14) back, while a v2 chip will sit there waiting for a valid "message" (that has to begin with 0x1B)


franck102

As far as I can tell optiboot for one doesn't implement v1's get signon (0x31), and 0x31 is leave programming mode in v2, so not great as a test cmd.

I will experiment with v2's signon 0x01, which isn't a valid v1 command, and see how v1 bootloaders react.

Franck

westfw

Quote
for one doesn't implement v1's get signon (0x31)
I'm pretty sure it's one of the commands that optiboot handles in it's default "else" case; all of which it answers with "yeah, sure" (STK_INSYNC), and if that's not appropriate it's up to the other side to complain, or send additional bytes which result in reboot...  If not, there's "0 " (GET_SYNC), which we can see the bootloader responding to in a "very verbose" avrdude log:

Code: [Select]
avrdude: Send: 0 [30]   [20]
avrdude: Recv: . [14]



Quote
and 0x31 is leave programming mode in v2, so not great as a test cmd.
Doesn't matter if it exits; you can just reset it again, and you know what's there...
Besides, in stk500v2, the "leave programming mode" would have to be wrapped in a message with a proper CRC and whatnot...


franck102

It turns out that the MegaCore bootloaders support page sizes greater than 128kb through stk500v1, so I don't have any incentive to implement stk500v2 after all...

https://github.com/MCUdude/MegaCore

With those cores and auto-detection of the baud rate I can upload to my Unos, pro minis, and atmega2560s without any configuration, which is all I wanted :)

Thanks for the help!

Go Up