Building Anduril with Docker

It’s a program, it’s just written in Java. Works on Windows.

1 Thank

Where do I put that ? It doesn’t go inside the docker run command.

Does the image need to be built on linux ?

Ah, I just noticed you were using a locally built version. I have a version on Docker Hub that Ipush changes to, so if you run it with --pull then it will automatically get the latest updates.

docker run --pull=always --rm -v E:\light_fw\tk\anduril-trunk:/src -e DEBUG=1 siterelenby/anduril-builder <build args>

At the moment with the new repo it needs a bit better integration with the new build scripts, e.g. it wants to install the DFP even when not needed, but I have a PR open for that.

Any OS that can run Docker and is the same architecture as you intend to use the image will be able to build it. My prebuilt image is multiarch and will work on multiple different CPU architectures (currently x64, armv7, and arm64).

thanks, that worked, well it doesn’t build, like you said it wants the DFP , but no file or directory error :+1:

edit: ah it gets the DFPs with

docker run --pull=always --rm -v E:\light_fw\tk\anduril-trunk:/src -e DEBUG=1 siterelenby/anduril-builder dfp

then it works for T85/T1634 builds, but not AVRDD nor T1616

/usr/lib/gcc/avr/10.3.0/../../../../avr/bin/ld: address 0x807038 of ui/anduril/anduril.elf section `.data' is not within region `data'
/usr/lib/gcc/avr/10.3.0/../../../../avr/bin/ld: address 0x8070cf of ui/anduril/anduril.elf section `.bss' is not within region `data'
/usr/lib/gcc/avr/10.3.0/../../../../avr/bin/ld: address 0x807038 of ui/anduril/anduril.elf section `.data' is not within region `data'
/usr/lib/gcc/avr/10.3.0/../../../../avr/bin/ld: address 0x8070cf of ui/anduril/anduril.elf section `.bss' is not within region `data'
collect2: error: ld returned 1 exit status

The FLEX Asgard did that.

It kind of bombed, so they stopped trying to do bluetooth-configured flashlights. It sold poorly, was difficult to pair with a phone, and cost way too much to develop and maintain the app.

It probably didn’t help that the flashlight itself wasn’t great, and the configurable options were fairly limited.

Maybe it’ll happen someday… but that day isn’t here yet.

For now, a pogo pin USB dongle is a cheap, easy solution. Touch 3 spring-loaded pins to a driver, press a button, wait a few seconds, and it can give the flashlight a whole new personality.

1 Thank

there’s that one too : Foursevens Quark Smart QSL-X measurements (bluetooth controlled, cr123a)

But also very limited (and not maintained beyond initial release ?) I can’t help but notice the unusually large switch boot, maybe for better radio transmission.

1 Thank

Ah, I vaguely recall seeing that one at some point… I think they put the radio under the conspicuously large, raised switch on the side?

Anyway, phone OSes are a quickly moving target, and the light’s companion app might work today but there’s not much chance it’ll still work several phones down the line in 10 or 20 years. So I try to stick to standard programs that someone else is going to maintain long-term. It’s a lot of work to keep a phone app working over time, and I might get hit by a bus or something. Plus, I just don’t like phones very much. The phone ecosystem has been a corporate mess ever since Android arrived and pretty much ended all the community-based mobile OS projects.

Yeah, that makes sense - since the body tube is the battery negative, that makes it close to impossible to get a signal with an internal antenna contained within it. Having a coiled antenna under a switch boot makes sense (it might also be possible to integrate into the optics or bezel in some way, but that’s a lot harder and probably more expensive)/.

There is no need to worry about a companion app. If this functionality is really desired, a data model should be defined. If BLE is used, its as simple as creating the GATT model. Interoperability and open protocols / standards are just as important as open source.

On that note, lets hope 20 years from now we’ve figure out something better than C :stuck_out_tongue:

I think we’re talking about fundamentally different layers of the software stack. BLE/GAP/GATT are basically a link / transport / protocol layer sort of thing, and I’m talking about stuff a few levels up in the application and content layers. Like, if I want to build a web site full of things people want to use, merely defining a standard for HTTP isn’t enough. That just takes care of one low-level prerequisite before work can begin on the bulk of the project.

