# Reading an Emcraft SOM-NRF9151 from brintOS This machine reaches an Emcraft SOM-NRF9151 on its Starter Kit through two USB devices that you grant to it from Chrome: a SEGGER J-Link on the kit's debug header, which openocd drives over SWD, and the kit's own USB-serial bridge, which carries the board's shell. Installing a release onto the board is not part of this image yet. Everything below only reads the board. ## 1. Your own copy of the machine Fork `https://brintos.io/sergei/core-image-brintos-nrf-sdk` into your account (`https://brintos.io/new?fork=sergei/core-image-brintos-nrf-sdk`), and work in your fork: a visitor's session on ours gets a read-only root. In your machine, turn on **Settings → General → Developer mode**. This image carries its own HardwareJS runtime in `/boot` and runs on it only in Developer mode; with it off, Expect cannot spawn its children and the console tools fail. ## 2. What connects where SOM-NRF9151 Starter Kit |-- debug header (P4) --- J-Link --- USB --- the computer running Chrome `-- console USB (FT230X) ----------- USB --- the same computer Grant both devices to the machine. The console is 115200 8N1. ## 3. Check the station first With no board attached: brintos-selftest 99-nrf-station.test 99-som-nrf91.test 99-openocd.test 99-som-console.test ## 4. The board's shell som-console # the board's shell in picocom; C-a C-x leaves som-console --list # every USB-serial port this machine has minicom -b 115200 -D $(som-console --find) `som-console` finds the bridge by its USB id, not by its tty number, so it works in whatever order the devices were granted. Scripts take the node from `som-console --find`. ## 5. Probing and reading the chip The board config `board/emcraft-som-nrf9151.cfg` selects the J-Link and SWD and creates `nrf91.cpu`, with the flash bank `nrf91.flash` (bank 0) and the UICR bank `nrf91.uicr` (bank 1): openocd -f board/emcraft-som-nrf9151.cfg -c init -c "flash probe 0" -c shutdown prints `SWD DPIDR 0x6ba02477`, `Cortex-M33 r0p2` and `nRF9151-LACA 1024kB Flash, 256kB RAM`. `VTarget = 0.000 V` means the cable is on the wrong header or the wrong way round. A read needs no halt, so it runs with the application's watchdog live: openocd -f board/emcraft-som-nrf9151.cfg -c init -c "dump_image /tmp/flash.bin 0 0x100000" -c shutdown openocd -f board/emcraft-som-nrf9151.cfg -c init -c "flash read_bank 1 /tmp/uicr.bin" -c shutdown sha256sum /tmp/flash.bin /tmp/uicr.bin 1 MiB of flash took 57 s through a J-Link EDU Mini. `/tmp` is memory: copy what you keep off the machine before the session ends. Another SWD adapter, or another speed, is a variable set before the config: openocd -c "set BRINTOS_JTAG_IFACE interface/.cfg" -f board/emcraft-som-nrf9151.cfg ... openocd -c "set BRINTOS_JTAG_SPEED 2000" -f board/emcraft-som-nrf9151.cfg ... Keep the speed at 2000 kHz or below; above it, flash programming fails. ## 6. What the nRF9151 does not forgive Read these before anything that halts, erases or writes the chip: 1. **The application's watchdog.** The 1.2-114 application resets the chip 3 to 6 s after openocd halts it, and the halted operation dies with `SWD: Read data parity mismatch`. Run `watchdog disable` on the board's shell first. It stays off across `reset halt` and comes back at the next boot. 2. **A reset of an erased chip locks debug access** (APPROTECT), and openocd's `program` starts with a reset. Erase, write and verify in one openocd session with no reset in between, and reset only after the verify passes. 3. **The UICR is write-once.** Emcraft's hex files carry UICR records. Never write them: strip everything from `0xFF0000` up, and compare the UICR rather than write it. ## 7. Installing a release The machine carries Emcraft's release 1.2-114 for the SOM, unmodified: two applications, each in its own directory beside a PROVENANCE file that gives its origin, sha256, the version its shell reports, and the oldest modem firmware it runs on. | Release | Where | |---|---| | `asset_tracker_v2` | `/usr/share/brintos-som/nrf9151/asset_tracker_v2/` | | `hello_mcuboot` | `/usr/share/brintos-som/nrf9151/hello_mcuboot/` | With the J-Link and the console both attached: som-program-nrf91 --app asset_tracker_v2 --check # probe; is the release compatible? writes nothing som-program-nrf91 --app asset_tracker_v2 # install it som-program-nrf91 --app hello_mcuboot # or the other one `som-program-nrf91` keeps every rule in §6 for you: it turns the watchdog off, holds the core halted to prove nothing resets it (12 s, or the watchdog's own timeout and 3 s more when the board's shell reports a longer one; `--gate ` holds longer, and with no console it warns that the watchdog is unknown), erases only the 4 KiB pages the image covers, writes and verifies in one session, compares the UICR instead of writing it, and checks after the reset that the board reports the version the PROVENANCE names. Pages outside the image (the application's settings, a provisioned SoftSIM) are kept; `--erase all` clears the whole 1 MiB instead. It ends with one PASS or FAIL line and the time the run took. **The nRF91's own watchdog (WDT0)** is read by the probe too. Once started it is not stopped by a soft reset, the only reset this station makes, so: if it keeps counting while the core is halted, the gate lasts its timeout and 3 s more, and then, unfed, it fires there, before anything is erased (a timeout longer than 600 s is refused outright) -- this station cannot write such a board. If it pauses while the core is halted, openocd's flash loader feeds it through RR[0] as it writes; any other reload register enabled is warned about, because the loader leaves it unfed. 1.2-114 does not start WDT0 (it uses the nPM1300's watchdog). **A backup** is taken only with `--backup`: into `/tmp`, the pages the erase will clear (all 1 MiB with `--erase all`), one file per range, listed with their sha256 in a `.pages` file; write each back with `--image --addr
`. **Interrupting a run.** A Ctrl-C (or a HUP or TERM) is honoured between steps, never inside an openocd session: a write in progress runs to its end, and the run then says what it left (exit 130, or 129/143). A write that fails keeps its retry session in `/tmp/som-nrf91-retry-`, which starts with a plain `halt` -- do not reset or power-cycle the board, run the retry. Until that session is gone, the next run refuses to start (it would reset a chip that may be half-written); `--ignore-retry` overrides it once the board has been rewritten another way. **The modem firmware.** This station cannot update the nRF9151's modem. Before it writes anything, `som-program-nrf91` reads the modem firmware over the console (`AT%SHORTSWVER`) and refuses a release that needs a newer one; update the modem natively with `nrfutil device program --firmware mfw_nrf91x1_.zip`, then install again. The modem can be read only while the running application has an AT shell; when it cannot be read, the run says so and goes on. 1.2-114 runs on `nrf91x1_2.0.1` and later. **A locked chip.** If the probe reports the chip locked (APPROTECT), recover it from here, with a release to install in the same session: som-recover-nrf91 --app asset_tracker_v2 --yes It erases everything through the chip's CTRL-AP, the UICR included, writes the two UICR words that keep the debug port open (0x50FA50FA at 0x00FF8000 and 0x00FF802C; 1.2-114 opens the port at boot only when both hold), writes and verifies the release with its own UICR records, and only then resets. After the reset it checks that the debug port stayed open and reads the UICR back. A board's saved UICR page goes back instead with `--uicr `, and is compared with the file byte for byte once the chip has reset: the key-slot part of the UICR, from 0x00FF8400, reads back erased until then. It refuses a chip whose debug access is open (`som-program-nrf91` installs it and keeps the UICR) unless `--force`, which reads the chip out first, and a chip whose erase protection is set, which no debugger can recover. Once its erase has run, it sets aside, as `som-nrf91-recovered-*`, any retry session a failed write left in `/tmp`: that session no longer describes the chip, and `som-program-nrf91` would refuse to start beside it. `nrfutil device recover` on a PC remains the fallback. ## 8. The QA Test Plan's console tests `som-test-nrf91 --suite qa` runs the unattended console tests of the NRF-SOM QA Test Plan v23 against the board: 3.1 serial console, 3.2 version, 3.4 thread stacks and 3.6 SPI flash. It is not one of the default suites: som-test-nrf91 --suite qa --allow-reset # 3.1, 3.2 and 3.4 som-test-nrf91 --suite qa --allow-reset --allow-fs-writes # and 3.6 The tests reset the board, so the suite refuses to start without `--allow-reset`. The resets are soft, not the plan's power cycle: `kernel reboot cold` on the board's shell, or with `--reset swd` an openocd `reset run` through the J-Link, which then needs both devices granted. Every result says which, and names the plan test it ran. 3.6 writes two files, `atest` and `test1`, to the board's `/lfs1` and removes them at the end, which the plan does not; without `--allow-fs-writes` it is skipped. 3.4 runs only on a board that holds nRF Cloud credentials (`at AT%CMNG=1` lists key types 0, 1 and 2), and waits up to five minutes for `CLOUD_EVT_CONNECTED` (`--qa-cloud-wait`). The version 3.1 and 3.2 expect is taken from the PROVENANCE of the release the board runs (`1.2-114-release`); `--qa-version` names another. The expected lines are copied from v23, so a later edit of the plan does not reach the station.