Skip to content

Fix the manual install instructions for HALPI2 - #43

Merged
mairas merged 3 commits into
mainfrom
fix/ubuntu-install-sync
Aug 11, 2026
Merged

Fix the manual install instructions for HALPI2#43
mairas merged 3 commits into
mainfrom
fix/ubuntu-install-sync

Conversation

@mairas

@mairas mairas commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

The manual install page had drifted from what a HALPI2 actually needs. Following it top to bottom left the reader with a halpid that could not reach the power management controller, and several commands that fail as written.

What was wrong

dtparam=i2c_arm=on was missing. Raspberry Pi OS ships it commented out (pi-gen/stage1/00-boot-files/files/config.txt), so there was no /dev/i2c-1 and the daemon had nothing to talk to. The page only loaded the i2c-dev module.

Four more defects on the same page:

  • sudo echo i2c-dev > /etc/modules-load.d/i2c-dev.conf runs the redirect in the unprivileged shell and fails. Now echo … | sudo tee ….
  • The manual flash path /usr/share/halpi2/firmware/ does not exist. The package installs to /usr/share/halpi2-firmware/.
  • dtparam=sd=off was missing. Without it shutdown can stall long enough to drain the supercapacitors before the controller powers the board down.
  • The NMEA 0183 baud rate read 34800.

What review turned up

Reviewing the fix against the shipped packages and the hardware sources found three more, all of which changed the result:

The package does not flash automatically. Its postinst probes the board with halpi get firmware_version, and halpi has no get subcommand — halpi/src/main.rs defines status, version, config, shutdown, usb, flash. The probe fails on every machine, the postinst takes its fallback branch, and apt still reports success. Filed as hatlabs/HALPI2-firmware#40. The page now documents manual flashing as the real path, including the power-off the controller needs — a reboot does not apply new firmware.

The reboot was in the wrong place. dtparam=i2c_arm=on only takes effect after a restart, and the page's only reboot was the last line of the optional CAN section. A reader with no NMEA 2000 network went straight from editing config.txt to installing halpid, against a bus that did not exist. There is now an explicit reboot and an ls /dev/i2c-1 check before the daemon is installed.

dtparam=sd=off needs a precondition. The Raspberry Pi kernel maps that parameter to sdio1 on CM5 (bcm2712-rpi-cm5.dtsi), and the overlays README states it disables "the SD card (or eMMC on non-lite SKU of CM4/5)". HALPI2 carries a fitted microSD socket — J26 is (dnp no) in SDCard.kicad_sch and appears in assembly-panel/bom.csv. On NVMe, which is the standard configuration, the line is needed. On microSD or eMMC it makes the device unbootable. The line stays in the block, with a danger admonition before it so the reader checks their boot device first.