1 Thank
docker run --pull=always --rm -v E:\light_fw\tk\anduril-2023-12-17_20h:/src -e DEBUG=1 siterelenby/anduril-builder avr32dd20
latest: Pulling from siterelenby/anduril-builder
Digest: sha256:a1166571fefabec09c5668c35f7d1923c5ee1600268583c466f1f7cbf7bb76a4
Status: Image is up to date for siterelenby/anduril-builder:latest
+ set -e
+ set -o pipefail
+ [[ ! -d /src ]]
+ [[ 1 == \1 ]]
+ export DEBUG=1
+ DEBUG=1
+ [[ 1 == \0 ]]
+ POSITIONAL=()
+ for arg in "${@}"
+ [[ avr32dd20 == \-\-\s\h\e\l\l ]]
+ [[ avr32dd20 == \-\-\i\n\s\t\a\l\l\-\d\f\p ]]
+ [[ avr32dd20 == \-\-\d\e\b\u\g ]]
+ POSITIONAL+=("$1")
+ shift
+ set -- avr32dd20
+ [[ '' != \1 ]]
+ export SKIP_DFP_INSTALL=1
+ SKIP_DFP_INSTALL=1
+ [[ -x /src/make ]]
+ [[ '' == \1 ]]
+ exec ./make avr32dd20
bin/version-string.sh: line 34: git: command not found
bin/version-string.sh: line 50: git: command not found
===== anduril 0. : thefreeman-avr32dd20-devkit =====
avr-cpp: fatal error: cannot read spec file 'device-specs/specs-avr32dd20': No such file or directory
compilation terminated.
ERROR: build failed
===== 0 builds succeeded, 1 failed =====
FAIL: thefreeman-avr32dd20-devkit

With latest Anduril, T1616 builds now compile but not AVRDD.

Have you tried the steps/commits in this issue?

1 Thank

Sorry for the slow pace of stuff recently, had a lot going on. I’m going to work on this next.

1 Thank

We’re talking about two different things in this thread. My original Docker build environment and @wolfgirl42’s fork.

Recently I have updated my fork so that it works with the new repo format (but I haven’t released a build yet). It works only without the DFP and only for older MCUs, not the DD series! I “carefully” selected a version of avr-gcc together with the latest development version of avr-libc to create the smallest possible hex files (newer versions of avr-gcc have changed their optimization, which doesn’t work great with Anduril). The latest version of avr-libc supports tinyAVR 0/1 without the DFP (which would cause conflicts).

So if you want to build for DD, you can’t use the Docker versions right now. But the older MCUs are well supported with my new branch.

Does it work if you make dfp and then rm -rf arch/dfp/attiny ?

I’m not sure if all DFPs are incompatible with the newer libc, or only the ones which have coverage overlap / collisions.

That’s what I’m interested in though, right now there’s just my devkit in the public repo but I’m developing several AVRDD drivers, and not just personal mods but for future commercially available lights.
Right now I’m using a Vmware ubuntu VM but it’s very annoying because the copy pasting (hex) out of the VM stops working after 5min and I have to reboot it constantly, shared folders also don’t work. I tried virtualbox but the VM just crashes for whatever reason. But even if it worked properly docker is just way more convenient.
I also tried WSL, very simple to setup but then when I add/edit folder/files from Windows I get permission denied on those in WSL …

1 Thank

No, it doesn’t work. Right now it’s completely incompatible with avr-gcc 10.3 that is used in my image.

===== anduril 2023-12-03+6 : thefreeman-avr32dd20-devkit =====
/usr/lib/gcc/avr/10.3.0/../../../../avr/bin/ld: address 0x807038 of ui/anduril/anduril.elf section `.data' is not within region `data'
/usr/lib/gcc/avr/10.3.0/../../../../avr/bin/ld: address 0x8070cf of ui/anduril/anduril.elf section `.bss' is not within region `data'
/usr/lib/gcc/avr/10.3.0/../../../../avr/bin/ld: address 0x807038 of ui/anduril/anduril.elf section `.data' is not within region `data'
/usr/lib/gcc/avr/10.3.0/../../../../avr/bin/ld: address 0x8070cf of ui/anduril/anduril.elf section `.bss' is not within region `data'
collect2: error: ld returned 1 exit status
ERROR: build failed
===== anduril 2023-12-03+6 : thefreeman-boost-fwaa-mp3432-hdr-dac-rgb =====
  Device: attiny1616
  Program:   10624 bytes (64.8% Full)
  Data:        207 bytes (10.1% Full)
  # 81a8d4069b95ff4449774236b5be1e7a
  > hex/anduril.thefreeman-boost-fwaa-mp3432-hdr-dac-rgb.hex

I now tried Alpine 3.19 which uses avr-gcc 12.2 and avr-libc 2.1 and it fails as well, not only for DD, but also for all other targets.

===== anduril 2023-12-03+6 : thefreeman-avr32dd20-devkit =====
In file included from ./arch/mcu.h:12,
                 from ui/anduril/anduril.c:38:
./arch/avr32dd20.c: In function 'mcu_adc_sleep_mode':
./arch/avr32dd20.c:114:5: error: 'MCUCR' undeclared (first use in this function); did you mean 'MCU'?
  114 |     set_sleep_mode(SLEEP_MODE_STANDBY);
      |     ^~~~~~~~~~~~~~
./arch/avr32dd20.c:114:5: note: each undeclared identifier is reported only once for each function it appears in
./arch/avr32dd20.c:114:5: error: 'SLEEP_SMODE0_bm' undeclared (first use in this function)
  114 |     set_sleep_mode(SLEEP_MODE_STANDBY);
      |     ^~~~~~~~~~~~~~
In file included from /usr/avr/include/avr/io.h:99,
                 from /usr/avr/include/avr/eeprom.h:38,
                 from ./arch/mcu.h:8:
./arch/avr32dd20.c: In function 'prevent_reboot_loop':
./arch/avr32dd20.c:262:5: error: 'RAMPD' undeclared (first use in this function); did you mean 'RAMEND'?
  262 |     wdt_disable();  // from avr/wdt.h
      |     ^~~~~~~~~~~
./arch/avr32dd20.c:262:5: error: 'WDT_CTRL' undeclared (first use in this function); did you mean 'WDT_CTRLA'?
  262 |     wdt_disable();  // from avr/wdt.h
      |     ^~~~~~~~~~~
In file included from ./arch/mcu.h:13:
./arch/avr32dd20.c:262:5: error: 'WDT_ENABLE_bm' undeclared (first use in this function); did you mean 'ADC_ENABLE_bm'?
  262 |     wdt_disable();  // from avr/wdt.h
      |     ^~~~~~~~~~~
./arch/avr32dd20.c:262:5: error: 'WDT_CEN_bm' undeclared (first use in this function)
  262 |     wdt_disable();  // from avr/wdt.h
      |     ^~~~~~~~~~~
./fsm/standby.c: In function 'sleep_until_eswitch_pressed':
./fsm/standby.c:48:9: error: 'MCUCR' undeclared (first use in this function); did you mean 'MCU'?
   48 |         set_sleep_mode(SLEEP_MODE_PWR_DOWN);
      |         ^~~~~~~~~~~~~~
./fsm/standby.c:48:9: error: 'SLEEP_SMODE0_bm' undeclared (first use in this function)
   48 |         set_sleep_mode(SLEEP_MODE_PWR_DOWN);
      |         ^~~~~~~~~~~~~~
./fsm/standby.c:50:9: error: 'SE' undeclared (first use in this function); did you mean 'SP'?
   50 |         sleep_enable();
      |         ^~~~~~~~~~~~
./fsm/standby.c: In function 'idle_mode':
./fsm/standby.c:96:5: error: 'MCUCR' undeclared (first use in this function); did you mean 'MCU'?
   96 |     set_sleep_mode(SLEEP_MODE_IDLE);
      |     ^~~~~~~~~~~~~~
./fsm/standby.c:96:5: error: 'SLEEP_SMODE0_bm' undeclared (first use in this function)
   96 |     set_sleep_mode(SLEEP_MODE_IDLE);
      |     ^~~~~~~~~~~~~~
./fsm/standby.c:98:5: error: 'SE' undeclared (first use in this function); did you mean 'SP'?
   98 |     sleep_enable();
      |     ^~~~~~~~~~~~
ERROR: build failed
===== anduril 2023-12-03+6 : thefreeman-boost-fwaa-mp3432-hdr-dac-rgb =====
In file included from ./arch/mcu.h:12,
                 from ui/anduril/anduril.c:38:
./arch/attiny1616.c: In function 'mcu_adc_sleep_mode':
./arch/attiny1616.c:66:5: error: 'MCUCR' undeclared (first use in this function); did you mean 'MCU'?
   66 |     set_sleep_mode(SLEEP_MODE_STANDBY);
      |     ^~~~~~~~~~~~~~
./arch/attiny1616.c:66:5: note: each undeclared identifier is reported only once for each function it appears in
./arch/attiny1616.c:66:5: error: 'SLEEP_SMODE0_bm' undeclared (first use in this function)
   66 |     set_sleep_mode(SLEEP_MODE_STANDBY);
      |     ^~~~~~~~~~~~~~
In file included from /usr/avr/include/avr/io.h:99,
                 from /usr/avr/include/avr/eeprom.h:38,
                 from ./arch/mcu.h:8:
