Po-util: The Ultimate Local Particle Experience for Linux and macOS

Continuing the discussion from Toolchain Installer / Helper for Linux and OSX (I can't edit the post for some reason...)

Github All Releases Slack Status Donate Bitcoin GitHub issues GitHub stars Build Status Circle CI

Particle Offline Utility:

A handy script for installing and using the Particle Toolchain on Ubuntu-based distros and OSX.
This script downloads and installs: dfu-util, nodejs, gcc-arm-embedded, particle-cli, and the Particle Firmware source code.

# Quick Install / Update

curl po-util.com/download | bash

Copy and paste this into your terminal.

See 2.0 instructions in a post below.

Info

po-util Copyright (GPL) 2016  Nathan Robinson
This program comes with ABSOLUTELY NO WARRANTY.
Read more at http://bit.ly/po-util

Usage: po DEVICE_TYPE COMMAND DEVICE_NAME
       po DFU_COMMAND
       po install [full_install_path]

Commands:
  install      Download all of the tools needed for development.
               Requires sudo. You can optionally install to an
               alternate location by specifying [full_install_path].
               Ex.:
                   po install ~/particle

               By default, Firmware is installed in ~/github.

  build        Compile code in "firmware" subdirectory
  flash        Compile code and flash to device using dfu-util
  clean        Refresh all code
  init         Initialize a new po-util project
  patch        Apply system firmware patch to change baud rate
  update       Download latest firmware source code from Particle
  upgrade      Upgrade system firmware on device
  ota          Upload code Over The Air using particle-cli
  serial       Monitor a device's serial output (Close with CRTL-A +D)

DFU Commands:
  dfu         Quickly flash pre-compiled code
  dfu-open    Put device into DFU mode
  dfu-close   Get device out of DFU mode

Tips

The three most useful commands are build, flash and clean. Build compiles code in a "firmware" subdirectory and saves it as a .bin file in a "bin" subdirectory. Flash does the same, but uploads the compiled .bin to your device using dfu-util. Clean refreshes the Particle firmware source code.

A po-util project must be arranged like so:

po-util_project/
  â”” firmware/
    â”” main.cpp
    â”” lib.cpp
    â”” lib.h

Since po-util compiles .cpp and not .ino files, #include "application.h" must be present in your main.cpp file.

A blank main.cpp would look like:

#include "application.h"

void setup()
{

}

void loop()
{

}

One of the features of po-util is that it changes the baud rate to trigger dfu mode on Particle devices from 14400 to 19200. The reason for this is because Linux can not easily use 14400 as a baud rate. To enable this feature, connect your device and put it into DFU mode, and type:

po DEVICE_TYPE patch

# Replace DEVICE_TYPE with either "photon" or "electron"

Your computer will then recompile both parts of the Particle system firmware and flash each part to your device using dfu-util.

Why I created this script

I created this script because Particle does not currently have a script for easily installing the Particle Toolchain and depedencies on Linux and OSX. I created this script in order to help out other Particle users and to improve my bash scripting skills. It would be my dream come true if Particle added this script to its resources or gave it a shout out in its documentation. If that happened, I would feel very proud of myself for making a meaningful contribution.

Read more at po-util.com

15 Likes

nice! this is great stuff. definitely helpful for the local dev / offline use case.
thanks for sharing.

1 Like

UPDATE:

This script can now also patch the system firmware to change the DFU baud rate speed from 14400 to 19200, meaning that triggering DFU mode on a Photon or Electron without pressing the SETUP and RESET buttons can now be done on Linux.

The flash command now puts the device into DFU and automatically compiles and uploads new firmware to it, allowing quicker development.

See 2.0 Installation instructions in a post below.

UPDATE: Build Status

I have moved this script over from a gist to a repository.

I have also made it super easy to install this utility:

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

See 2.0 Installation instructions in a post below.

Additional functions have also been added, including OTA flashing and manual DFU control.
Find out more in the repository, https://github.com/nrobinson2000/po-util

2 Likes

###I have made many improvements to my script recently and I have created a website for it using Github Pages. Read more at http://bit.ly/po-util

See 2.0 Installation instructions in a post below.

I have updated my script so that it lets the user choose the install path.

See 2.0 Installation instructions in a post below.

1 Like

I have updated po-util a lot recently. Most importantly, I have:

I have started a wiki for po-util. https://github.com/nrobinson2000/po-util/wiki

Github All Releases

Github Releases (by Release)

Release 2.0!

ENHANCEMENTS:

  • Added cool ascii art logo
  • Updated to Nodejs v6.x
  • Updated to gcc-arm-embedded v4.9
  • Build and flash can now take a third argument to compile a specific firmware directory
  • Improved update command
  • General bug fixes

Info:

Po-util is a handy script for installing and using the Particle Toolchain on Ubuntu-based distros and OSX. It downloads and installs: dfu-util, nodejs, gcc-arm-embedded, particle-cli, and the Particle Firmware source code. Information about po-util can be found on my website. https://po-util.com

Manual Install / Update

If you already have po-util installed, run po update and po install to update and re-install.

You can get a copy of po-util at the Github repository. The easiest way is to download po-util.sh from this link and run:

./po-util.sh install

To setup po-util and install dependencies.

Alternatively, you can clone po-util with git:

git clone https://github.com/nrobinson2000/po-util
cd po-util
./po-util.sh install

When installing po-util, an alias is added to your .bashrc that allows you to run po from anywhere to use po-util.

# Quick Install / Update

curl po-util.com/download | bash

Copy and paste this into your terminal.

Note: We download everything from well known locations and Github. While we believe this is a reasonable method as a quick start, it’s always a good idea to know what is going on under the hood.

Please use the Manual Install/Update instructions in the post above.

Hi guys!

Can you please join my Thunderclap Campaign to help people discover po-util? https://www.thunderclap.it/projects/44489-help-support-po-util

Particle Offline Utility, pronounced po-util, is a script for installing and using the Particle Toolchain on Ubuntu-based distros and OSX.

Po-util makes it easy for developers to download the Particle Toolchain and install the required dependencies to quickly begin creating projects using the Particle Platform.

Po-util features a responsive experience, giving developers the tools they need for seamless local development. Po-util provides understandable commands for simplifying complex tasks like properly compiling and flashing firmware.

Po-util downloads and installs: dfu-util, nodejs, gcc-arm-embedded, particle-cli, and the Particle Firmware source code.

Nathan Robinson
@nrobinson2000

Po-util now supports building directories relative and un-relative to the current working directory. Support for other Linux Distributions, (Fedora, Arch) is being developed.

Hello nrobinson,

Po-util is a very handy script–thanks much for sharing. How exactly does po-util trigger DFU mode on a Photon/P1 without pressing the SETUP and RESET buttons? Can po-util trigger DFU on a Photon/P1 straight from the factory?

-shm45

1 Like

That's a feature described here
https://docs.particle.io/reference/firmware/photon/#begin-

@shm45
To make po-util use the default Particle baud rate you need to edit the ~/.po configuration file and change the DFUBAUDRATE=19200 line to DFUBAUDRATE=14400
This is explained in the Triggering DFU mode on your Device(s) section of po-util.com.

po-util uses the stty command to change the baud rate of a device. When a Particle device detects a specific baud rate (14400 is Particle’s default), it goes into DFU mode.

1 Like

Yes, this is supported on all Particle devices out of the box after editing the po-util config file.

Excellent–thank you ScruffR and nrobinson.

Cheers,
shm45

2 Likes

I have added support am working on adding support for RHEL and Arch Linux distributions. I have also added a po config command which lets users easily select what branch of Paticle firmware they want to use and what baud rated they want to use to put devices into DFU mode.

I need users on distros like Fedora and Arch to test if po-util installs properly on their system. https://github.com/nrobinson2000/po-util/issues/24

Edit:
I am testing po-util in an Arch virtual machine and it is not working. I’m getting a similar error as this thread. Even if I completely delete arm-none-eabi, it still looks for it, saying:

/bin/sh: 1: /home/nrobinson/bin/gcc-arm-embedded/gcc-arm-none-eabi-4_9-2015q3/bin/arm-none-eabi-gcc: not found

This is driving me crazy. I have checked po-util for anything that is causing this error, but I have not found anything. Note: Arch did not have a desktop environment, and I am beginning to think that no DE correlates to po-util not working.

I am now trying po-util on Fedora in another virtual machine.

Edit:
On Fedora 24 I get this error:

Building firmware for Production Photon, platform ID: 6, product ID: 6
/bin/sh: /usr/local/bin/arm-none-eabi-gcc: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
/home/nrobinson/github/firmware/build/arm-tools.mk:43: *** "ARM gcc version 4.8.4 or later required, but found ".  Stop.
build/recurse.mk:11: recipe for target 'communication' failed
make: *** [communication] Error 2

A bit different, but still not working. Basically, it’s having the same problem as Arch, where it “can not find” the executables, even though they exist, and so do their links. They are visible to which, and found by which.

Does anyone have any input on this problem?

Some thoughts:

Check the permissions for the file that you are trying to execute. I presume you install as root and then run another another username.

Check /var/log/secure for permissions violations or other errors.

Do you have SELinux enabled? Check using sestatus. That can upset a few things.

Using strace might help if you can narrow the problem down to a single command otherwise you will get too much diagnostic trace. For example, if I call zcat I get this:

[tim@c7va ~]$ strace zcat
execve("/usr/bin/zcat", ["zcat"], [/* 31 vars */]) = 0

If I then remove permissions to zcat I get this:

[tim@c7va ~]$ strace zcat
execve("/usr/bin/zcat", ["zcat"], [/* 31 vars */]) = -1 EACCES (Permission denied)
write(2, "strace: exec: Permission denied\n", 32strace: exec: Permission denied
) = 32
exit_group(1)                           = ?
+++ exited with 1 +++

The other thing that I can think of is that environments can be slightly different depending on how a shell is invoked. Google “bash_profile or .bashrc” and see whether that might be affecting you.

1 Like

@timx

On the Fedora virtual machine I get this when running sestatus:

[nrobinson@localhost po-util]$ sestatus 
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          error (Permission denied)
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      30

When I use which and strace, I get:

[nrobinson@localhost po-util]$ which arm-none-eabi-gcc
/usr/local/bin/arm-none-eabi-gcc
[nrobinson@localhost po-util]$ strace arm-none-eabi-gcc
execve("/usr/local/bin/arm-none-eabi-gcc", ["arm-none-eabi-gcc"], [/* 49 vars */]) = -1 ENOENT (No such file or directory)
write(2, "strace: exec: No such file or di"..., 40strace: exec: No such file or directory
) = 40
exit_group(1)                           = ?
+++ exited with 1 +++

I'm going to see what happens when I follow this guide.

Edit:
No change after changing SELinux to permissive mode.

Edit:
I get similar results on Arch for strace:

execve("/usr/local/bin/arm-none-eabi-gcc", ["arm-none-eabi-gcc"], [/* 19 vars */]) = -1 ENOENT (No such file or directory)
write(2, "strace: exec: No such file or di"..., 40strace: exec: No such file or directory
) = 40
exit_group(1)                           = ?
+++ exited with 1 +++

Edit:
This problem has also happened in the past on Ubuntu (14.04) on Travis CI.

However, Circle CI (Also Ubuntu 14.04) does not have any problems.

Neither does my Ubuntu VPS (16.04), which is able to use po-util just fine.

I Googled and found an article that says you can get the not found message if one of the dependent libraries isn’t available. I guess that attempting to execute the compiler causes a cascade load of other modules and it’s one of those that wasn’t found.

Ref: https://ubuntuforums.org/showthread.php?t=2183052

I therefore tried the following on one of my Centos 7 VMs (64 bit):

Downloaded https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q2-update/+download/gcc-arm-none-eabi-5_4-2016q2-20160622-linux.tar.bz2
unzipped it

[root@c7va bin]# ./arm-none-eabi-gcc
-bash: ./arm-none-eabi-gcc: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory

[root@c7va bin]# strace ./arm-none-eabi-gcc
execve("./arm-none-eabi-gcc", ["./arm-none-eabi-gcc"], [/* 24 vars */]) = -1 ENOENT (No such file or directory)
write(2, "strace: exec: No such file or di"..., 40strace: exec: No such file or directory
) = 40
exit_group(1)                           = ?
+++ exited with 1 +++

[root@c7va bin]# file arm-none-eabi-gcc
arm-none-eabi-gcc: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, stripped

yum install glibc.i686

[root@c7va bin]# ./arm-none-eabi-gcc
arm-none-eabi-gcc: fatal error: no input files
compilation terminated.

So I was able pretty much reproduce the error that you get. That last command suggests that the code can now be loaded and it simply needs an input file. The reason why I installed glibc.i686 was because it was one of the packages that I used to install when I was building my own Docker containers for compiling the Particle firmware. That was 18 months ago so I’ve forgotten why I had to do it but this is probably why :slight_smile:

1 Like