14.1.1.2. Building the firmware¶
With the environment from Setting up the development environment in place, building a firmware image is two make commands plus a TARGET selection.
14.1.1.2.1. Compiling¶
First build mpy-cross, the host tool that compiles the frozen .py modules into bytecode (do this once, and again whenever you update MicroPython):
make -j$(nproc) -C lib/micropython/mpy-cross
Then build the firmware for a board, where <TARGET> is one of the names from the table below:
make -j$(nproc) TARGET=<TARGET>
-j$(nproc) builds in parallel across all CPU cores (on macOS use -j$(sysctl -n hw.ncpu)). TARGET is mandatory – make with no target aborts with “Invalid or no TARGET specified”.
A complete first build, end to end:
make sdk
make -j$(nproc) -C lib/micropython/mpy-cross
make -j$(nproc) TARGET=OPENMV4
14.1.1.2.1.1. Supported boards¶
TARGET values are the directory names under boards/. The cameras and their silicon:
Camera |
| MCU | Port | Core |
|---|---|---|---|---|
OpenMV Cam M4 |
| STM32F427 | stm32 | Cortex-M4 |
OpenMV Cam M7 |
| STM32F765 | stm32 | Cortex-M7 |
OpenMV Cam H7 |
| STM32H743 | stm32 | Cortex-M7 |
OpenMV Cam H7 Plus |
| STM32H743 + SDRAM | stm32 | Cortex-M7 |
OpenMV Pure Thermal |
| STM32H743 + SDRAM | stm32 | Cortex-M7 |
OpenMV Cam N6 |
| STM32N657 | stm32 | Cortex-M55 |
OpenMV Cam RT1062 |
| MIMXRT1062 | mimxrt | Cortex-M7 |
OpenMV AE3 |
| Alif Ensemble (dual M55) | alif | Cortex-M55 |
Arduino Portenta H7 |
| STM32H747 | stm32 | Cortex-M7 |
Arduino Giga |
| STM32H747 | stm32 | Cortex-M7 |
Arduino Nicla Vision |
| STM32H747 | stm32 | Cortex-M7 |
Arduino Nano 33 BLE Sense |
| nRF52840 | nrf | Cortex-M4 |
Arduino Nano RP2040 Connect |
| RP2040 | rp2 | Cortex-M0+ |
Build the exact TARGET for your hardware – e.g. OPENMV4 for the OpenMV Cam H7, OPENMV4P for the H7 Plus, OPENMV_N6 for the N6.
14.1.1.2.1.2. Build output¶
Everything for a board lands in build/<TARGET>/bin/. For TARGET=OPENMV4 that is build/OPENMV4/bin/, containing:
File | What it is |
|---|---|
| Firmware binary – flashed by OpenMV IDE Tools -> Load Custom Firmware and by |
| Firmware with debug symbols – the file you point the debugger at |
| The bootloader (only on boards with a bootloader enabled) |
| Combined bootloader + firmware image |
| Read-only ROM filesystem image flashed alongside the firmware |
The Alif AE3 is dual-core, so it produces firmware_M55_HP.elf / firmware_M55_HP.bin (the high-performance core) and a separate firmware_M55_HE.elf / firmware_M55_HE.bin (the high-efficiency core) plus a table-of-contents (TOC) image that tells the boot ROM where each core’s image lives.
14.1.1.2.1.3. Cleaning and rebuilding¶
Builds are isolated per board under build/<TARGET>/. To wipe one board’s build:
make TARGET=<TARGET> clean
There is no distclean; clean always needs a TARGET. mpy-cross is shared across boards – if you update MicroPython, rebuild it too:
make -C lib/micropython/mpy-cross clean
make -j$(nproc) -C lib/micropython/mpy-cross
To report the flash/RAM usage of a build:
make TARGET=<TARGET> size
14.1.1.2.1.4. Building in Docker (no host toolchain)¶
If you would rather not install anything on the host (or you are on a platform without a native build), use the Docker path:
git clone --recursive https://github.com/openmv/openmv.git
cd openmv/docker
make TARGET=<TARGET>
Artifacts appear in openmv/docker/build/<TARGET>. For repeated builds there is an incremental dev path that mounts the repo at the same absolute path inside the container as on the host, so debugger source paths resolve without remapping:
make install-sdk
make build-firmware-dev TARGET=<TARGET>
Run make clean-dev when switching TARGET.
14.1.1.2.2. Build options¶
Build behavior is controlled by variables passed on the make command line, for example:
make -j$(nproc) TARGET=OPENMV4 DEBUG=1 V=1
The variables a firmware developer will use:
Variable | Default | Effect |
|---|---|---|
| (required) | The board to build. Selects |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Which debugger the |
Note
Many more variables exist (camera/sensor drivers, wireless stacks, ML backends, USB stack, secure boot, etc.), but those are set per-board in boards/<TARGET>/board_config.mk and are not normally overridden on the command line. Changing them is board customization, not a normal developer build – see docs/boards.md in the firmware repository.
For everyday work the only options you need are TARGET (always), DEBUG=1 (whenever you intend to debug, see Debugging the firmware), and occasionally V=1.