Skip to content

In-app path to write the camera FPGA bitstream to flash at 0x081A0000 (bitstream updates on bootloader units) #112

Description

@boringethan

Problem

Part 2 of #109. Not needed yet — filed so it isn't lost. #111 covers provisioning; this covers updating.

Once #111 lands, a factory unit gets its bitstream from the production image. But on a unit already running the bootloader, the bitstream can never change:

  • openmotion-bl clamps its DFU erase/write/upload window to the active application slot, 0x080200000x0809FFFF (USB_DEVICE/App/usbd_dfu_if.c). 0x081A0000 is far outside it.
  • Widening that window is the wrong fix. The bound exists so that all DFU-writable flash is covered by secure-boot slot verification; opening it up would reintroduce exactly the gap it was written to close.
  • Re-running the production image is a full reflash over SWD, not a field operation.

So today an FPGA bitstream update on a converted unit is an SWD/factory job.

Proposal

Add an application command that writes the bitstream into MCU flash at ADDR_CAMERA_BITSTREAM (0x081A0000) from host-streamed data, then reports back so the host can verify.

Why this is a comfortable place to do it:

  • The slot application executes from bank 1 (0x08020400, ≤511 KB) while the bitstream region is in bank 2, so erase and program happen on the non-executing bank — no read-while-write stall against the running code.
  • It is a natural extension of the existing OW_FPGA_* family, which today only programs the CrossLink's volatile SRAM (OW_FPGA_PROG_SRAM, OW_FPGA_BITSTREAM) and never touches the flash copy the boot path actually reads.
  • 163,489 B over the COMMS endpoint at 8192 B max payload is ~20 transactions; the two-sector erase dominates the wall time.

Design notes

  • Bound the write to 0x081A00000x081DFFFF and reject anything outside, the same way the bootloader bounds its own window.
  • Keep crosslink.c's length constant in sync. It streams a hardcoded byte count; if the stored bitstream can now change at runtime, the length needs to be stored alongside it rather than compiled in. Worth folding into this work — feat: merge the camera FPGA bitstream into the production image (#109) #111 added a CI guard that catches the compile-time mismatch, but that guard cannot see a bitstream written at runtime.
  • Verify before it is used, since a half-written bitstream currently fails only at the post-program status check on the next boot. A length + checksum record stored with the bitstream would let both this command and fpga_configure() refuse a bad blob.
  • Consider whether the region should be erased on failure, so a partial write cannot masquerade as valid.

Bonus

This also decouples FPGA updates from firmware updates for bare-metal units, where a bitstream change currently forces a full ~1.78 MB reflash of the merged image. The SDK could then flash the ~374 KB app-only image in the common case.

Related

Activity

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions