Flash Verify Passed but the Board Did Not Boot: Make Programming and Functional Tests Separate Gates
A completed, error-free verification with reconciled section and byte coverage establishes a specific image-to-memory comparison through the selected access path. A success return or banner alone is insufficient, including in the pinned OpenOCD version below. It does not establish that the board selects that image at reset, executes it correctly or meets a product requirement. Preserve programming, memory verification, reset/boot identity and functional acceptance as separate gates.
The concrete tool boundary here is upstream OpenOCD 0.12.0, including its tagged manual and program helper implementation. Vendor scripts, flash drivers and later versions need their own review. No OpenOCD session, flash operation or board test was executed; the procedure is a proposed station qualification plan.
Inspect what the station actually requested
Start with the complete invocation, board/interface scripts, tool build and selected image. Do not infer optional actions from a log line or from the GUI button’s name. An image called production.bin is not enough: retain its digest, approved manifest and intended hardware compatibility.
In the 0.12.0 program helper, initialization is followed by reset init. If programming is needed, the helper invokes flash write_image erase. The post-write verify operation occurs only when requested; a reset run at the end is also conditional. A wrapper that omits these options cannot claim their results simply because the helper returned successfully.
The same implementation has a preverify path before writing. If its comparison succeeds, programming is skipped. Record that branch as “existing image comparison accepted,” rather than reporting that new bytes were programmed. It still does not establish boot or functional success.
These details explain the tool’s behavior, not a recommendation to run its erase-capable helper blindly. Qualification must review the actual flash geometry, affected erase regions, per-unit data and recoverability before any write.

Define the verification coverage explicitly
Inventory the image sections, their addresses, lengths and any supplied relocation offset. The tagged manual’s image commands describe test_image as displaying section sizes and addresses. Use an offline artifact inventory or a reviewed tool session to reconcile that coverage with the approved memory map.
A raw binary needs the correct placement contract. A structured image can contain multiple sections and gaps. Comparing the represented image bytes does not establish that every unrelated location, configuration word, boot selector or external storage component contains the intended state.
Make a coverage worksheet with one row per required artifact: bootloader, application, configuration, external image and per-unit data where applicable. For each, identify who writes it, who checks it and what cannot be read through the selected path. Do not fill a missing row with the application’s verify result.
Reject a success banner with incomplete coverage
The 0.12.0 target.c verification handler initializes its return value to success. If allocation of a section buffer fails, it prints an allocation-error diagnostic and leaves the loop without setting a failure return. With no earlier comparison differences, the handler can return success and report only a partial or zero verified-byte total. That return can also satisfy the program helper’s preverify check and skip writing.
This is a source-derived edge case; no allocation failure or OpenOCD execution was induced here. Require absence of allocation/error diagnostics and reconcile completed section/address coverage and total compared bytes with an independently established artifact inventory. Treat truncated output or unexplained coverage as incomplete verification, even when the process exits successfully. Do not rely on test_image alone as an independent completeness oracle: the pinned source routes it through the same internal handler.
Describe the comparison accurately
OpenOCD 0.12.0 documents verify_image as first attempting a CRC comparison and falling back to binary comparison when that fails. It is therefore inaccurate to describe every successful invocation as an unconditional byte-for-byte comparison. The separate verify_image_checksum command performs only the checksum comparison.
The manual also distinguishes flash verify_image: flash banks with a specific verification method can use that method instead of ordinary target-memory reads. Its result is an overall bank outcome rather than a list of individual failed byte addresses. Check which command the station actually used and what the selected driver supports.
None of these results authenticates the approved publisher by itself. A correct comparison against the wrong artifact remains wrong for the product. Image authorization, compatibility and rollback policy belong to their own reviewed controls.
Require a fresh boot observation
After the programming gate, qualify the reset condition the product requires. A debugger-controlled reset may leave power domains or peripherals in a different state from a cold start. Use the board’s approved reset or power procedure and record its observed completion.
Identify the image that actually starts. A bootloader may choose another slot, medium or recovery path even when the intended application bytes compare correctly. Bind the runtime response to a new boot session and to the connected unit; an old serial-buffer message must not satisfy this gate.
A version string is useful only within a trustworthy build/identity contract. Where the application can report a build identifier tied to the release artifact, compare it with the manifest. If that relationship has not been established, state the weaker evidence rather than treating arbitrary text as a cryptographic proof.
Give each failure a distinct next action
| Gate outcome | First investigation | Do not conclude |
|---|---|---|
| Programming command fails. | Target selection, transport, power, flash driver and operation stage. | That no target bytes changed. |
| Write reports success; comparison fails. | Image addresses, read path and programming evidence. | That a reboot will repair the mismatch. |
| Comparison passes; expected boot identity is absent. | Reset, boot selection, dependencies and startup diagnostics. | That verification tested execution. |
| Expected image starts; functional check fails. | The specific product function and its stimulus/measurement path. | That reflashing is the appropriate default repair. |
Retain intermediate results even when the final disposition is failure. A complete record allows the next engineer to begin at the first unsupported gate rather than repeat every write. An interrupted command should remain uncertain until the tool and device state are reconciled.
Challenge the station’s gate logic
On recoverable qualification hardware, plan separate controls for omitted verification, incorrect image placement, wrong boot selection and a validly programmed image with an intentionally failing application-level test. Use reviewed artifacts and isolation appropriate to each control; do not improvise destructive failures on production units.
First exercise the report pipeline with synthetic gate results. Require a missing or failed gate to prevent a final pass, and require the report to distinguish preverified/no-write from programmed-and-verified. These software checks can expose reporting errors without programming anything, but they do not qualify the electrical or flash path.
Define the functional check in terms of a requirement and an observable result: a controlled input produces the required output, for example. Merely reaching main or printing a banner can be a useful startup milestone without being the product’s acceptance test.
Release an evidence chain, not one success banner
The station record should bind unit identity, artifact manifest, tool/configuration, covered address ranges, operation branch, comparison result, reset evidence, running-image identity and functional observations. Preserve an explicit missing state for a gate that was not performed.
This decomposition does not promise that every boot or hardware defect will be found. It makes the scope of each result visible, so a successful memory comparison cannot silently stand in for the execution and product evidence still required.