Monday, October 1, 2018

How to dockerize Cypress FX3 Linux USB programmer

I've been working with the Domesday Duplicator lately and one of the pieces of hardware that they use is the FX3 board from Cypress.  Domesday documentation focuses on linux tools so I booted into my Ubuntu and got the FX3 USB programmer working.  It wasn't that easy, though.  For example, I had to modify the source code to fix a build error.  Installation seems to be one-way, meaning there is no uninstall (which seems somewhat rude).  It would've been cool to run this in a VM so that when I was done, I could just shut the VM down.  That is kind of a huge pain, though.  A better option is Docker!  The problem is, the software's license likely prohibits it being distributed as a docker container, so one must create one from scratch.  Fortunately, after some experimenting, I got it all working.

The benefits to running this program from a docker container are:
  • The docker image, once created, will likely work on many more platforms than what the native installation option offers.
  • You don't have to install all of the qt4 dev packages on your native OS.
  • Uninstalling is simple and clear. (no weird files leftover in weird places)
So here are my instructions to Docker-ize Cypress's FX3 linux USB programmer:
  • Be using some linux flavor (I am on Ubuntu 18.04).
  • Install Docker and configure it so that normal users can access it (beyond scope of this blog post).
  • Create a file called /etc/udev/rules.d/88-cyusb.rules which has the following contents: (this file is necessary to get flash programming mode to work)

    # Cypress USB driver for FX2 and FX3 (C) Cypress Semiconductor Corporation / ATR-LABS
    # Rules written by V. Radhakrishnan ( rk@atr-labs.com )
    # Cypress USB vendor ID = 0x04b4
    KERNEL=="*", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ACTION=="add", ATTR{idVendor}=="04b4", MODE="666", TAG="cyusb_dev", RUN+="/usr/local/bin/cy_renumerate.sh A"
    KERNEL=="*", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ACTION=="remove", TAG=="cyusb_dev", RUN+="/usr/local/bin/cy_renumerate.sh R"
  • Run "sudo udevadm control --reload-rules" to make the change take effect
  • Create a script called /usr/local/bin/cy_renumerate.sh that contains this:

    #!/bin/bash
    pid=`pidof cyusb_linux`

    if [ "$pid" ]; then
        kill -s SIGUSR1 $pid
    fi
  • Type "chmod a+x /usr/local/bin/cy_renumerate.sh" so the script can be executed
  • Download the Cypress FX3 linux SDK (try here or search for "cypress fx3 linux sdk")
  • Extract the archive and locate the file called cyusb_linux_1.0.5.tar.gz .
  • Create a new subdirectory and copy cyusb_linux_1.0.5.tar.gz into it.
  • Inside this subdirectory, create a file called Dockerfile and paste this into it:

    # this is known to work on 18.04, may not work on later versions
    FROM ubuntu:18.04

    ARG DEBIAN_FRONTEND=noninteractive
    ARG CYUSB=cyusb_linux_1.0.5.tar.gz

    COPY $CYUSB /$CYUSB

    RUN apt-get update && \
            apt-get -y -qq install apt-utils && \
        apt-get -y -qq install sudo qt4-default \
            less make g++ dialog libusb-1.0-0-dev \
            xterm

    RUN export uid=1000 gid=1000 && \
        mkdir -p /home/developer && \
        echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd && \
        echo "developer:x:${uid}:" >> /etc/group && \
        echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
        chmod 0440 /etc/sudoers.d/developer && \
        chown ${uid}:${gid} -R /home/developer

    # switch to user so it installs from the user's context
    USER developer
    ENV HOME /home/developer

    # needed so cypress app can program itself to go into flash mode
    ENV CYUSB_ROOT /home/developer/cyusb_linux_1.0.5

    # build/install
    RUN    sudo chmod a+r /$CYUSB && \
            tar xvfz /$CYUSB -C /home/developer && \
            sudo rm -f /$CYUSB && \
            cd $HOME && \
            cd cyusb* && \
            make && \
            sed -i 's/errno/_errno/g' gui_src/main.cpp && \
            sudo ./install.sh

    # put /usr/local/lib in the lib search path so running 'cyusb_linux' from anywhere works
    RUN     sudo sh -c "echo '/usr/local/lib' >> /etc/ld.so.conf.d/cyusb.conf" && \
            sudo ldconfig

    # launches in xterm so we can see log messages
    CMD xterm -e "cyusb_linux"
  • From within this subdirectory (which contains the .tar.gz file and Dockerfile), run this command:
    "docker build -t cyusb ."
  • It will take ~5 mins depending on the speed of your system.  When it finishes, your Docker image will be generatedand will be called "cyusb".
  • Plug in your FX3 to a USB port.
  • Make sure that the FX3 image that you want to program to the FX3 is stored somewhere under your home directory.
  • Run the following command:
    docker run --rm \
        -v $HOME:/shared:ro \
        -v /tmp/.X11-unix:/tmp/.X11-unix \
        -e DISPLAY \
        -e "QT_X11_NO_MITSHM=1" \
        --privileged \
        -v /dev/bus/usb:/dev/bus/usb \
        cyusb
  • If all goes well, the cyusb app will launch inside of the container.  Your host's home folder will be accessible as /shared in the root.  Follow the instructions from DdD to complete the programming.
  • When you exit the program, the container will automatically delete/uninstall itself.
The only thing left on your host system once you exit the container will be the file you put inside of /etc/udev/rules.d, the little script in /usr/local/bin, and the docker image that you created.  Uninstalling is as easy as removing those two files and deleting the docker image.  Simply re-execute the "docker run" command above in the future to reprogram.

Neat, eh?

No comments:

Post a Comment