Skip to content

BLE branches cannot build in CI: HCI driver is absent from the pinned zephyr revision #16

Description

@tyeth

Both board builds fail to link on the BLE branches. Distinct from #11 (which is the tests / zephyr / native_sim job) — this is ports (zephyr-cp) / board (...).

Run 34264719937 on zephyr-picow-ble, both boards identically:

ld.bfd: libsubsys__bluetooth__host.a(hci_core.c.obj):(.data.bt_dev+0x16c):
        undefined reference to `__device_dts_ord_8…'
collect2: error: ld returned 1 exit status

Cause

The devicetree side resolves correctly — CI's own log shows:

DEBUG:zephyr2cp:cyw43_bt_hci: okay
DEBUG:zephyr2cp: infineon,cyw43-bt-hci -> infineon_cyw43_bt_hci -> bluetooth/hci

So the zephyr,bt-hci chosen node exists, CONFIG_BT switches itself on, and Zephyr's BT host links against the HCI device ordinal. But the driver that defines that device does not exist in the Zephyr tree CI checks out: ports/zephyr-cp/zephyr-config/west.yml on these branches still pins adafruit/zephyr @ 62e7a3764, which predates drivers/bluetooth/hci/hci_cyw43_shared_bus.c. DT node present, DEVICE_DT_INST_DEFINE absent, hence the undefined ordinal at link time.

This is a dependency, not a regression: the affected branches are correct on their own terms and build fine locally against the fork branch that carries the driver.

Blocking relationship

Not affected

#13 (RP2040 ranges boot fix) is off main, touches only three .overlay files, and involves no Bluetooth, so it should build clean. Note it currently has no Build CI run at all, which looks like a separate triggering oddity rather than a failure.

Options

  1. Leave zephyr-cp: enable BLE on the Raspberry Pi Pico 2 W #4/zephyr-cp: enable BLE on the Raspberry Pi Pico W #14 red until the zephyr PR merges, with this issue as the explanation.
  2. Bump the manifest to the fork revision on the PR branches — but that is exactly the CI-only override CI-only west.yml override on ci/pico2w-ble-assets must not be merged, and depends on an unreviewed branch #12 says must not merge, so it would contaminate the reviewable PRs.
  3. Split the DT node + CONFIG_BT enablement out of zephyr-cp: enable BLE on the Raspberry Pi Pico 2 W #4/zephyr-cp: enable BLE on the Raspberry Pi Pico W #14 so the rest can be reviewed and merged green ahead of the driver.

Tracked under #15.

Activity

  1. tyeth commented on Sep 8, 2026

    @tyeth
    OwnerAuthor

    Follow-up on the "#13 has no Build CI run" note — now confirmed, and unexplained.

    Querying every run for that commit returns exactly one:

    head sha: a49dfc507ef17d88b0a9896c86803f206e115098
    runs for sha: 1
      34264437693  pre-commit  event=push  status=completed/success
    

    So no pull_request-triggered Build CI run was ever created — not queued, not skipped, not cancelled. Closing and reopening the PR did not produce one either.

    That is not a base-branch rule: #5 is also based on main and did get a Build CI run (34253341423, success). Build CI triggers on push for main/*.x only, plus pull_request with no paths filter, so #13 should qualify exactly as #5 did.

    I have not established why. Candidates not ruled out: an Actions usage/queue limit on the fork silently dropping the run, or something about a branch created by cherry-pick onto main. Flagging rather than guessing.

    Practical consequence: #13 is currently unvalidated by CI. It is the most independently mergeable change in this stack (three .overlay files, no Bluetooth, verified on hardware), so it would be good to see it green. A trivial push to the branch should fire synchronize and create the run; I have not done that to avoid adding noise commits to a review branch.

  2. tyeth commented on Sep 8, 2026

    @tyeth
    OwnerAuthor

    Root cause of the missing Build CI run on #13 — established, and it was neither an Actions limit nor the cherry-pick.

    At the time, #13 reported mergeable=CONFLICTING / mergeStateStatus=DIRTY (checked via the GitHub API). The branch was cut from a main that still had the flat ports/zephyr-cp/boards/rpi_pico*.overlay files; main had meanwhile moved them to boards/<vendor>/<board>/board.overlay (d0f27bfc97) and edited the very same partition nodes (ffd62e1c59, 78b217d250, fdb56f994b). GitHub could not compute the refs/pull/13/merge commit, and it does not create pull_request-triggered workflow runs for a PR it cannot merge — not queued, not skipped, simply never created. That matches what the run query showed (zero runs for the event), and why close/reopen changed nothing.

    pre-commit kept appearing because it fires on push, which needs no merge commit. #5 got its Build CI run because debug.conf did not conflict, so its merge ref could be built.

    Consequence for this issue's body: the "#13 should build clean" note is moot — #13 is closed as redundant (the ranges; fix is on main, see #6). The BLE branches have since been rebased onto main 121489fe70; they now inherit main's west.yml pin (adafruit/zephyr @ 52dc937c7c rather than 62e7a3764), which still predates hci_cyw43_shared_bus.c, so the link failure described above is unchanged and remains blocked on tyeth/zephyr#1.

    🤖 Generated with Claude Code

  3. tyeth commented on Sep 8, 2026

    @tyeth
    OwnerAuthor

    The CI path is now verified green for both boards — without merging tyeth/zephyr#1.

    ci/pico2w-ble-assets has been rebased onto the top of the BLE stack (94bfd47b5f, now 0 commits behind main, was 229). The three stale pre-rebase BLE commits were dropped in favour of the rebased stack, and the single CI-only commit was replayed on top, so the override branch now exercises the current boards/<vendor>/<board>/board.overlay files rather than the deleted flat ones.

    Pico 2 W Pico W
    run 34287512362 ✅ 34287514167 ✅
    FLASH 1,146,092 B = 73.25% 1,181,368 B = 75.51%
    RAM 229,144 B = 43.03% 228,044 B = 84.36%
    artifact raspberrypi_rpi_pico2_w_zephyr-en_US-latest, 8,852,015 B raspberrypi_rpi_pico_w_zephyr-en_US-latest, 8,912,451 B

    Both expire 2026-12-07. This is the first CI build of the Pico W BLE firmware at all — previously only the Pico 2 W had an asset. CI matched the local builds to within 4 bytes of flash and exactly on RAM.

    The Pico W run also reports BOOT_FLASH 256 B 100.00%, which is a positive CI check that .boot2 is linked — the RP2040 unbootable-image failure mode from #6, now confirmed rather than inferred from a UF2 hexdump.

    What this changes, and what it does not

    The override needs tyeth/zephyr#1 to exist, not to merge: a project declared in zephyr-config/west.yml overrides the same-named project imported from Zephyr's own manifest. So CI verification of the driver is fully decoupled from upstream review, and option 2 above stays off the table (#12).

    Unchanged: #4 and #14 themselves still cannot link, for exactly the reason in the body. Option 1 remains the plan — they stay red, with this issue and the override runs as the evidence they are correct on their own terms.

    Corrections to the body

    • The pinned revision is no longer 62e7a3764. After the rebase the branches inherit main's pin, adafruit/zephyr @ 52dc937c7c, which also predates hci_cyw43_shared_bus.c — the cause is unchanged, only the revision named is.
    • The "Not affected" section is moot: zephyr-cp: restore "ranges" on RP2040 partitions, fixing unbootable images #13 is closed (the ranges; fix landed upstream as ffd62e1c59), and its missing Build CI run was root-caused above to the stale base, not a triggering oddity.

    Gotcha for anyone re-running this

    gh workflow run build-board-custom.yml --ref ci/pico2w-ble-assets is not sufficient on a fork. --ref only selects which workflow file runs; the checkout step is git checkout -b fork-branch "fork/$BRANCH" from the branch input, which defaults to main. Dispatched without it, the job silently builds main and produces a plausible-looking artifact with no Bluetooth in it. Always pass both:

    gh workflow run build-board-custom.yml --ref ci/pico2w-ble-assets \
      -f board=raspberrypi_rpi_pico2_w_zephyr -f branch=ci/pico2w-ble-assets
    

    🤖 Generated with Claude Code

  4. tyeth commented on Sep 8, 2026

    @tyeth
    OwnerAuthor

    Binaries from the two runs above, parked on a prerelease so they outlive the artifacts (which expire 2026-12-07) and need no Actions access: v-zephyr-cp-ble-ci-20260909.

    • Pico 2 W — UF2 (2,292,224 B) · ELF
    • Pico W — UF2 (2,363,392 B) · ELF

    Relevant to this issue specifically: these are what the west.yml override produces, i.e. what #4/#14 would build once the manifest names a revision containing hci_cyw43_shared_bus.c. They are not built from #4/#14 as they stand, which still fail to link.

    Details and caveats in #15 (comment 5593160524) — flashing either board reformats CIRCUITPY.

    🤖 Generated with Claude Code


    Edit: the release tag was renamed to v-zephyr-cp-ble-ci-20260909 and the links above updated. A tag not starting with v is picked up by py/version.py (git describe --first-parent --match "[!v]*"), which broke every pristine build and both CI asset builds on ci/pico2w-ble-assets with "Cannot determine version". The v- prefix makes it invisible to that matcher.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions