Advance the NuttX submodule from 1db7c59 to the fork branch tip
f07832f0 (px4_firmware_nuttx-12.12.0+), pulling in three backports:
- FlexCAN: store the TX deadline only once the frame is sent
- FlexCAN: assign MAXMB rather than OR-ing it in
- STM32F412: set SRAM1_END to 256KiB (#407)
The two FlexCAN backports are the apache/nuttx#19970 follow-ups the
branch was missing; they land the corrected i.MX RT TX-abort behavior.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Assisted-by: Claude:claude-fable-5-1
* fix(uavcan): apply UAVCAN_BITRATE on FlexCAN again
58dfff0de7 turned the SIOCSCANBITRATE path off for i.MX RT, S32K and Kinetis,
which is every board in the tree that builds SocketCAN, so UAVCAN_BITRATE
stopped doing anything at all. It was written before db6f7ec304, and the crash
it works around is that commit's bug: the driver reports bit/s on NuttX 12 and
the caller still divided by 1000, so a 1 Mbit/s board asked its controller for
1000 bit/s on every boot.
Benched on an ARK FMU-v6XRT with the gate removed: 1 Mbit/s -> 500 kbit/s ->
1 Mbit/s round-trips with both DroneCAN nodes coming back OPERAT, buses
error-active, no fault. Requesting a rate the controller cannot reach is also
survivable now -- it is reported and the configured rate is kept, where before
a negative return from here made CanDriver::init() give up and DroneCAN never
started.
The %u for a uint32_t is fixed as well; nothing compiled this branch while the
gate was in place.
* fix(work_queue): size the uavcan and TTY work queues for NuttX 12
NuttX 12.12 costs a few hundred bytes of stack on the paths that go through
the file layer, and that is more than these two defaults left spare. Measured
against the same PX4 tree on 10.3.0:
wq:uavcan 2860/3728 -> 3184/3736 (ARK FMU-v6X, two DroneCAN GNSS nodes)
wq:ttyS4 1088/1704 -> 1432/1712 (ARK FMU-v6XRT, crsf_rc)
load_mon reports wq:ttyS4 low on stack with 280 bytes left, and wq:uavcan sits
at 85 % of its own. 4096 and 2048 restore the margin the 10.3.0 figures had.
The fix is upstream as f20cf4aac3 but landed after the 12.12.0 tag, so
moving the submodule onto 12.12.0 dropped a fix the previous branch
already carried. Backport it.
Without it the group address in the IGMP header, a uint16_t[2] that decays
to a pointer, is compared against INADDR_ANY, which is always false. A
General Query then falls through to the group-specific branch, a group is
allocated for 0.0.0.0, and joined groups never have their report timers
restarted, so the querier ages out the membership and multicast delivery
to the device stops.
CONFIG_NET_IGMP is enabled on ark/fmu-v6xrt, px4/fmu-v6xrt,
nxp/mr-canhubk3, nxp/mr-tropic and nxp/tropic-community.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>
The SIOCSCANBITRATE path in CanIface::setBitRate() was gated on
SIOCGCANERRORS, which the NuttX submodule bump now defines. That turned on
a retune sequence that had never been compiled or run in this tree: it takes
the interface down, sets the bitrate and brings it back up.
Two problems surfaced on a Pixhawk v6XRT. The path did not build, because it
still used IFF_DOWN, which NuttX removed; SIOCSIFFLAGS now acts on the
IFF_UP request bit, so clearing it is what takes an interface down. Once it
built, the board booted and then crashed a few seconds later, when uavcan
started and retuned the interfaces. The driver ioctl itself is harmless and
only stores the timings, so the fault is in bringing a FlexCAN interface
down and back up at runtime, where ECC RAM initialisation runs again on a
controller that has already been started.
SIOCGCANERRORS reports whether a driver can read error counters, which says
nothing about whether it can be retuned; the two capabilities only happened
to arrive in the same commit. Gate on the capability that is actually meant,
and keep the configured rate on the FlexCAN chips. Every board in the tree
that enables SocketCAN today is FlexCAN, so this restores the behaviour
those boards already had before the bump.
Verified on px4_fmu-v6xrt: crashes with the retune path active, stable with
the configured rate kept.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>
NuttX 12.12.0 added arm_initialize_stack(), which moves thread mode onto
the process stack pointer whenever CONFIG_ARCH_INTERRUPTSTACK > 7. Every
bootloader config qualifies, so the bootloader now reaches arch_do_jump()
with CONTROL.SPSEL set, where previously it ran on the main stack.
arch_do_jump() writes the MSP and branches, but never selects it. The
application therefore starts on the bootloader's PSP while its own startup
code initialises a stack pointer the CPU is not using. Boards booted far
enough to reach NSH and start MAVLink, then hard faulted once the stale
bootloader stack was overwritten, surfacing as an assertion in Idle_Task
with no useful backtrace.
Clear CONTROL.SPSEL so control passes on the stack the application expects.
The i.MX RT bootloader performs the same jump and its configs also exceed
the interrupt stack threshold, so fix both.
Verified on CubePilot CubeOrange and Pixhawk 6C; the prebuilt bootloaders
for both are regenerated, as the shipped binaries have the defect.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>
NuttX 12.12.0 shares one statically allocated g_kthread_group between all
kernel threads, but group_leave() guards the group_release() call behind
HAVE_GROUP_MEMBERS, which is only defined when pthreads are enabled. Every
bootloader config sets CONFIG_DEFAULT_SMALL=y, so DISABLE_PTHREAD defaults
to y, and the first kernel thread to exit tears down the shared group and
calls kmm_free() on a .bss static. The bootloader died before USB
enumeration. Around 64 configs in the tree share that combination.
The submodule now carries the upstream fix, apache/nuttx f20f9ff19e.
The bump also picks up the backport that recombines the per-command CAN
ioctl Kconfig options back into NETDEV_CAN_IOCTL. Defconfigs on this branch
already reference CONFIG_NETDEV_CAN_IOCTL, which does not exist at the
previously pinned commit, so SocketCAN bitrate, filter and state ioctls
were silently disabled on ark/fmu-v6xrt, px4/fmu-v6xrt, nxp/mr-canhubk3,
nxp/tropic-community and nxp/mr-tropic.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>
The UAVCAN_BITRATE code merged via #28457 prints the driver's
arbi_bitrate (uint32_t) with %u. On the NuttX 12.12 toolchain
uint32_t is unsigned long, so -Werror=format fails every SocketCAN
board (imxrt, s32k). Use PRIu32 for the uint32_t; kbps stays %u as it
is a uint16_t promoted to int.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Main removed this file in f05739035e (#28185) when USB autostart moved
into the cdcacm_autostart driver. The NuttX upgrade rebase brought back
a NuttX 12 adaptation of it, but nothing references it in any build
file, so it is 370 lines of dead code.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
The upgrade defconfig sweep (04c00266e5) replaced
CONFIG_STDIO_BUFFER_SIZE=256 with CONFIG_STDIO_DISABLE_BUFFERING=y on
these two boards. On NuttX 12.12 that config hits an upstream
regression (62c2b1abba): task_init_stream() only assigns
fs_cookie/fs_oflags inside the buffered branch, so with unbuffered
stdio every spawned task's stdout FILE is left zeroed and bound to
fd 0. All printf output on the board is silently discarded, including
the boot log and every shell command that prints via stdio; raw fd
writes (top, dmesg) still work, which made this hard to spot.
Verified on fmu-v5x hardware (fileno(stdout)==0 in spawned tasks,
EACCES on flush over the MAVLink shell). Restoring buffered stdio
returns these boards to their pre-upgrade configuration. The upstream
fix apache/nuttx 2b1cf4238756 (post-12.12.0) should additionally be
backported to px4_firmware_nuttx-12.12.0+ to cure the class for any
unbuffered config.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
The nsh output path changed architecture in NuttX 12: nuttx-apps
95f32fd018 decoupled nshlib from FILE streams, so every output call
now runs vdprintf() with the stream engine and full VFS write chain
on the nsh task stack. On CONFIG_DEFAULT_SMALL boards the
lib_get_tempbuffer() fallback additionally compiles to alloca() on
the parse path. The hardcoded 2048 byte stack overflows, and because
NuttX 12 keeps the TLS block at the stack base the failure is a
silent mute shell rather than a hardfault.
Verified on fmu-v5x hardware: shell dead at 2048, working at 4096.
Mirrors the nshterm stack fix already on this branch (8a8f32699b).
Assisted-by: Claude:claude-fable-5
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
The mcp_gpio_dev_s / gpio_pin_dev_s struct layout changed in NuttX
12.12, so use designated initializers (.gp_pintype/.gp_ops) instead of
positional initialization.
Co-authored-by: marinauterion <224611774+marinauterion@users.noreply.github.com>
Signed-off-by: Peter van der Perk <peter.vanderperk@nxp.com>
Upgrading the NuttX apps submodule (kernel bump or switching branches then
`git submodule update`) updates tracked files only. When the new revision
removes an application directory, the autogenerated Kconfig a previous build
left inside it is untracked, so it survives `git clean -dX`. mkkconfig.sh keeps
globbing that orphaned `*/Kconfig`, whose stale `source` points at a file that
no longer exists, breaking `make olddefconfig`:
olddefconfig: apps/gpsutils/Kconfig:9: 'apps/gpsutils/minmea/Kconfig' not found
Add a `cmake -P` helper, invoked at the end of the `clean` target, that walks
the apps Kconfig graph and removes only untracked Kconfig files that source a
missing path. Tracked files and the nuttx tree (whose stale artifacts are all
gitignored and already dropped by `git clean -dX`) are never touched, so a
`make clean` before rebuilding now migrates cleanly across the upgrade.
Assisted-by: Claude:claude-opus-4.8
Signed-off-by: Peter van der Perk <peter.vanderperk@nxp.com>
Fix a protected kernel link failure caused by static initialization
of a shared uORB::Publication in AM32Settings. Which is problematic
for NuttX 12.12.0.
The NuttX 12.12 PX4 protected kernel does not provide __dso_handle.
boards: Disable MMC_IOC_CMD ioctl
NuttX default is Y, but it's not used
boards: Fix meminfo/free
boards: fix libc float setting
boards: Reduce flash usage
Using strerr short mode
Don't cache DNS entries (also saves some ram)
fix(boards): kakutef7 disable optical flow ekf2 to save flash
kakutef7 overflows with nuttx 12.12.0 also it doesn't have optical
flow drivers anyhow. Thus disable ekf2 optical flow
bootloader: update main prototype for NuttX 12.12.0
platforms/nuttx: Add wrapper for queue.h
For some reason the queue.h header was moved, add this wrapper so
posix and nuttx builds can both still use #include <queue.h>
Fix print_load to be compatible with upstream NuttX
Also Change tg_filelist -> tg_fdlist as per new NuttX
Co-authored-by: Ville Juven <ville.juven@unikie.com>
Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
* fix(navigator): preserve VTOL mode in direct mission RTL
Remove the unconditional multicopter-to-fixed-wing transition from direct mission-land RTL so the return uses the VTOL mode active when RTL starts. This allows an MC-mode vehicle to proceed through the mission landing sequence instead of becoming stuck after an unnecessary forward transition.
Add module-level and MAVSDK SITL regressions covering an airborne multicopter-mode VTOL with a planned mission landing.
Refs #27817
Refs #24323
Assisted-by: Codex:gpt-5
Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>
* fix(navigator): drop the fixed wing transition from the fast RTL modes too
The fast and the reverse mission RTL carried the same request for a
transition to fixed wing as the direct mission land RTL. The VTOL
attitude controller rejects that command during RTL, so a VTOL in
multicopter mode waited on it forever instead of flying the mission.
Remove both. A VTOL in multicopter mode now flies the mission RTL as a
multicopter, the same as direct RTL does. Reported in #24323.
Two unit tests pin the active item to a waypoint for a VTOL in
multicopter mode, and two MAVSDK cases fly it on the standard VTOL in
SIH: the mission landing and the reverse mission both stay in
multicopter mode to touchdown, within 5 m of the land item and of home.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>
---------
Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>
Commit af3cfaea25 introduced a small semantic change in _actuator_sp:
- prior to that commit it was always the output of the allocation
algorithm, i.e. if 0 thrust was allocated the _actuator_sp was 0, and
the NaN needed to stop some motors only entered the picture when
populating the actuator_motors message in publish_actuator_controls
- after that commit, we change _actuator_sp itself to be NaN when the
corresponding motor should be stopped
This breaks consumers of _actuator_sp that expect there to be a finite,
physical thrust in _actuator_sp. One such consumer is
publish_control_allocator_status, which produces NaN if the _actuator_sp
is NaN and is thus currently useless.
Fix: Convert NaNs back to zero in getAllocatedControl so all consumers
of that work as before.
* fix(dshot): emit the DShot rate that was asked for on STM32
io_timer_set_dshot_burst_mode() wrote the tick count into ARR, but an STM32 timer
period is ARR + 1 ticks, and the prescaler divided by that same tick count. Every
bit came out one tick long, so the output ran at 21/20 of the requested rate and
the 7/14 compare counts -- betaflight's, where the period really is 20 ticks --
landed on 21 and gave 33.3 %/66.7 % instead of the protocol's 37.5 %/75 %.
Measured on an ARK FMU-v6X (240 MHz timer, BDShot300) with a logic analyser:
bit period 3.500 us (+5.00 %) -> 3.333 us (-0.01 %)
bit 0 high 33.2 % -> 37.3 %
bit 1 high 66.5 % -> 74.9 %
Subtracting one from ARR alone is not enough. A tick count fixed at 20 (19, 18)
cannot divide every timer clock by every rate: 200 MHz at DShot600 would go from
+0.80 % to -4.00 % and 90 MHz from -2.00 % to -6.67 %. Choose the tick count and
the prescaler together instead, scoring the emitted rate first and the two high
times second, and derive the compare counts from the tick count that wins. That
is exact on 84, 90, 96, 108, 168, 180, 216 and 240 MHz at all three rates, and
within 0.25 % on 160 MHz and 0.80 % on 200 MHz, where no integer pair is exact.
The search only depends on the timer clock and the rate, so io_timer.c caches its
answer per timer and recomputes only if the rate changes, which is once. That
leaves the transmit path with no arithmetic at all where it previously ran a
modulo loop and two divisions on every burst and every capture.
The capture prescaler comes out of the same struct and no longer follows the
transmit tick count. It only sets the resolution of a free-running counter, so it
aims for a fixed 20 ticks per response bit, which is what keeps a one-to-three bit
run inside the interval window convert_edge_intervals_to_bitstream() accepts.
* fix(dshot): search up to 40 ticks per bit and keep the search in 32 bits
333 cycles per bit (200 MHz at DShot600, 100 MHz at DShot300) is 9 x 37, so a
ceiling of 32 ticks left those clocks at 0.79 % when 37 x 9 lands within 0.10 %.
The wider range also moves the clocks that were settling on a 39-40 % bit-0
duty onto 37.5 %.
The rounded prescaler keeps ticks * prescaler * rate within half a bit of the
timer clock, so the 64-bit compare bought nothing. The timing cache now starts
on a rate nobody asks for, so its zero-rate guard is reachable instead of
returning a zeroed struct.
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
---------
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* fix(uploader): shorten the wait for a bootloader after reboot
Reboot-to-bootloader is immediate, so this wait only has to cover USB
re-enumeration, not the reboot. Five seconds of it meant a port that was
never going to answer held up every other port on the list, and it could
outlast the window it was trying to catch: a board sits in its bootloader
for BOOTLOADER_DELAY, 3s on some boards and 5s on most, before it jumps to
the application.
With an FMU-v6C and a Black Magic probe attached, a pass over the probe's
two CDC nodes drops from 14.75s to 5.45s, and a running application is in
its bootloader 3.52s after the uploader starts.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>
* fix(uploader): report ports by their /dev/serial/by-id name
A ttyACM number is handed out in plug order and says nothing about which
device it belongs to, which is awkward as soon as there is more than one
CDC device on the bus -- "Attempting reboot on /dev/ttyACM0" gives no hint
that it is a debug probe rather than the board.
Resolve each detected port back to its by-id symlink when one exists, so
every message names the device. This also collapses a duplicate: a board
is matched both by a by-id pattern and by the /dev/ttyACM* catch-all, so
it was being probed twice per pass. With an FMU-v6C and a Black Magic
probe attached, detection goes from four entries with two naming the same
board to three, each identifying itself.
Linux only; elsewhere, and for ports with no symlink, paths are unchanged.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>
---------
Signed-off-by: Julian Oes <julian@oes.ch>
The 24LC64T on I2C3_BASE is wired to LPI2C6 (X1_8/10). Manifest MTD talks I2C, so it has to run after those pins are I2C and VDD_5V_PERIPH is on, or the chip does not attach and netman cannot save.
The driver only hard-resets when SPI6_nRESET_EXTERNAL1 / SPI6_RESET are defined. v6xrt named the pin GPIO_SPI6_nRESET_EXTERNAL1, so SCH16T never left software reset.
NUTTX_GIT_TAG_STR was computed by taking the highest nuttx-X.Y.Z tag in
the NuttX submodule, without checking that the tag is an ancestor of the
checkout. The PX4/NuttX fork's tags were last synced in Oct 2022 and
topped out at nuttx-11.0.0, so every build has reported NuttX 11.0.0
regardless of the actual kernel (ver all, AUTOPILOT_VERSION.os_sw_version,
the ULog sys_os_ver_release field). With the nuttx-12.12.0 tag now pushed
for the NuttX 12.12 upgrade (#26215), fresh clones of main would flip to
misreporting 12.12.0 while still running the 10.3-era kernel.
Resolve the version from the fork branch name recorded in .gitmodules
(px4_firmware_nuttx-X.Y.Z+) instead, which is updated atomically with
every kernel change, and fall back to git describe for checkouts that do
not follow the fork convention. Output format is unchanged: vX.Y.Z, as
consumed by version_tag_to_number().
Assisted-by: Claude:claude-fable-5
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
The FC-side GlobalTimeSyncMaster needs the TX timestamp of its previous
sync frame, delivered by a loopback receive; without it every broadcast
carries previous_transmission_timestamp_usec 0 and slaves never adjust.
The SocketCAN platform had no loopback at all, never filled the UTC
timestamp of received frames, and clock::adjustUtc() was a stub, so the
UTC clock was wall time rather than the HRT base the sensor bridges
expect. Time sync was therefore a silent no-op on every i.MX RT, Kinetis
and S32K board.
Frames sent with CanIOFlagLoopback are now handed back from receive()
stamped at the moment they entered a hardware mailbox: NuttX has no TX
echo, so this stands in for the true transmission time with a bias of at
most one frame time when the sync frame wins arbitration. All received
frames get a UTC timestamp derived from SO_TIMESTAMP, and SystemClock is
one shared instance whose first adjustUtc() is absolute, so the existing
hrt_absolute_time() seed makes bus time equal HRT as on STM32.
* fix(uavcan): report FlexCAN bus state and error counters on SocketCAN
The SocketCAN platform driver returned 0 from getErrorCount(),
getRxQueueOverflowCount() and isInBusOffState(), so a controller sitting
error-passive or bus-off was invisible from `uavcan status` and the
can_interface_status topic on every i.MX RT board. Read them through
NuttX's SIOCGCANERRORS instead, and print fault confinement, TEC/REC and
RX overruns per interface. Builds without the ioctl keep the old zeros.
* fix(uavcan): apply UAVCAN_BITRATE on SocketCAN
CanDriver::init() ignored its bitrate argument, so the controller stayed
at the Kconfig rate and a bus configured for anything but 1 Mbit/s never
came up. Program the nominal rate through SIOCSCANBITRATE when it differs
from what the driver reports, keeping the data-phase settings untouched.
The driver applies the timing at the next ifup, so the interface is taken
down around the request. Older PX4/NuttX restarted a running controller
from inside the ioctl instead, which on FlexCAN with ECC RAM
initialisation is a bus fault; against that NuttX the rate is left as
configured with a warning.
* fix(boards): switch SocketCAN defconfigs to NETDEV_CAN_IOCTL
PX4/NuttX#401 merges the per-command CAN ioctl options into a single
NETDEV_CAN_IOCTL, so the old BITRATE/FILTER/ERROR names no longer
exist there and would be silently dropped, disabling the whole CAN
ioctl block. Requires the NuttX gitlink to include PX4/NuttX#401;
until that bump the option is dropped against the old tree and the
bitrate/error ioctls are inert at runtime (the code builds either
way). mr-canhubk3 is included so its bitrate ioctl survives the bump.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* chore(nuttx): bump NuttX to the px4_firmware_nuttx-10.3.0+ tip
Picks up PX4/NuttX#401 so SIOCGCANERRORS, SIOCSCANBITRATE-requires-ifdown
and NETDEV_CAN_IOCTL are in the tree the SocketCAN changes need. Also
includes PX4/NuttX#399 (STM32F412VG/CG chip selections), which landed
between main's gitlink and #401.
Assisted-by: Grok:grok-4.6
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
---------
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* fix(ci): attach FMU bootloader .bin to GitHub releases
Releases only shipped `_bootloader.px4`, the USB uploader envelope. SWD recovery needs the raw `.bin` at 0x08000000.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* fix(ci): do not attach unused bootloader .px4
USB flashing would write it into the application slot. SWD uses the raw .bin.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* fix(ci): omit bootloader SBOMs from GitHub releases
GitHub Releases glob artifacts/**/*.sbom.spdx.json. Bootloader metadata dirs are not a recovery artifact.
*_bootloader_* variants (e.g. bootloader_secureboot) stay omitted: those images are baked with in-tree test keys.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* docs(bootloader): point SWD recovery at the release .bin
Match the cannode pre-built blurb. The .px4 envelope is not the SWD image.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* docs(bootloader): scope release .bin to SWD programmers
gdb load needs ELF program headers. The release image is a raw .bin for ST-Link / CubeProgrammer / OpenOCD, and only in-tree *_bootloader targets are attached.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
---------
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
Picks up PX4/NuttX#402, where memmem() missed a needle that ends the
haystack, and a configurable STM32 Ethernet TX watchdog timeout whose
default is the 60 s the drivers hard-coded before.
The default label is multicopter-only and already occupies 96.8% of the
1792 KB application slot, so the fixed-wing stack cannot be added
alongside it. This variant swaps the two, mirroring ark_fpv_fw, and
lands at 95.3%.
PX4 only bundles the 2xxx/3xxx airframes when FW_RATE_CONTROL is
enabled, so the plane entries added to the board airframe whitelist are
inert for every other label.