交叉編譯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(碼雲)上,再克隆的。
或者使用淺克隆,意思就是複製的適合只複製與專案相關的東西,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