Search | Sailfish OS | Running | PineTime | All Posts

Compiling a Sensor Watch firmware on FreeBSD

April 16, 2024 — Nico Cartron

Context

As I wrote in that article, I am "testing" a bunch of watches, and started with the Sensor Watch / Casio F-91W, a board swap for the aforementioned famous watch.

You can also use the very good online Sensor Watch Builder, but hey, why not trying to make it work on FreeBSD? :-)

First steps

The excellent documentation gives clear instructions on how to build the firmware.

The page only lists Linux and MacOS, and not FreeBSD - but that's not gonna scare me.

Here are the simple steps you have to follow:

  • clone the repo,
  • cd Sensor-Watch/movement/make
  • make COLOR=RED (since I'm using a Sensor Watch Lite board).

I initially tried with make but got plenty of errors.

The rest of the article will explain what I did to make it work - but before that, for folks in a hurry, I have a TL;DR version just below.

Making it work! - The TL;DR version

pkg install arm-none-eabi-binutils arm-none-eabi-newlib gcc-arm-embedded
export PATH=$PATH:/usr/local/gcc-arm-embedded/bin
gmake COLOR=RED

Making it work! - The complete version, with pain and sweat

The documentation specifies that you need to install the GNU ARM Embedded Toolchain.

A quick search in the FreeBSD packages yields a promising result:

# pkg search embedded
gcc-arm-embedded-10.3.20210921 Complete gcc-based toolcahin for embedded ARM development

Using gmake worked better, but after a while I got:

gmake: arm-none-eabi-gcc: No such file or directory
gmake: *** [../../rules.mk:50: build/tusb.o] Error 127

Again, a pkg search eabi yielded a few results, including one that looked spot on:

arm-none-eabi-gcc-11.3.0_2     GNU Compiler Collection for bare metal arm cross-development

After yet another pkg install and running gmake again, I still encountered issues:

/usr/local/bin/arm-none-eabi-ld: cannot find crt0.o: No such file or directory
collect2: error: ld returned 1 exit status
gmake: *** [../../rules.mk:27: build/watch.elf] Error 1

OK, let's look for arm-none in the FreeBSD packages:

# pkg search arm-none
arm-none-eabi-binutils-2.40_4,1 GNU binary tools
arm-none-eabi-gcc-11.3.0_2     GNU Compiler Collection for bare metal arm cross-development
arm-none-eabi-newlib-2.4.0_2   Newlib distribution for arm-none-eabi targets

Right, the last one (arm-none-eabi-newlib-2.4.0_2) looks interesting, let's install it and run gmake again - here's the result:

git submodule update --init
LD build/watch.elf
Memory region         Used Size  Region Size  %age Used
          bootloader:          0 GB         8 KB      0.00%
                 rom:      121556 B       240 KB     49.46%
              eeprom:          0 GB         8 KB      0.00%
                 ram:       12576 B        32 KB     38.38%
OBJCOPY build/watch.hex
OBJCOPY build/watch.bin
UF2CONV build/watch.uf2
gmake: python3: No such file or directory
gmake: *** [../../rules.mk:39: build/watch.uf2] Error 127

Alright, it goes a bit further, but still an error about python3.

Installing python with pkg install python fixed it:

# pkg install python
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 2 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
python: 3.9_3,2
python3: 3_3

Number of packages to be installed: 2

and finally:

√ make % gmake COLOR=RED
git submodule update --init
UF2CONV build/watch.uf2
Converting to uf2, output size: 247808, start address: 0x2000
Wrote 247808 bytes to build/watch.uf2
size:
   text    data     bss     dec     hex filename
   121556  2296   10280  134132   20bf4 build/watch.elf
   121556  2296   10280  134132   20bf4 (TOTALS)

Youhou!! we have a build/watch.uf2

and indeed, when checking the build directory, we can see a watch.uf2 file, which is the one we'll need to upload to the watch:

-rw-r--r--  1 nc user 247808 Feb 12 17:33 watch.uf2

Epilog

While trying to compile again with fewers watchfaces, I got the following:

/usr/local/lib/gcc/arm-none-eabi/11.3.0/include-fixed/stdio.h:432:9: error: unknown type name '__ssize_t'
/usr/local/lib/gcc/arm-none-eabi/11.3.0/include-fixed/stdio.h:433:9: error: unknown type name '__ssize_t'
/usr/local/lib/gcc/arm-none-eabi/11.3.0/include-fixed/stdio.h:449:25: error: unknown type name '__off_t'; did you mean '_off_t'?
/usr/local/lib/gcc/arm-none-eabi/11.3.0/include-fixed/stdio.h:453:1: error: unknown type name '__off_t'; did you mean '_off_t'?
/usr/local/lib/gcc/arm-none-eabi/11.3.0/include-fixed/stdio.h:453:21: error: unknown type name '__off_t'; did you mean '_off_t'?
/usr/local/lib/gcc/arm-none-eabi/11.3.0/include-fixed/stdio.h:457:46: error: unknown type name '__off_t'; did you mean '_off_t'?
/usr/local/lib/gcc/arm-none-eabi/11.3.0/include-fixed/stdio.h:461:33: error: unknown type name '__off_t'; did you mean '_off_t'?
/usr/local/lib/gcc/arm-none-eabi/11.3.0/include-fixed/stdio.h:545:25: error: expected ';' before 'typedef'
gmake: *** [../../rules.mk:50: build/tusb.o] Error 1

Damned! What went wrong? It worked before.

Well, it turns out that installing the arm-none-eabi-newlib package was not a good idea, as it conflicts with the arm-none-eabi-binutils.

When looking a bit closer at the first error message I got:

% gmake COLOR=RED 
git submodule update --init
CC build/tusb.o
gmake: arm-none-eabi-gcc: No such file or directory
gmake: *** [../../rules.mk:50: build/tusb.o] Error 127

It struck me that the arm-none-eabi-gcc was actually the missing binary!

A search on the FreeBSD forums gave me that interesting result: this binary had actually been installed by the gcc-arm-embedded package, and could be found in /usr/local/gcc-arm-embedded/bin:

√ ~ % ls -l /usr/local/gcc-arm-embedded/bin/ |grep gcc
-rwxr-xr-x  2 root wheel  1615624 Jan  8 03:21 arm-none-eabi-gcc
-rwxr-xr-x  2 root wheel  1615624 Jan  8 03:21 arm-none-eabi-gcc-10.3.1
-rwxr-xr-x  1 root wheel    29136 Jan  8 03:21 arm-none-eabi-gcc-ar
-rwxr-xr-x  1 root wheel    29136 Jan  8 03:21 arm-none-eabi-gcc-nm
-rwxr-xr-x  1 root wheel    29136 Jan  8 03:21 arm-none-eabi-gcc-ranlib

I added this directory to my path with this command:

export PATH=$PATH:/usr/local/gcc-arm-embedded/bin

then compiled again, and this time it succeeded!

So to recap, here are the packages needed:

# pkg version |grep -i arm
arm-none-eabi-binutils-2.40_4,1    >
gcc-arm-embedded-10.3.20210921     =

Customizing the watchfaces

By default, compiling Sensor Watch will give the default watchfaces.
As detailed in that page, if you want your own set of watchfaces, all you have to do is:

  1. edit the movement/movement_config.h file,
  2. modify the below array with your liking,
  3. run gmake COLOR=red again.

Here's the default array:

const watch_face_t watch_faces[] = {
    simple_clock_face,
    world_clock_face,
    sunrise_sunset_face,
    moon_phase_face,
    stopwatch_face,
    preferences_face,
    set_time_face,
    thermistor_readout_face,
    voltage_face
};

Here's the resulting watch.uf2 file:

-rw-r--r--  1 nc user 217600 Feb 13 14:13 watch.uf2

and if I only select the simple clock face:

const watch_face_t watch_faces[] = {
    simple_clock_face
};

Of course, the watch.uf2 file will be smaller:

-rw-r--r--  1 nc user 170496 Feb 13 14:23 watch.uf2

Tags: FreeBSD


I don't have any commenting system, but email me (nicolas at ncartron dot org) your comments!
If you like my work, you can buy me a coffee!