Smaller corrections from the same pass: the flash example no longer pins version 3.3.1 (it used a glob that cannot match bootloader_*.bin, which the package's own head -n 1 selection does resolve to — noted on hatlabs/HALPI2-firmware#40); halpi flash gets the sudo the 0660 root:halpid socket requires; and the page notes that halpi needs a new login session before the halpid group applies.

Translations

All nine carry the same changes. Code fences stay English per the translate-page skill, so all 16 blocks are byte-identical across the ten files. Each language keeps its own register — Spanish and Italian impersonal with infinitive steps, German Sie, French vouvoiement with U+00A0 before colons — and the cross-reference into user-guide/software.md uses each language's real translated anchor. kernel module is now recorded in eight glossaries, as the skill requires for a newly introduced term.

Verification

mkdocs build --strict, check_typography.py (9 languages, 0 faults), check_anchors.py (9880 links resolve), check_glossary.py (all nine), and translation_status.py (20 current, 0 stale per language). The rendered HTML was checked to confirm the danger admonition appears in every language rather than trusting the source markdown. The one French blackout glossary finding predates this branch.

Two pre-existing bugs found during review are filed rather than fixed here: hatlabs/HALPI2-firmware#40 and #45.

A fly-by typo fix is included: "The following command with enable the CAN Bus" → "commands enable". The translations already rendered it correctly.

mairas added 2 commits August 11, 2026 15:57
The page omitted dtparam=i2c_arm=on, so /dev/i2c-1 never appeared and
halpid could not reach the power management controller. The i2c-dev
redirect ran outside sudo and failed, the firmware path did not exist,
and the NMEA 0183 baud rate read 34800.
Code fences stay in English per translate-page. The new I2C warning, the
i2c-dev module sentence and the firmware auto-flash note are translated;
Spanish and Italian keep the impersonal infinitive.
@github-actions

Copy link
Copy Markdown

Translation status

da — 20 current
de — 20 current
es — 20 current
fi — 20 current
fr — 20 current
it — 20 current
nb — 20 current
nl — 20 current
sv — 20 current

Every translation of the pages in scope is current.

Review of the previous commits found three claims that do not hold.

The package does not flash automatically: its postinst probes the board
with 'halpi get firmware_version', a subcommand halpi does not have, so
the probe always fails and nothing is flashed while apt reports success
(hatlabs/HALPI2-firmware#40). Manual flashing is now the documented path,
with the power-off the controller requires.

The config.txt edits need a reboot before /dev/i2c-1 appears, and the
page's only reboot sat inside the optional CAN section. A reader who
skipped it installed halpid against a bus that did not exist.

dtparam=sd=off also disables the onboard microSD slot and CM5 eMMC, so
readers who boot from either now get a warning before the block they
paste. The line stays: without it shutdown can stall past the
supercapacitor reserve.

Also drops the pinned firmware version for a glob that cannot match the
bootloader image, adds the sudo the daemon socket needs, and records
'kernel module' in eight glossaries.
@mairas mairas changed the title Sync manual install instructions with halos-pi-gen Fix the manual install instructions for HALPI2 Aug 11, 2026
@mairas

mairas commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Code review — fix/ubuntu-install-sync

Scope: 10 files, docs/{en,da,de,es,fi,fr,it,nb,nl,sv}/software-development/ubuntu-installation.md, base 28b2870.
Intent: bring the manual install page in line with what a HALPI2 actually needs, so a reader following it ends up with a working halpid.
Reviewers: correctness, testing, maintainability, project-standards (always-on), adversarial (205 changed lines; boot-config instructions that break installs when wrong).

All findings below were re-verified against the shipped packages, the kernel sources and the hardware files before being acted on. Everything actionable has been fixed in ce0872b; this comment records what was found and what was deliberately not done.

P0 — Critical

# File Issue Reviewer(s) Conf. Route
1 docs/en/…/ubuntu-installation.md:82 dtparam=sd=off was added with the comment "the unused SD card interface". The RPi overlays README says the parameter disables "the SD card (or eMMC on non-lite SKU of CM4/5)", and bcm2712-rpi-cm5.dtsi:734 maps sd to sdio1. HALPI2 has a fitted microSD socket (J26, (dnp no) in SDCard.kicad_sch, present in assembly-panel/bom.csv). A reader booting from microSD or CM5 eMMC would be unbootable at the next restart, recoverable only over rpiboot. adversarial, correctness 0.88 fixed

Fixed by keeping the line — it is needed on NVMe, where omitting it lets shutdown stall past the supercapacitor reserve — and putting a danger admonition before the block so the reader checks their boot device first. The fence comment now states what the parameter actually disables.

P1 — High

# File Issue Reviewer(s) Conf. Route
2 docs/en/…:139 "Flashing happens automatically when the package is installed or upgraded" is false. The postinst gates on halpi get firmware_version; halpi has no get subcommand (halpi/src/main.rs:17-45). The probe fails everywhere, nothing is flashed, apt reports success. adversarial, correctness 0.92 fixed + filed
3 docs/en/…:89 The config.txt edits need a reboot before /dev/i2c-1 exists, but the page's only reboot was the last line of the optional CAN section. A reader skipping CAN installed halpid against a bus that did not exist — the exact failure this PR set out to remove. adversarial, correctness 0.85 fixed
4 docs/en/…:139 The postinst tells users to power off after a flash ("restart is not sufficient"); the page said nothing, and its only reboot preceded the flash. adversarial 0.85 fixed

Package bugs behind #2 are filed as hatlabs/HALPI2-firmware#40, including a second one found in the same script: FIRMWARE_PATH uses dpkg -L | grep '\.bin$' | head -n 1, which resolves to bootloader_0.1.0.bin because it sorts first. The fallback message therefore instructs users to flash the bootloader into the application slot, and nothing downstream rejects it.

P2 — Moderate

# File Issue Reviewer(s) Conf. Route
5 docs/en/…:143 The flash example pinned halpi2-rs-firmware_3.3.1.bin in ten files, replacing a VERSION placeholder that could not go stale. correctness, maintainability, testing, adversarial 0.82 fixed
6 docs/en/…:143 halpi flash without sudo. The daemon socket is 0660 root:halpid (halpid/src/server/app.rs:161), and the package's own postinst prints sudo halpi flash in four branches. correctness, maintainability 0.75 fixed
7 docs/en/…:129 Non-root halpi needs a new login session before the halpid group applies, so halpi status fails in the reader's current shell. correctness 0.75 fixed
8 docs/en/…:139-143 The new firmware paragraphs duplicated user-guide/software.md:195-216, which already documents the same path and the AUTO_FLASH_ON_INSTALL procedure — and had the correct path while this page had the stale one. maintainability 0.85 fixed
9 8 glossaries kernel module was translated in eight languages without a glossary row; translate-page requires adding new terms in the same change. project-standards 0.78 fixed

#5 is fixed with a halpi2-rs-firmware_*.bin glob, which also cannot match bootloader_*.bin. #8 is fixed by trimming to a cross-reference, using each language's real translated anchor.

Pre-existing (action required)

# File Issue Route
10 docs/en/user-guide/software.md:375,378,381 Documents the daemon socket as /var/run/halpid.sock; the shipped default is /run/halpid/halpid.sock. All three curl examples fail. Same defect class as this PR, on a different page, in ten files. filed — #45
11 debian/postinst (HALPI2-firmware) Dead auto-flash probe and bootloader-selecting FIRMWARE_PATH. filed — hatlabs/HALPI2-firmware#40
12 docs/en/…:91 "The following command with enable the CAN Bus" — typo for "will". fixed here as a fly-by; translations already read correctly

Not done, deliberately

  • A pointer to halos-pi-gen in the config block (maintainability). Reader-facing docs should say why a setting is needed, not where it was copied from; most readers do not know what pi-gen is. Each config line already carries its own reason.
  • Dropping the I2C warning admonition as redundant with the fence comment (maintainability, 0.70). It is the single defect that broke installs; an admonition is more visible than a comment inside a block the reader is pasting.
  • A binary glossary row (project-standards, 0.66). Moot after the rewrite — the English now says "firmware images", and the "path to the binary" prose is gone.
  • New CI checks. Testing proposed shellcheck over fenced bash blocks (which flags exactly the sudo echo > defect, 1 true positive and 1 suppressible false positive across the whole corpus), an allowlist of documented absolute paths, and a cross-language code-fence identity check. All three look proportionate and all three are out of scope for a docs-content PR. Worth filing if wanted — say the word and I will.

Coverage

  • Suppressed: 0 findings below the confidence gate.
  • Untracked and excluded from scope: .claude/settings.local.json, book/.
  • Testing gap that remains: nobody has flashed stock Ubuntu on a HALPI2 and followed this page end to end. Every claim here was verified statically, against package artifacts, or in a container. Finding Built-in hardware devices #2 would have been caught by a single real run.
  • check_typography.py and check_glossary.py run only by hand; CI gates mkdocs build --strict and check_anchors.py only.

Verdict

Ready with fixes — all applied in ce0872b. mkdocs build --strict, check_typography.py, check_anchors.py (9880 links), check_glossary.py and translation_status.py all pass; all 16 code fences are byte-identical across the ten files; the danger admonition was confirmed in the rendered HTML for every language. The pre-existing French blackout glossary finding is unrelated and predates the branch.

@mairas
mairas merged commit 50510e9 into main Aug 11, 2026
1 check passed
@mairas
mairas deleted the fix/ubuntu-install-sync branch August 11, 2026 14:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant