Flashing an Arduino Leonardo with AVRDUDE is troublesome #1443
-
The 1. The flash procedure explainedUnlike others, the Arduino Leonardo and Arduino Micro boards identify themselves through one port (eg.
Arduino IDE does it this way. PlatformIO also. 2. What is the problem?The flash procedure explained above consists of three steps. I know how to put the third step in a makefile, but I have no idea how to implement the first two. I could just hardcode the first two steps in Embeetle IDE and run them behind the scenes before launching the third step. I actually just did that, and it works. But it feels wrong. At Embeetle, we have the desire to keep our users informed and free. In other words: if one of our users decides to work on a project outside Embeetle IDE, he/she is free to do so. We achieve that in two ways:
Hardcoding (part of) the flash procedure in the IDE itself defeats this goal. The user cannot run his project outside our IDE anymore. 3. Potential solutionsI see two solutions to this dilemma:
I believe the second solution is the cleanest and will help most AVRDUDE users - also those that have nothing to do with Embeetle IDE. I would love to help with the implementation, but I'm afraid I need a little help and guidance, as I'm not familiar with the source code. Kind regards, |
Beta Was this translation helpful? Give feedback.
Replies: 53 comments 1 reply
-
The way the second device comes up is very OS-specific. I'd like to avoid that kind of OS hacks in AVRDUDE itself, as it opens a can of worms. So far, AVRDUDE suffers only from very few (low-level) things that are really OS specific, as for most of the required abstractions, it can sit on top of the respective backend libraries (libusb, hidapi and such).
Obviously, that script is inherently OS specific. |
Beta Was this translation helpful? Give feedback.
-
Hi @dl8dtl , You basically suggest to defer the first two steps (1. resetting device and 2. waiting for it to return with a new serial port) to an OS-specific script outside AVRDUDE. A good idea, as this keeps AVRDUDE clean from OS-specific stuff. A few questions come to my mind:
Kind regards, |
Beta Was this translation helpful? Give feedback.
-
Hi Kristof, while I agree that it would be a nice addition to AVRDUDE, it is not quite trivial to do this cross-platform. I did this for Windows, check out The code for doing the auto-reset is here, it is just about 1k lines of non-portable code: |
Beta Was this translation helpful? Give feedback.
-
Hi @mariusgreuel , |
Beta Was this translation helpful? Give feedback.
-
Puh. I'm not sure whether I'd like to have that in a supposed-to-be portable application. |
Beta Was this translation helpful? Give feedback.
-
As a compromise, would it be an idea to create a separate "1200 bps touch" handler that would contain all the non-portable code one could call along with avrdude? The boards I know of that are currently "impossible" to flash directly using Avrdude because of this is the Arduino Leonardo, Arduino Micro/Pro Micro, and the Arduino Nano Every. I believe making this work on Windows is the most difficult part, but @mariusgreuel has already figured out this part. At least on my mac, the serial port always has the same name after a disconnect. The only time the name changes is when I use a different USB port. The command below is just to illustrate what I mean. The idea
Here's the python based logic PlatformIO uses: before_ports = get_serial_ports()
if upload_options.get("use_1200bps_touch", False):
env.TouchSerialPort("$UPLOAD_PORT", 1200)
if upload_options.get("wait_for_upload_port", False):
env.Replace(UPLOAD_PORT=env.WaitForNewSerialPort(before_ports)) def TouchSerialPort(env, port, baudrate):
port = env.subst(port)
print("Forcing reset using %dbps open/close on port %s" % (baudrate, port))
try:
s = Serial(port=port, baudrate=baudrate)
s.setDTR(False)
s.close()
except: # pylint: disable=bare-except
pass
sleep(0.4) # DO NOT REMOVE THAT (required by SAM-BA based boards)
def WaitForNewSerialPort(env, before):
print("Waiting for the new upload port...")
prev_port = env.subst("$UPLOAD_PORT")
new_port = None
elapsed = 0
before = [p["port"] for p in before]
while elapsed < 5 and new_port is None:
now = [p["port"] for p in util.get_serial_ports()]
for p in now:
if p not in before:
new_port = p
break
before = now
sleep(0.25)
elapsed += 0.25
if not new_port:
for p in now:
if prev_port == p:
new_port = p
break
try:
s = Serial(new_port)
s.close()
except SerialException:
sleep(1)
if not new_port:
sys.stderr.write(
"Error: Couldn't find a board on the selected port. "
"Check that you have the correct port selected. "
"If it is correct, try pressing the board's reset "
"button after initiating the upload.\n"
)
env.Exit(1)
return new_port |
Beta Was this translation helpful? Give feedback.
-
I have the Arduino Leonardo and I am getting the Arduino Pro Micro and Arduino Nano Every soon. So this is interesting. |
Beta Was this translation helpful? Give feedback.
-
This is what Arduino is doing: run log under Windows with a clone Pro Micro with ATmega32U4.
|
Beta Was this translation helpful? Give feedback.
-
Ref: https://www.avrfreaks.net/forum/uploading-code-new-arduino-nano-every
More details here: |
Beta Was this translation helpful? Give feedback.
-
@mariusgreuel I tried your branch ( https://github.com/mariusgreuel/avrdude) and it seems to work for me for the Pro Micro clone. Run log with a Pro Micro clone.
|
Beta Was this translation helpful? Give feedback.
-
@mariusgreuel I tried your branch ( https://github.com/mariusgreuel/avrdude) under Windows but somehow it does not work for my official Arduino Leonardo as it stuck there forever.
It does work under Arduino.
|
Beta Was this translation helpful? Give feedback.
-
@MCUdude It seems that Arduino does more things for Arduino Leonardo than to the Arduino Nano Every. The reason is to switch COM port, that is not necessary for Arduino Nano Every. But you are right, macOS will not change the serial port number name. Arduino Nano Every (official version):
Arduino Leonardo (official version)
|
Beta Was this translation helpful? Give feedback.
-
This is Arduino is doing under macOS (Mac Mini M1).
|
Beta Was this translation helpful? Give feedback.
-
Ref: this one seems to offer different solutions for different OS. Under macOS, the following shell script file works for me.
It also has the script for Linux using Python/pyserial. This does not seem to work for me under macOS.
Minor modification makes the above work under both macOS (Mac Mini M1) and Linux (Ubuntu 20.04 x86_64)..
Windows batch file using WMIC -- not working for me yet, need to try again.
|
Beta Was this translation helpful? Give feedback.
-
It would be really nice if we somehow could find a way to implement the whole
|
Beta Was this translation helpful? Give feedback.
-
The You already have something written for this exact purpose, actively maintained by the primary manufacturer of the boards that use it and the primary consumer of the package, which is used by Arduino IDE 2.x, and Arduino Create Agent (the local tool used by Arduino Web Editor for facilitating uploads). Why would you want to reinvent the wheel and then maintain it? Go is well suited for this type of application. The amount of wrapper code required to make an application around this package is likely very minimal. |
Beta Was this translation helpful? Give feedback.
-
I vote against using Go, primarily because that would exclude many of us (including me) from being able to work with this code.
Seems like the Arduino people implemented B. Note all the Sleeps() :-). Personally, I think this functionality should be integrated in avrdude. If we are talking external application, we might ditch the entire idea and say 'go and use the Arduino CLI instead'. If we do B, the avrdude codebase already includes most of the code. The only issue left is being able to enumerate all serial devices. I think that is doable. |
Beta Was this translation helpful? Give feedback.
-
@mariusgreuel I agree. Even though Go might provide what we need, I'l have to learn Go before being able to contribute.
I'll assume resolving/implementing the feature mentioned in #907 is a part of this task? |
Beta Was this translation helpful? Give feedback.
-
My previous comment was specific to the proposal of creating a standalone "1200 bps touch" tool. Obviously it is not relevant to the proposal of providing this capability in AVRDUDE itself.
Is it really more effort than what would be required to reinvent the wheel? |
Beta Was this translation helpful? Give feedback.
-
I think B is good enough. I tend to think sigrok libserialport has all the things we need (to combine the following three examples, for example). The question is whether we want to add one more dependency.
|
Beta Was this translation helpful? Give feedback.
-
For that purpose, I'd be fine with it.
Which is not all that of a bad idea, given that this hack is only required for one (or just a few) Arduinos. The "use an external tool" option has the merit that people with specific requirements for activating their own bootloaders could benefit from that as well, so it's not just targeting one Arduino platform only. |
Beta Was this translation helpful? Give feedback.
-
arduino-cli is kind of interesting. I have never used it before. I can see from Windows Device Manager that the port changed from COM5 --> COM8 --> COM5.
|
Beta Was this translation helpful? Give feedback.
-
I'm leaving this here in case I ever forget. For those of you that just need a simple 1200bps touch command that will work on macOS and other *nix systems,
EDIT: Or perhaps even better:
|
Beta Was this translation helpful? Give feedback.
-
Another discussion here:
Interesting |
Beta Was this translation helpful? Give feedback.
-
For those who are using Arduino Nano Every official version, you may encounter issues like this under Linux. |
Beta Was this translation helpful? Give feedback.
-
Not exactly related to this issue but for those who are using Uno WiFi Rev2 (with Arduino custom FW xplainedmini_udpi) due to FW bug. |
Beta Was this translation helpful? Give feedback.
-
In the end, I think we will not include this in avrdude. Therefore I will only keep the documentation label. |
Beta Was this translation helpful? Give feedback.
-
As for the documentation, since this is very specific to a paticular board, I am thinking that Wiki entry is good enough. I will close this as an avrdude issue and move this to discussion. |
Beta Was this translation helpful? Give feedback.
-
Further discussion here: This issue should be resolved by PR #1507. |
Beta Was this translation helpful? Give feedback.
-
Now that #1507 has been merged, I think we can flag this discussion as resolved. |
Beta Was this translation helpful? Give feedback.
Now that #1507 has been merged, I think we can flag this discussion as resolved.