./arch/attiny1616.c: In function 'prevent_reboot_loop':
./arch/attiny1616.c:223:5: error: 'RAMPD' undeclared (first use in this function); did you mean 'RAMEND'?
  223 |     wdt_disable();  // from avr/wdt.h
      |     ^~~~~~~~~~~
./arch/attiny1616.c:223:5: error: 'WDT_CTRL' undeclared (first use in this function); did you mean 'WDT_CTRLA'?
  223 |     wdt_disable();  // from avr/wdt.h
      |     ^~~~~~~~~~~
In file included from ./arch/mcu.h:13:
./arch/attiny1616.c:223:5: error: 'WDT_ENABLE_bm' undeclared (first use in this function); did you mean 'ADC_ENABLE_bm'?
  223 |     wdt_disable();  // from avr/wdt.h
      |     ^~~~~~~~~~~
./arch/attiny1616.c:223:5: error: 'WDT_CEN_bm' undeclared (first use in this function)
  223 |     wdt_disable();  // from avr/wdt.h
      |     ^~~~~~~~~~~
./fsm/standby.c: In function 'sleep_until_eswitch_pressed':
./fsm/standby.c:48:9: error: 'MCUCR' undeclared (first use in this function); did you mean 'MCU'?
   48 |         set_sleep_mode(SLEEP_MODE_PWR_DOWN);
      |         ^~~~~~~~~~~~~~
./fsm/standby.c:48:9: error: 'SLEEP_SMODE0_bm' undeclared (first use in this function)
   48 |         set_sleep_mode(SLEEP_MODE_PWR_DOWN);
      |         ^~~~~~~~~~~~~~
./fsm/standby.c:50:9: error: 'SE' undeclared (first use in this function); did you mean 'SP'?
   50 |         sleep_enable();
      |         ^~~~~~~~~~~~
./fsm/standby.c: In function 'idle_mode':
./fsm/standby.c:96:5: error: 'MCUCR' undeclared (first use in this function); did you mean 'MCU'?
   96 |     set_sleep_mode(SLEEP_MODE_IDLE);
      |     ^~~~~~~~~~~~~~
./fsm/standby.c:96:5: error: 'SLEEP_SMODE0_bm' undeclared (first use in this function)
   96 |     set_sleep_mode(SLEEP_MODE_IDLE);
      |     ^~~~~~~~~~~~~~
./fsm/standby.c:98:5: error: 'SE' undeclared (first use in this function); did you mean 'SP'?
   98 |     sleep_enable();
      |     ^~~~~~~~~~~~
ERROR: build failed

What versions do you use?

I’m using debian/stable.

  • avr-libc 1:2.0.0+Atmel3.6.2-1.1
  • gcc-avr 1:5.4.0+Atmel3.6.2-1+b1

It seems like the old vs new gcc+libc has changed so much that I probably can’t support both at the same time, so I probably just have to pick a version and stick with it for now.

I’m using debian here, and github uses ubuntu LTS for CI purposes, and WSL uses the same packages, so it’s easy to use the version included in debian+ubuntu… unless, of course, there’s a meaningful benefit worth upgrading for.

Is there some reason why docker couldn’t just use some debian packages for its dependencies? I thought that was pretty common.

1 Thank

That’s ancient!

It is possible to use debian as a base image, but it is much larger. Alpine is less than 5 MB, Debian or Ubuntu at least 25-50 MB. Dependencies will add a lot, though.

AFAIK I tested all versions from 4.9 to 13.2 and decided that 10.3 was the best (hex size, optimization, supported features etc).

It can be done - I can certainly rearchitect the existing image to be based on Debian instead of Alpine, but it might be simpler just to install the matching versions on alpine too. In the absolute worst case it can be installed from source which won’t affect the performance of the Docker image by end users, just the time it takes for me to build (which is already slow anyway as I build multiarch images, but I have already automated the actual build/push).

In terms of the image size, it’s not something I often worry about - Debian’s versions are very stable, and when you update the image, it’s not going to be pulling new filesystem layers often for the base image; most likely updated layers will be for things like the entrypoint script, and occasional libc/gcc upgrades. All it really does to switch it to debian is slows down the very initial pull with my Docker hub version, while even if people are building the image themselves, if they allow the layers to be cached then it wouldn’t be much of a space penalty.

I’m going to have a go at updating my fork of the docker builder to match your package versions, because that’s definitely the easiest way, not to mention that size optimisation is generally just easier if everyone is using the same compiler versions… (Edit: Looks like Alpine doesn’t package 2.0.0 anyway, so it’s going to be from source on Alpine, but it should be entirely possible to get the same versions working there)