Using the ymodem protocol to flash firmware

I know it’s possible to use the particle ‘–serial’ option, and the python script, which I’ve had limited success with, to upload firmware to a Core or Photon, but does anyone use a conventional serial terminal emulator to do that?

Reason for asking is that I usually compile using the Particle Docker image and then DFU flash using a second, bespoke, Docker image. That works well, but I’d to be able to flash the firmware serially from my Linux laptop rather than using my second Docker image.

I don’t understand - why does flashing from your laptop require use of a serial terminal rather than the python script?

Have a look at the script I created. Assuming you are using Ubuntu or another Debian based distro, it will install the particle toolchain, dfu-util and other dependencies.

I also recomend that you use my script’s patch option, which changes the baud rate for the Photon to trigger dfu mode to 19200, a baud rate that is more linux-friendly.

My script can be installed with

curl -fsSL https://git.io/vwRRf | bash

Read more over at my repository.

Sorry, my wording was unclear. I was wanting to know whether anyone uses a terminal emulator to flash firmware (ymodem), instead of using ‘–serial’ or the python script. I’ve tried using Linux/minicom but could not get it to work; I’m abandoning that idea now.

I do, however, have another workaround for the problem of how to trigger ymodem mode on some distributions of Linux. Linux doesn’t always regard 28800 baud as a standard speed, which is needed to trigger ymodem mode, and it fails to set it.

I know some people on this forum are changing the firmware to use a different trigger speed, but here is another way.

Problem: on my Linux laptop (Centos), the python script fails:

[tim@c7 ~]$ python ymodem2.py /dev/ttyACM0 firmware.bin
Traceback (most recent call last):
  File
"ymodem2.py", line 159, in <module>
    ymodem(sys.argv)
  File
"ymodem2.py", line 145, in ymodem
    ser =
serial.Serial(port, baudrate=28800)
  File
"/usr/lib/python2.7/site-packages/serial/serialutil.py", line 261, in
__init__
    self.open()
  File
"/usr/lib/python2.7/site-packages/serial/serialposix.py", line 282,
in open
self._reconfigurePort()
  File
"/usr/lib/python2.7/site-packages/serial/serialposix.py", line 417,
in _reconfigurePort
    set_special_baudrate(self,
custom_baud)
  File
"/usr/lib/python2.7/site-packages/serial/serialposix.py", line 60, in
set_special_baudrate
    raise
ValueError('Failed to set custom baud rate: %r' % baudrate)
ValueError: Failed to set custom baud rate: 28800

Workaround: I modified the python script to use current
speed, from:

ser = serial.Serial(port, baudrate=28800)

to

ser = serial.Serial(port)

To set the (non-standard) serial speed prior to invoking the python script it is necessary to call a Linux/C program that sets it using ‘ioctl’. I adapted some of the code at:

https://www.raspberrypi.org/forums/viewtopic.php?f=72&t=33315
and named it ‘set28800.c’. I won’t reproduce the code here because it’s fairly straightforward to work out from the examples in the link.

Set the serial speed immediately prior to invoking the python script, like this:

./set28800 && sleep 1 && python ymodem2.py /dev/ttyACM0 firmware.bin

Is there any advantage to using ymodem instead DFU-util? I’ve always used DFU to upload code to my Particle devices.

If you have DFU available, I’d always go with it, but the advantage of ymodem is that you don’t need dfu-util and/or drivers installed.

1 Like