udev + bossa = failure to autorecover?



  • Had another silly idea; if my RPi should detect a BOSSA device plugged in, why not have it automatically flash the board with the appropriate firmware.

    While all the Duets have different usb id's when running the firmware, while in the bootloader they're all the same - fortunately bossac can query the chip and from the chip family we can determine which firmware is correct.

    Bus 001 Device 006: ID 1d50:60ec OpenMoko, Inc. (Ed. Duet 2 Wifi)
    Bus 001 Device 006: ID 1d50:60ed OpenMoko, Inc. (Ed. Duet 2 Maestro)
    Bus 001 Device 004: ID 1d50:60ee OpenMoko, Inc. (Ed. Duet 3)
    Bus 001 Device 008: ID 03eb:6124 Atmel Corp. at91sam SAMBA bootloader
    

    So to get the ball rolling we need some udev rules.

    /etc/udev/rules/99-duet.rules

    ACTION=="add", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="6124", RUN+="/home/pi/duet_bossac.sh"
    
    

    and reload sudo udevadm control -R

    /home/pi/duet_bossac.sh contain:

    #!/bin/bash
    
    #RRF2 files and urls
    D2MF=~/DuetMaestroFirmware.bin
    D2MFURL=https://github.com/dc42/RepRapFirmware/releases/download/2.05.1/DuetMaestroFirmware.bin
    D2CF=~/Duet2CombinedFirmware.bin
    D2CFURL=https://github.com/dc42/RepRapFirmware/releases/download/2.05.1/Duet2CombinedFirmware.bin
     
    #RRF3 files and urls
    #D2MF=~/DuetMaestroFirmware.bin
    #D2MFURL=https://github.com/dc42/RepRapFirmware/releases/download/3.0/DuetMaestroFirmware.bin
    #D2CF=~/Duet2CombinedFirmware.bin
    #D2CFURL=https://github.com/dc42/RepRapFirmware/releases/download/3.0/Duet2CombinedFirmware.bin
    D3=~/Duet3Firmware_MB6HC.bin
    D3URL=https://github.com/dc42/RepRapFirmware/releases/download/3.0/Duet3Firmware_MB6HC.bin
    
    
    verifyversion()
    {
      PORT=$1
      #sleep a little extra if asked to do so with $2
      [ $# -eq 2 ] && /bin/sleep $2
      #init serial
      /bin/stty -F $PORT 57600 raw -echo &&
      #flush serial
      /usr/bin/timeout 1s /bin/echo -e "\n\n" > $PORT
      /usr/bin/timeout 2s /bin/cat $PORT &> /dev/null
      /bin/sleep 1s
      #ask for current version
      /usr/bin/timeout 2s /bin/cat $PORT | head -n1 &
      /usr/bin/timeout 1s /bin/echo M115 > $PORT
      /bin/sleep 1s
    }
     
    
    erase()
    {
      PORT=/dev/$(ls $1)
      /bin/echo @Erasing
      /bin/echo Device is: $PORT
      /bin/echo Board is:  $(cat $1/../../manufacturer): $(cat $1/../../product) $(cat $1/../../version) \(USB $( cat $1/../../idVendor):$( cat $1/../../idProduct)\)
      verifyversion $PORT
      #send duet to bootloader
      /usr/bin/timeout 2s /bin/cat $PORT | head -
      /usr/bin/timeout 1s /bin/echo -e  "\nM999 P\"ERASE\"" > $PORT
      /bin/echo Waiting for board to settle
      /bin/sleep 5s
    }
    
    flash()
    {
      PORT=/dev/$(ls $1)
      /bin/echo @Flashing
      /bin/echo Device is: $PORT
      /bin/echo Board is: \(USB $(cat $1/../../idVendor):$(cat $1/../../idProduct)\)
      case `/usr/bin/timeout 5 $BOSSAC -i -p $PORT | grep Device | cut -d : -f2 ` in
      " ATSAM4S8")
        /bin/echo "Duet 2 Maestro (ATSAM4S8)"
    	bossa  $D2MF $D2MFURL $PORT && verifyversion $PORT 5s
        ;;
      " ATSAM4E8")
        /bin/echo "Duet 2 Wifi/Ethernet (ATSAM4E8)"
    	bossa  $D2CF $D2CFURL $PORT && verifyversion $PORT 5s
        ;;
      " ATSAME70x20")
        /bin/echo "Duet 3 6HC (ATSAME70x20)"
    	bossa  $D3 $D3URL $PORT && verifyversion $PORT 5s
        ;;
      *)
        /bin/echo CPU not identified.
        /bin/echo lsusb:
        /usr/bin/lsusb
        ;;
    esac
    }
    
    bossa()
    {
      FW=$1
      FWURL=$2
      PORT=$3
      #[ ! -s "$FW" ] &&
      echo Downloading $FWURL
      wget -q "$FWURL" -O $FW
      #flash with debug enabled, supress most of it
      [ -s "$FW" ] && /usr/bin/timeout 120 $BOSSAC -d -p $PORT -e -w -v -b $FW -R 2>&1  | tee bossa.log | grep -iv addr
      #delete log if successful
      grep "Verify successful" bossa.log &> /dev/null && rm -f bossa.log
    }
    
    BOSSAC=~/BOSSA/bin/bossac
    if [ ! -f "$BOSSAC" ]; then
      [ ! -f /usr/bin/git ] && sudo apt install -y git
      git clone https://github.com/shumatech/BOSSA ~/BOSSA
      cd ~/BOSSA
      make bossac
    fi
    
    #test for Duets with working RRF vendor 1d50 product 60e?
    for i in $(find -L  /sys/bus/usb/devices/ -maxdepth 2 -name "tty*"); do
      grep -i "v1d50p60e[c-e]" $i/../modalias &>/dev/null && erase  $i
    done
    
    #test for SAM-BA vendor 03eb product 6124
    for i in $(find -L  /sys/bus/usb/devices/ -maxdepth 2 -name "tty*"); do
      grep -i "v03ebp6124" $i/../modalias &>/dev/null &&  flash $i
    done
    

    Connecting a erased board shows udev is starting the script but it doesn't do much. I run the script as pi and it works fine as show by the logs

    Mar 16 05:40:12 duet3 kernel: [ 1980.232111] usb 1-1.1.2: USB disconnect, device number 16
    Mar 16 05:40:18 duet3 kernel: [ 1986.668315] usb 1-1.1.2: new full-speed USB device number 17 using dwc_otg
    Mar 16 05:40:19 duet3 kernel: [ 1986.800823] usb 1-1.1.2: New USB device found, idVendor=03eb, idProduct=6124, bcdDevice= 1.10
    Mar 16 05:40:19 duet3 kernel: [ 1986.800837] usb 1-1.1.2: New USB device strings: Mfr=0, Product=0, SerialNumber=0
    Mar 16 05:40:19 duet3 kernel: [ 1986.801842] cdc_acm 1-1.1.2:1.0: ttyACM0: USB ACM device
    Mar 16 05:40:19 duet3 root: /home/pi/duet_bossac.sh started
    Mar 16 05:40:19 duet3 root: /home/pi/duet_bossac.sh started
    Mar 16 05:40:19 duet3 root: /home/pi/duet_bossac.sh started
    Mar 16 05:40:19 duet3 root: /home/pi/duet_bossac.sh started
    Mar 16 05:40:27 duet3 pi: duet_bossac.sh started
    Mar 16 05:40:28 duet3 pi: duet_bossac.sh Duet 2 Maestro
    Mar 16 05:40:45 duet3 kernel: [ 2013.512104] usb 1-1.1.2: USB disconnect, device number 17
    Mar 16 05:40:46 duet3 kernel: [ 2013.808063] usb 1-1.1.2: new full-speed USB device number 18 using dwc_otg
    Mar 16 05:40:46 duet3 kernel: [ 2013.941183] usb 1-1.1.2: New USB device found, idVendor=1d50, idProduct=60ed, bcdDevice= 1.00
    Mar 16 05:40:46 duet3 kernel: [ 2013.941197] usb 1-1.1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
    Mar 16 05:40:46 duet3 kernel: [ 2013.941207] usb 1-1.1.2: Product: Duet
    Mar 16 05:40:46 duet3 kernel: [ 2013.941216] usb 1-1.1.2: Manufacturer: Duet3D
    Mar 16 05:40:46 duet3 kernel: [ 2013.942212] cdc_acm 1-1.1.2:1.0: ttyACM0: USB ACM device
    

    A little digging it seems udev runs in a sandbox that prevent access to networks and mounting file systems; while the script does download missing firmware files and tools it fails even if everything is in place.

    Maybe i just have to parse udevadm monitor or something to get around the sandbox, but if anyone has ideas I'm all ears!



  • could i ask @gtj0 and/or @wilriker to test the following on a non-raspberry / non-raspbian setup? (with any duet attached to usb)

    #!/bin/bash
    #test for Duets with working RRF vendor 1d50 product 60e?
    for i in $(find -L  /sys/bus/usb/devices/ -maxdepth 2 -name "tty*"); do
      grep -i "v1d50p60e[c-e]" $i/../modalias &>/dev/null && echo /dev/$(ls $i) 
    done
    
    #test for SAM-BA vendor 03eb product 6124
    for i in $(find -L  /sys/bus/usb/devices/ -maxdepth 2 -name "tty*"); do
      grep -i "v03ebp6124" $i/../modalias &>/dev/null && echo /dev/$(ls $i)
    done
    


  • @bearer said in udev + bossa = failure to autorecover?:

    Of course I can

    $ uname -a
    Linux duet3-6HC 4.19.115-1-ARCH #1 SMP PREEMPT Fri Apr 24 14:53:41 UTC 2020 armv7l GNU/Linux
    
    $ ./the-bear-needs-test-helpers.bash
    /dev/ttyACM0
    


  • Cool, seems to work. Thanks!
    (asuming /dev/ttyACM0 is a duet in one form or another:P)

    (goal is to avoid trying to flash a non duet that happens to occupy ttyACM0:)

    @wilriker said in udev + bossa = failure to autorecover?:

    ./the-bear-needs-test-helpers.bash

    😁



  • @bearer said in udev + bossa = failure to autorecover?:

    (asuming /dev/ttyACM0 is a duet in one form or another:P)

    Yes, that's a Duet 3 permanently attached to RPi4 that runs DSF.

    ./the-bear-needs-test-helpers.bash

    😁

    I knew you'd like that. 😁 Also as I use fish I had to put it into a script. 😉

    BTW:

    $ lsusb
    Bus 001 Device 006: ID 1d50:60ec OpenMoko, Inc. (Duet 2 Wifi)
    Bus 001 Device 006: ID 1d50:60ed OpenMoko, Inc. (Duet 2 Maestro)
    Bus 001 Device 004: ID 1d50:60ee OpenMoko, Inc. (Duet 3)
    Bus 001 Device 008: ID 03eb:6124 Atmel Corp. at91sam SAMBA bootloader
    

    Did you hack your usb-ids or did you just add the values in parentheses yourself? I have submitted change requests to fix the names to usb-ids months ago but they do not accept them.



  • ...sounds fishy!)

    @wilriker said in udev + bossa = failure to autorecover?:

    Did you hack your usb-ids or did you just add the values in parentheses yourself?

    just added them for my own pleasure, wasn't aware it made it to the forum.



  • @bearer said in udev + bossa = failure to autorecover?:

    ...sounds fishy!)

    You as a bear should like that, don't you? 😂



  • @wilriker said in udev + bossa = failure to autorecover?:

    usb-ids

    huh poking around i find (but oddly enough not all fields for the bossa bootloader with the correct usb-id). oh well, enough to identify the board before querying bossa for the cpu type.

    echo $(cat $1/../../manufacturer): $(cat $1/../../product) $(cat $1/../../version) \($( cat $1/../../idVendor):$( cat $1/../../idProduct)\)
    Duet3D: Duet 2.00 (1d50:60ec)
    

    edit:

    seems there has been an update to usb-ids as well

    pi@raspberrypi:~ $ lsusb
    Bus 001 Device 031: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC
    Bus 001 Device 039: ID 1d50:60ec OpenMoko, Inc. Duet 3D Printer Controller
    Bus 001 Device 005: ID 0424:7800 Standard Microsystems Corp.
    Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
    Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    pi@raspberrypi:~ $
    


  • @bearer Here's my info from a Jetson Nano if you still need it...

    duet3j /~# uname -a
    Linux duet3j.f5.int 4.9.140-tegra-gtj8+ #5 SMP PREEMPT Sat Mar 14 08:58:08 MDT 2020 aarch64 aarch64 aarch64 GNU/Linux
    duet3j /~# ./testudev.sh 
    /dev/ttyACM0
    duet3j /~# 
    


  • @gtj0 awesome! just wanted to check if i could derive the tty device from usb ids across different combinations, so far so good.



  • @bearer said in udev + bossa = failure to autorecover?:

    seems there has been an update to usb-ids as well

    pi@raspberrypi:~ $ lsusb
    Bus 001 Device 039: ID 1d50:60ec OpenMoko, Inc. Duet 3D Printer Controller
    

    Not really. 1d50:60ec has been in there for a very long time already. I added 1d50:60ed for Maestro and 1d50:60ee for Duet 3. Already back in October last year. But it still didn't make it into the release.



  • @wilriker said in udev + bossa = failure to autorecover?:

    @bearer said in udev + bossa = failure to autorecover?:

    seems there has been an update to usb-ids as well

    pi@raspberrypi:~ $ lsusb
    Bus 001 Device 039: ID 1d50:60ec OpenMoko, Inc. Duet 3D Printer Controller
    

    Not really. 1d50:60ec has been in there for a very long time already. I added 1d50:60ed for Maestro and 1d50:60ee for Duet 3. Already back in October last year. But it still didn't make it into the release.

    ah, not often i have a wifi/ethernet connected, come to think of it I might initially have defered derived(?) the pid as 60ec based on maestro and duet 3. my bad.


Log in to reply