I recently discovered jazda, which is a hackable bike computer. Well, actually, right now, it is a smart watch with a half-finished bare-bones core app that wants to become a biking app when it is grown up. You need to compile your own rust-based operating system and flash it using an STLink 2.0 pluged into a SWD breakout board dev kit, plugged into the charging cable, attached to the watch. So what can possibly go wrong? 🙂
The devkit arrived quickly, containing the Bangle2js watch, a STLink 2.0 and the breakout board to connect the STLINK to the charging cable and a few stickers. Do NOT expect a manual yet!
In this post, I am going to describe the steps to setup jazda, based on my first experiences.
Install required things
- You will need
tockloader
to flash things to the watch.
I just installed it as regular user (python setup.py install --user
), ideally one could do this in a container or python venv to avoid polluting your local python modules. The upstream tockloader did not know the board name(?!), TODO: check out if/why upstream tockloader is not sufficient. - The example app later requires
python3-z3
, so install that from your package manager or via pip, if you want to run the test app. - You need
openocd
(which is used by tockloader) to do the actual flashing. The version in Debian testing/bookworm (0.11.0-1(?)) was sufficiently up to date. - You need to install the
stlink-tools
(otherwise, openocd produced aError: libusb_open() failed with LIBUSB_ERROR_ACCESS
error message). The reason is that this adds udev rules that permit any user in the plugdev group to do flashing to the STLINK without being root.
Note: restarting udev and re-plugging the stlink is required to make use of the added udev rules. - Install rust (which is required for all the compiling)
I first installed rust-all and rust-src on my Debian testing, in order to avoid the rustup script. (I just don’t like to cheat on my package manager).
After failing with the rust version provided by the Debian package manager, I uninstalled everything and locally installed rust via rustup for my user. (sorry package manager, I hope you’ll forgive me!) just
is a command line something (similar to make, but less powerful). Debian did not have a package ready, butcargo install just
provides it to you. You need it to build the jazda Core app.
Compile and flash the tock kernel
- Compile the tock kernel
The board setup is described in https://framagit.org/jazda/tock/-/tree/flashil/boards/nordic/sma_q3 - Just run
make
in the directoryboards/nordic/sma_q3
. - This resulted in the file:
a907d5297a74f999bb98f860151a1dea87c021b3cf9fa247f7fae299615b88c2 target/thumbv7em-none-eabi/release/sma_q3.bin - I then issued
make flash
with the STLINK plugged in and the running watch attached.
This flashed the filesma_q3.bin
to the watch. and output a success info on the terminal.
There was NO change of the display in the watch which continued to show the time, and the display simply froze dead. (not even 30s button pressed will cause any reset or anything) You might be forgiven if you believe that you just bricked your brand new watch. Your watch is running the tock kernel, but does not do anything useful yet. The next step is to compile and run an example app, so see if things worked out.
Compile/run an example test app
So, next I compiled the libtock-rs sample app (note: you need python3-z3 installed for it, see requirements section above!). The jazda wiki explains how:
cargo install elf2tab EXAMPLE=leds make nrf52840
If that succeeds, flash it and run it:
tockloader install ./target/thumbv7em-none-eabi/release/examples/leds.tab --board sma_q3 --openocd tockloader listen --board sma_q3 --openocd --rtt
This made the watch blink and vibrate until I killed the app with ctrl-c.
Once you are sure, it worked great, you need to uninstall the example app, or you’ll end up with a full memory and you’ll be unable to install anything else.
use tockloader list
–board sma_q3 –openocd and tockloader uninstall
–board sma_q3 –openocd to remove apps.
Compile and run the real jazda “core” app
Now on to the real application. You need two repositories checked out in the same directory: Core, yanp. libtock-rs (yes, the one from the sample app above will be automatically checked out and build as part of the Core build process, so it is not needed to keep around anymore).
Before compiling succeeded, I needed to add the thumbv7em-none-eabi
target to rust. That went like this:
rustup target add thumbv7em-none-eabi
If you have just
installed (see requirements section), it will be as easy as entering the “core” repository and issueing
just build_bin map
If all this goes well, you’ll end up with an app as: target/thumbv7em-none-eabi/release/map
.tab
To install the app, connect your watch, and try to install the app
tockloader install target/thumbv7em-none-eabi/release/map.tab --board sma_q3 --openocd
and starting the app worked by issueing:
just listen
which is just a shorthand for:
tockloader listen --board sma_q3 --openocd --rtt
once, it runs, just unplug the charger to keep the maps app running. To “stop” the app, connect it again, tockloader listen
and interrupt with ctrl-c.
This will display a map. There is also an app called “speed”, it is compiled and installed the same way as the map app.