OK, so after a long and harrowing journey through a majestic sea of makefiles 
, I think I got something working!
The following instructions are intended for the OPENMV4 target, which I believe corresponds to the OpenMV H7/OpenMV H7 R2 (please correct me if I’m wrong). For anyone reading in the future, I’m using revision d10c883e6557bd62bc105388360542407094ecdb of the source tree. This has not been thoroughly tested, but if I discover something I’m missing I’ll add a follow-up post to this thread.
Step 1
Download the source tree and the submodules using the instructions here: openmv/README.md at master · openmv/openmv · GitHub.
Step 2
Add a C++ source file to the project:
// src/omv/modules/new_custom_module.cpp
#include <algorithm>
extern "C" short biggest_short(short a, short b)
{
return std::max(a, b);
}
Step 3
Tell the MicroPython makefile (which is invoked indirectly by running make
in src/
), to add a corresponding entry to the list of object files to generate:
# src/micropython/ports/stm32/Makefile, in the variable definition section
OBJ += $(BUILD)/modules/new_custom_module.o
Step 4
Tell the MicroPython makefile how to build that object file:
# src/micropython/ports/stm32/Makefile, in the build rules section
$(BUILD)/modules/new_custom_module.o: ../../../omv/modules/new_custom_module.cpp
$(CXX) \
-Wall -Werror -Warray-bounds -Wdouble-promotion -Wno-float-conversion \
-mthumb -mcpu=cortex-m7 -mtune=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=hard \
-O2 -fdata-sections -ffunction-sections -fno-inline-small-functions \
-fsingle-precision-constant -fsingle-precision-constant -fdata-sections -ffunction-sections \
-nostartfiles -nostdlib \
-c -o $(BUILD)/modules/new_custom_module.o \
../../../omv/modules/new_custom_module.cpp
I lifted the flags from compilation commands I observed running make
in verbose mode (make V=1 TARGET=OPENMV4 -C src
). $(CXX)
resolves to either arm-none-eabi-g++
or @arm-none-eabi-g++
(the same thing, but quieter).
Step 5
Compile the firmware as you would normally. The functions defined in the C++ file can now be used in MicroPython modules:
// src/omv/modules/examplemodule.c
#include "py/runtime.h"
short biggest_short(short a, short b);
// Expose functions that use `biggest_short` here.
// Don't forget to flip the "module enabled" bit in the `MP_REGISTER_MODULE` call!
Using Rust
no_std
Rust seems to work as well:
// src/omv/modules/new_rusty_module.rs
#![no_std]
#![no_main]
use core::panic::PanicInfo;
use core::cmp;
#[panic_handler]
fn panic(_info: &PanicInfo<'_>) -> ! {
loop {}
}
#[no_mangle]
pub extern "C" fn smallest_long(a: i32, b: i32) -> i32 {
cmp::min(a, b)
}
# src/micropython/ports/stm32/Makefile, in the variable definition section
OBJ += $(BUILD)/modules/new_rusty_module.o
# src/micropython/ports/stm32/Makefile, in the build rules section
$(BUILD)/modules/new_rusty_module.o: ../../../omv/modules/new_rusty_module.rs
rustc \
--emit=obj --target thumbv7em-none-eabihf -C opt-level=3 \
-o $(BUILD)/modules/new_rusty_module.o \
../../../omv/modules/new_rusty_module.rs
I installed the Rust compiler and the Cortex-M7 code generator using rustup
:
> curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
> rustup target add thumbv7em-none-eabihf