What you can change¶
Every setting this project reads, in one place, with its default. They are all
environment variables. Nearly all begin UNOQ_; the few that do not are for
the firmware build and have their own section.
Every one has a working default — a board that sets none of them is a
correctly configured board.
The prefixed names on this page are checked against the code: tools/check.sh
docs fails if one exists in a script and not here, or here and not in a
script. The unprefixed ones are not covered by that check.
How a setting reaches the thing that reads it¶
There are three routes, and which one applies depends on what runs the script.
| The script is run by | Set the variable in | Then |
|---|---|---|
a systemd unit (the USB link, the LEDs, the uplink fallback) |
/etc/default/unoq-usb |
sudo systemctl restart <unit> |
you, at a prompt (bootstrap.sh, anything under provision/) |
the command line: UNOQ_ |
— |
you, through sudo |
after sudo, not before: sudo UNOQ_ |
— |
The third row catches people. sudo starts the command with a clean
environment, so UNOQ_X=1 sudo bash script.sh sets the variable for sudo and
not for the script. bootstrap.sh is the exception: it calls sudo -E for its
own steps, so variables set in front of bootstrap.sh do reach them.
/etc/default/unoq-usb is the one file on the board a person is expected to
edit. provision/95-usb-gadget.sh writes it once, with the common settings
commented out, and never overwrites it afterwards. Four units read it:
unoq-usb-gadget, unoq-usb-bind, unoq-uplink-fallback and unoq-leds.
That script does not run with --no-usb-gadget or --minimal, so a board set
up without the USB link has no such file. unoq-leds is installed on every board and reads
the same file, so to change an LED setting there, create it:
The file is plain NAME=value lines. A file you create this way is left alone
if you add the USB extra later.
To see what a running unit actually has:
systemctl show unoq-leds -p Environment -p EnvironmentFiles
sudo cat /proc/"$(systemctl show unoq-leds -p MainPID --value)"/environ | tr '\0' '\n' | grep UNOQ_
The USB link¶
Read by the scripts under usb/. Set these in /etc/default/unoq-usb. What
they control is explained in usb.md.
| Variable | Default | What it does |
|---|---|---|
UNOQ_ |
1 |
0 stops the USB link ever installing a default route. The board is then reachable from the computer it is plugged into and has no route to the internet through it. |
UNOQ_ |
700 |
The metric of that default route. It loses to wifi (600) and ethernet (100) on purpose: a real uplink keeps winning. |
UNOQ_ |
1 |
Once a packet has actually reached the internet through the cable, promote the USB route ahead of wifi. 0 leaves it as the last resort always. |
UNOQ_ |
550 |
The metric used for that promotion: below wifi's 600, above ethernet's 100. |
UNOQ_ |
1.1.1.1 8.8.8.8 |
The addresses pinged through the cable to decide whether the internet answers there. |
UNOQ_ |
1 |
When the computer routes to the internet but will not lease an address, claim one in the numbering its sharing feature uses, and keep it only if it routes. 0 settles for link-local instead. |
UNOQ_ |
/etc/unoq/usb-profiles.conf |
Where those known numberings are listed. |
UNOQ_ |
1.1.1.1 8.8.8.8 |
Nameservers used when the computer on the other end does not answer DNS. Set it empty to refuse the fallback. |
UNOQ_ |
example.com |
The name looked up to decide whether a nameserver is answering. |
UNOQ_ |
5 |
Seconds to wait for that lookup. |
UNOQ_ |
ncm |
rndis for a computer with no NCM driver. Only takes effect when the gadget is built; an existing one must be purged first, and gadget-up.sh says so. |
UNOQ_ |
br-usb |
The name of the bridge the USB network functions join. |
The guards¶
These exist so that a board with wifi off cannot lock you out. Read usb.md before changing any of them.
| Variable | Default | What it does |
|---|---|---|
UNOQ_ |
3 |
How many boots may try to bind the gadget without one being confirmed good, before the bind guard refuses to try again. |
UNOQ_ |
1 |
When the guard gives up, turn wifi back on so there is still a way in. 0 leaves the radio alone. |
UNOQ_ |
1 |
If wifi was turned off and the USB link has produced no route to the internet by the deadline, turn wifi back on. 0 lets the board sit with no uplink. |
UNOQ_ |
240 |
That deadline, in seconds from unoq-uplink-fallback starting at boot. |
UNOQ_ |
15 |
Seconds between probes while waiting for it. |
UNOQ_ |
1.1.1.1 8.8.8.8 |
The addresses that count as "the internet" for that decision. |
UNOQ_ |
1.1.1.1 |
The address usb/wifi.sh off pings through the cable first. No answer is a warning, not a refusal. |
UNOQ_ |
20 |
Seconds between 95-usb-gadget.sh finishing and the USB port changing hands, when the step was started from adb shell and so cannot do it itself. See usb.md. |
The status LEDs¶
Read by status/leds.sh, which runs as unoq-leds.service. Set these in
/etc/default/unoq-usb, creating it if it is not there (see
above), then
sudo systemctl restart unoq-leds.
| Variable | Default | What it does |
|---|---|---|
UNOQ_ |
5 |
Seconds between passes. Every pass re-reads everything, so this is also how stale a light can be. |
UNOQ_ |
12 |
The reachability ping runs on every Nth pass: once a minute at the defaults. |
UNOQ_ |
1.1.1.1 |
The address that ping goes to. |
UNOQ_ |
1000 |
The slow blink (degraded, or in progress): milliseconds lit, then the same again dark. Once every two seconds at the default. |
UNOQ_ |
250 |
The fast blink (needs a human), likewise. Twice a second at the default; do not go below about 170, which is three flashes a second and the ceiling for anything that flashes. Keep it well apart from the slow one: the two rhythms are how the states are told apart without color. |
These two set LED 1 and LED 2 only. LED 3 and LED 4 blink at the same rates
from the firmware, where they are constants in
mcu/app/include/status_leds.h; change one side and the other no longer
matches it.
The drive and the web server¶
| Variable | Default | Read by | What it does |
|---|---|---|---|
UNOQ_ |
8080 |
provision/75-learning-web.sh |
The port that script checks after starting the server. It does not move the server: the port is named in ExecStart in python/unoq-learn.service. Change both, or neither. |
UNOQ_ |
2600 |
share/build-image.sh |
Size of the FAT32 image that is both the USB drive and the web root. |
UNOQ_ |
~/unoq-share.img |
provision/95, provision/75, share/build-image.sh, usb/gadget-up.sh |
Where that image lives. If you move it, set this everywhere it is read, including /etc/default/unoq-usb. |
UNOQ_ |
/srv/unoq-share |
provision/75, share/build-image.sh |
Where the image is mounted for the web server. |
UNOQ_ |
/var/lib/unoq-share |
share/build-image.sh |
The staging directory the image is built from. |
Provisioning switches¶
Set on the command line, for one run of bootstrap.sh or of the script named.
| Variable | Default | Read by | What it does |
|---|---|---|---|
UNOQ_ |
0 |
provision/10-optimize-board.sh |
1 skips the apt-get upgrade a restored board needs. Services restart as their packages upgrade, so expect a blip on the link you are connected over when it runs. |
UNOQ_ |
1 |
provision/10-optimize-board.sh |
0 leaves Bluetooth and udisks2 enabled. They are disabled by default, not removed. |
UNOQ_ |
0 |
provision/10-optimize-board.sh |
1 keeps the ~2 GB of Arduino container images. |
UNOQ_ |
0 |
provision/90-cleanup.sh |
1 keeps apt's downloaded packages and the uv and pip caches, which the last step of a run otherwise clears. Worth it on a slow connection. |
UNOQ_ |
~/uno-q-backup |
provision/10, provision/55 |
Where the stock MCU firmware and the list of removed container images are saved. |
UNOQ_ |
0 |
bootstrap.sh, provision/55-purge-arduino.sh |
1 lets the firmware be flashed, and the purge go ahead, with no copy of the stock firmware saved. Only for a board whose copy is already gone. |
UNOQ_ |
0 |
provision/user/25-zephyr-sdk.sh |
1 lets an SDK release chosen with ZEPHYR_ be unpacked, and its setup.sh run, when the release publishes no checksum for it. It says so when it does. It has no effect on the pinned release, which is never unpacked unverified, and it never excuses a checksum that is published and does not match. |
UNOQ_ |
whoever ran sudo |
provision/lib.sh |
The account that owns the checkout and is written into the units. |
UNOQ_ |
<checkout>/.venv |
provision/user/35-python-venv.sh, tools/ |
The Python environment. |
UNOQ_ |
30 |
provision/80-watchdog.sh |
Whole seconds without a ping from systemd before the hardware watchdog resets the board. Refused below 10: a timeout that short resets a board that is merely busy, and does it again after every reboot. Only read with --with-watchdog. |
The MCU control lines¶
Read by mcu/link-up.sh. These are facts about the circuit board, not
preferences; they are variables so the script can be tested without one. See
hardware.md.
| Variable | Default | What it is |
|---|---|---|
UNOQ_ |
/dev/gpiochip1 |
The GPIO controller both lines are on. |
UNOQ_ |
37 |
The MCU's BOOT0. |
UNOQ_ |
70 |
The line that enables the serial link. |
Settings without the prefix¶
Read by the firmware build, flash and toolchain scripts. They have no UNOQ_
prefix because most are names Zephyr's own tools already use. Set them on the
command line for one run, for example BUILD_DIR=/tmp/b zbuild.
| Variable | Default | Read by | What it does |
|---|---|---|---|
ZEPHYR_ |
~/zephyrproject |
provision/user/30-zephyr-workspace.sh, mcu/zbuild.sh, mcu/flash.sh, mcu/flash-all.sh, mcu/ztest.sh |
Where the west workspace is. If you move it, set this for every one of those scripts. |
ZEPHYR_ |
~/zephyr-sdk-1.0.1 |
mcu/zbuild.sh, mcu/flash-all.sh, mcu/ztest.sh |
Where the Zephyr SDK (the cross-compiler) is installed. |
ZEPHYR_ |
1.0.1 |
provision/user/25-zephyr-sdk.sh |
Which SDK release that step downloads, into ~/zephyr-sdk-<version>. A pin: see the note below. |
ZEPHYR_ |
v4.4.2 |
provision/user/30-zephyr-workspace.sh |
Which Zephyr release the workspace is created at. A pin: see the note below. |
BOARD |
arduino_ |
mcu/zbuild.sh, mcu/flash-all.sh |
The Zephyr board to build for. env.sh exports the same value. |
BUILD_ |
~/zephyrproject/build for this project's app, build-<name> for any other |
mcu/zbuild.sh |
The build directory. With it set, zflash no longer finds the image by itself: name it, as zbuild prints at the end. |
IMAGE_ |
0.0.0+<seconds since 1970> |
mcu/zbuild.sh |
The version signed into the image, which fota.images() reports. The default makes every build distinguishable. |
MCUBOOT_ |
~/zephyrproject/build-mcuboot |
mcu/flash-all.sh |
Where the bootloader is built. |
OCD_ |
/opt/openocd |
mcu/flash.sh, provision/55-purge-arduino.sh |
The OpenOCD installation used for SWD. Point it at a rebuilt copy to try one without replacing the original. |
STOCK_ |
~/uno-q-backup/zephyr-arduino_ |
mcu/restore-arduino-firmware.sh |
The Arduino firmware image that script flashes. |
OPENOCD_ |
da3920b0a52d |
tools/build-openocd.sh |
The upstream OpenOCD commit that script builds. |
OPENOCD_ |
/opt/openocd-rebuilt |
tools/build-openocd.sh |
Where that build is installed. |
ZEPHYR_VERSION and ZEPHYR_SDK_VERSION can be overridden, and should not
be changed casually. The Zephyr version is also written in west.yml for CI,
and a gate fails when the two disagree; the SDK path is written into
env.sh and the ZEPHYR_SDK defaults above. Changing either is an upgrade
with its own checklist: see mcu.md.
Not for changing¶
These exist so the test suite can point a script at a temporary directory or a fake program instead of the real board. Nothing on a running system sets them, and setting one will mostly make a script look in the wrong place.
| Variable | Default | What it stands in for |
|---|---|---|
UNOQ_ |
/var/lib/unoq |
Where the bind guard's counter and the last DHCP lease are kept. |
UNOQ_ |
/run/unoq-usb-dhcp.state |
The current lease, as usb/status.sh reports it. |
UNOQ_ |
/run/unoq-usb-profile.state |
The address claimed when no lease was offered. |
UNOQ_ |
/etc/resolv.conf |
The resolver configuration usb-dhcp.sh edits. |
UNOQ_ |
/sys/kernel/config/usb_ |
The gadget's configfs directory. |
UNOQ_ |
/sys/class/leds |
The kernel's LED directory. |
UNOQ_ |
usb/bind-guard.sh |
The guard leds.sh asks whether it has given up. |
UNOQ_ |
/usr/local/lib/unoq |
Where provisioning puts root's copies of the scripts, and where usb/status.sh looks for them. Everything in that directory that is not one of them is deleted, so it is never pointed at a directory with anything else in it. |
UNOQ_ |
unset | Set by bootstrap.sh for the steps it runs, so that a warning about the board as a whole is printed once at the end instead of after every step. |
UNOQ_ |
/usr/sbin/avahi-autoipd |
The link-local address daemon. |
UNOQ_ |
nslookup |
The resolver probe. |
UNOQ_ |
/etc/systemd/system.conf.d |
Where 80-watchdog.sh writes its systemd drop-in. |
UNOQ_ |
/sys/class/watchdog |
Where 80-watchdog.sh looks for a watchdog device. |
UNOQ_ |
/etc/fstab |
The mount table 85-esp-permissions.sh edits. Its backup is written beside it. |
UNOQ_ |
.venv/bin/codespell |
The spelling checker tools/check-spelling.sh runs. |
UNOQ_, UNOQ_, UNOQ_, UNOQ_, UNOQ_ |
the files in the repository | The five files tools/check-constraints.sh compares, so its tests can hand it copies with one thing wrong. |
UNOQ_ |
/run |
Where usb-net-up.sh keeps the DHCP client's pid file, and where provisioning notes that packages changed in this boot. |
UNOQ_ |
/sys/class/net |
Where usb-net-up.sh looks for the gadget's network interfaces. |
UNOQ_ |
/proc |
Where usb-net-up.sh and gadget-down.sh check that a pid file names the daemon it claims to. |
UNOQ_ |
/var/cache/apt |
Where 90-cleanup.sh looks for downloaded packages. |
UNOQ_ |
/sys/class/udc |
Where usb/handover.sh looks for a USB controller to bind to. |
UNOQ_ |
/etc/ssh |
Where provisioning looks for SSH host keys before switching sshd on. |
UNOQ_ |
/proc/self/cgroup |
What a provisioning step reads to find out whether it was started from adb shell. |
Development only¶
Read by the scripts under tools/, on whatever machine runs the quality gates.
| Variable | Default | What it does |
|---|---|---|
UNOQ_ |
~/.local/bin |
Where install-dev-tools.sh puts shellcheck, shfmt and bats. |
UNOQ_ |
share/learn |
The built site the diagram checks inspect. |
UNOQ_ |
8099 |
The port check-diagrams.sh serves the site on while it renders. |
UNOQ_ |
the first Chromium or Chrome on PATH |
The browser check-diagrams.sh drives. CI sets it to the pinned one that install-diagram-browser.sh fetches. |
UNOQ_ |
8000 |
How long each page is given to draw its diagrams before it is reported as not drawn. |
UNOQ_ |
45 |
Seconds the browser is given to start, and to answer on any one page, before it is killed and the gate fails. |
Set for you¶
UNOQ_PROJECT is exported by env.sh: the path of the
checkout, worked out from where env.sh itself is. The zbuild, zflash,
mcucon and hpy shortcuts are built from it. Read it; do not set it.
UNOQ_OWNER_HOME and UNOQ_CHECKOUT are not environment variables at all.
They are two lines in /usr/local/lib/unoq/env, which provisioning writes
beside root's copies of the scripts: the
home directory of the account the board belongs to, and the checkout the
copies were made from. usb/gadget-up.sh reads the first to find the drive
image, and usb/status.sh reads the second. The file is rewritten by every
step that installs a root unit, so an edit to it does not last. To move the
drive image, set UNOQ_SHARE_IMG.
What is not a variable¶
Some numbers that look tunable are fixed, and on purpose:
- The serial port and its speed (
/dev/ttyHS1, 115200) are constants inpython/unoq/mcu.py. The firmware has to agree, so changing one end here would only break the link. - The LED matrix geometry lives in
mcu/app/include/app_proto.hand is pinned to the Python copy by a test. - The Zephyr and SDK versions are pins more than settings. The variables that hold them are listed under Settings without the prefix, and changing them is an upgrade with its own checklist: see mcu.md.