交叉编译openmv源码(ubuntu)
准备
- 下载源代码:https://github.com/openmv/openmv.git
- 准备一台有ubuntu系统的电脑,可以使用wsl来在windows安装ubuntu。(请看我的其他随笔)
环境
按照官方文档依次执行:
sudo apt-get update
sudo apt-get install git build-essential
安装GUN编译器
TOOLCHAIN_PATH=/usr/local/arm-none-eabi
TOOLCHAIN_URL="https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-rm/10-2020q4/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2"
sudo mkdir ${TOOLCHAIN_PATH}
wget --no-check-certificate -O - ${TOOLCHAIN_URL} | sudo tar --strip-components=1 -jx -C ${TOOLCHAIN_PATH}
export PATH=${TOOLCHAIN_PATH}/bin:${PATH}
解释一下:TOOLCHAIN_PATH为保存GUN编译器的路径,linux安装文件可能只需要解压即可运行。
获取代码
git clone https://github.com/openmv/openmv.git
这里获取代码非常不方便,因为GitHub网速感人,且经常断线。我将Github源码导入gitee(码云)上,再克隆的。注意还有子模块也要导入gitee,光只复制openmv工程子模块还是要从GitHub下载
或者使用浅克隆,意思就是复制的适合只复制与项目相关的东西,git仓库其他占内存历史文件就不复制了:
git clone --depth=1 https://gitee.com/pxforever/openmv-mirror.git
cd openmv
git submodule update --init --depth=1 --no-single-branch
git -C src/micropython/ submodule update --init --depth=1
编译
两个编译都要执行,先执行上面的make。再执行下面的make
cd openmv
make -j$(nproc) -C src/micropython/mpy-cross # Builds Micropython mpy cross-compiler
make -j$(nproc) TARGET=<TRAGET_NAME> -C src # Builds the OpenMV firmware
例如:
make -j$(nproc) TARGET=OPENMV4 -C src #Builds the boards of OpenMv4
支持如下版型:
ARDUINO_NANO_RP2040_CONNECT,NANO33,NICLAV,OPENMV1,OPENMV2,OPENMV3,OPENMV4,OPENMV4P,OPENMVPT,PICO,PORTENTA
编译注意
在每次退出用户或者重启机器,用户的环境变量会重置,建议将环境变量做出shell脚本
#!/bin/bash
TOOLCHAIN_PATH=/usr/local/arm-none-eabi &&
export PATH=${TOOLCHAIN_PATH}/bin:${PATH}
命名为source.sh,然后给予执行权限,chmod 777 source.sh
,接着以后可以执行source source.sh
完成环境变量设置。
问题
编译过程我遇到了undefined问题,如下:
/usr/local/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld: /home/px/openmv-mirror/src/build/micropython/modules/ulab/code/numpy/numpy.o:(.rodata.ulab_numpy_globals_table+0x1b4): undefined reference to `io_load_obj'
/usr/local/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld: /home/px/openmv-mirror/src/build/micropython/modules/ulab/code/numpy/numpy.o:(.rodata.ulab_numpy_globals_table+0x1bc): undefined reference to `io_loadtxt_obj'
/usr/local/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld: /home/px/openmv-mirror/src/build/micropython/modules/ulab/code/numpy/numpy.o:(.rodata.ulab_numpy_globals_table+0x1ec): undefined reference to `io_save_obj'
/usr/local/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld: /home/px/openmv-mirror/src/build/micropython/modules/ulab/code/numpy/numpy.o:(.rodata.ulab_numpy_globals_table+0x1f4): undefined reference to `io_savetxt_obj'
collect2: error: ld returned 1 exit status
make: *** [omv/ports/stm32/omv_portconfig.mk:655: firmware] Error 1
make: Leaving directory '/home/px/openmv-mirror/src'
查看文件omv/ports/stm32/omv_portconfig.mk第655行:
652 # This target generates the main/app firmware image located at 0x08010000
653 $(FIRMWARE): FIRMWARE_OBJS
654 $(CPP) -P -E -I$(OMV_BOARD_CONFIG_DIR) $(OMV_DIR)/ports/$(PORT)/$(LDSCRIPT).ld.S > $(BUILD)/$(LDSCRIPT).lds
655 $(CC) $(LDFLAGS) $(FIRM_OBJ) -o $(FW_DIR)/$(FIRMWARE).elf $(LIBS) -lgcc
656 $(OBJCOPY) -Obinary -R .big_const* $(FW_DIR)/$(FIRMWARE).elf $(FW_DIR)/$(FIRMWARE).bin
657 $(PYTHON) $(MKDFU) -D $(DFU_DEVICE) -b $(MAIN_APP_ADDR):$(FW_DIR)/$(FIRMWARE).bin $(FW_DIR)/$(FIRMWARE).dfu
第655行中$(FIRM_OBJ)是包含所有的.o文件,查看源码numpy.c是需要io.c文件中的四个变量:io_load_obj,io_loadtxt_obj,io_save_obj,io_savetxt_obj
。
将655行命令翻译出来,或者使用make V=1 -j$(nproc) TARGET=OPENMV4 -C src
可看到一大串打印,复制该串打印命令,进入到src/build目录下粘贴执行,发现还是该问题,在-o
前手动加入引用文件目录:/home/xx/openmv-mirror/src/build/micropython/modules/ulab/code/numpy/io/io.o
。发现可以正常运行,那么就是少了引用。
查看build文件目录下,发现io.o已经存在,那么问题可能是没有添加到路径中,故在:
omv_portconfig.mk的412行修改如下:
ifeq ($(MICROPY_PY_ULAB), 1)
FIRM_OBJ += $(addprefix $(BUILD)/$(MICROPY_DIR)/modules/ulab/,\
........
code/numpy/numpy.o \
code/numpy/io/io.o \ (此行为添加的行)
........
)
endif
其他
接下来有空就为大家带来如何写自己的驱动,以及设置python接口。