1. 程式人生 > 其它 >交叉編譯openmv原始碼(ubuntu)

交叉編譯openmv原始碼(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