--- tags: MicroPython, ESP32, 測試報告 robots: ESP32, firmware, 韌體, 編譯, expressif, esp-idf, MicroPython lang: zh-tw --- 編譯 ESP32 的 MicroPython 韌體 === 由於編譯 MicroPython 韌體用到的都是 Linux 下開源的工具鏈, 雖然在 Windows 以及 Mac 上都有移植跨平台的工具, 但最便利的環境還是 Linux, 以下說明均以在 Ubuntu 20.04 為例。 :::info 在 Windows 上也可用 [WSL (Windows Subsystem for Linux)](https://hackmd.io/@meebox/H1VHLqCgF)。 ::: 以下假設以 ~/code 為主要的資料夾, 我們會將所有的工具、原始碼都放在這個資料夾下。 ```bash mkdir code cd code ``` ## 安裝所需的套件與 Python 環境 編譯 MicroPythonn 韌體需要使用到許多工具以及 Python2 與 Python3 執行環境, 以下一一安裝。 ### 安裝套件 1. 編譯韌體的 esp-idf 工具需要先安裝以下套件: ```bash sudo apt-get install git wget libncurses-dev flex bison gperf python3 python3-pip cmake ninja-build ccache libffi-dev libssl-dev libdb-dev python2 ``` ### 安裝 Python 模組 3. 安裝 Python2 的 pip 管理模組, 由於在 Ubuntu 上沒有可直安裝的 Python2-pip 套件, 這裡改採用下載並執行 get-pip.py 的方式安裝: ```bash curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py ``` 注意上述網址中的 2.7 是根據系統上 Python2 的版本而定, 若沒有指定, 會取得預設為 Python3 的 get-pip.py。取得安裝 pip 的 Python 程式後, 執行以下步驟安裝 pip: ```bash sudo python2 get-pip.py ``` 4. 安裝 ESP-IDF 工具鏈需要的 virtualenv 套件, 版本不能太新, 請安裝舊版本: ```bash pip2 install virtualenv==16.7.9 ``` 1. 稍後的韌體建置會使用到 Python3 以及 Python3 下的 pyparsing 模組, 且 pyparsing 模組必須是 2.4 版以下: ```bash pip3 install 'pyparsing<2.4' ``` ### 設定 Python 環境 2. MicroPython 編譯時會以 Python2 為預設的 Python, 所以我們再安裝以下的套件設定 Python2 為預設的 Python: ```bash sudo apt install python-is-python2 ``` :::info 如果你不需要編譯 1.14 或更早的版本, 可以只使用 Python3, 可安裝以下的套件將你的 Python3 設定為預設的 python: ```bash sudo apt install python-is-python3 ``` ::: ## 下載 MicroPython 原始碼 1. 首先回到 ~/code 資料夾下: ```bash cd ~/code ``` 1. 接著複製 MicroPython 的原始碼: ```bash git clone https://github.com/micropython/micropython.git cd micropython ``` ### 切換 MicroPython 版本 1. 如果需要編譯特定版本的 MicroPython, 可以先切換到特定的版本或是提交: ```bash git checkout v1.14 ``` 1. 在 1.14 或是更早的版本, 可以先查看編譯所需的 esp-idf 工具鏈版本, 這只要在還沒有設定好 esp-idf 工具前, 切換到 ports/esp32 下執行 make 就可以了, 以下以 v1.14 版本為例: ```bash cd ports/esp32 $ make Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity. The ESPIDF variable has not been set, please set it to the root of the esp-idf repository. See README.md for installation instructions. Supported git hash (v3.3): 9e70825d1e1cbf7988cf36981774300066580ea7 Supported git hash (v4.0) (experimental): 4c81978a3e2220674a432a588292a4c860eef27b Makefile:74: *** ESPIDF not set. Stop. ``` 可以看到倒數第三行說明可以採用 V3.3 版 的 esp-idf, 也是雜湊碼 9e70825 開頭的提交。 如果是 1.15 開始的 MicroPython 版本, 稍後就請直接使用 v4.0.2 版的 esp-idf 即可。 ## 安裝 esp-idf 開發工具 MicroPython 韌體的編譯使用的是 esp-idf 工具鏈: 1. 從 github 上複製 esp-idf 開發工具, 首先切回 code 資料夾下: ```bash cd ~/code git clone https://github.com/espressif/esp-idf.git ``` 1. 接著切換到該資料夾中: ```bash cd esp-idf ``` ### 切換 esp-idf 工具版本 1. 請依照前面下載 MicroPython 的步驟, 將 esp-idf 工具鏈檢出到對應標籤的版本, 以下以切換到 v4.0.2 版編譯 v1.16 版的 MicroPython 韌體為例: ```bash git checkout v4.0.2 ``` 1. 此倉庫用到許多子模組, 所以要先更新子模組: ```bash git submodule update --init --recursive ``` ### 建置與設定環境變數 1. 接著執行 install.sh 建置完整的 esp-idf 工具: ```bash ./install.sh ``` 1. 設定環境變數: ```bash . ./export.sh ``` :::success 這裡的 `.` 可以換成 `source`, 表示在目前 shell 下執行 export.sh 腳本, 而不是另外啟動一個 shell 來執行腳本, 這樣腳本裡設定的環境變數才會在目前的 shell 中生效。 ::: 這裡設置的環境變數只在目前的 shell 中有效, 如果關閉 shell 重新開啟, 就要再重新執行一次 export.sh。 這樣就完成 esp-idf 工具的建置。 ## 編譯跨平台 Python 編譯器 1. MicroPython 中可以載入以 Python 撰寫的模組, 這需要可將 py 檔編譯為 mpy 的編譯器, 因此要先建置這個編譯器: ```bash cd ~/code/micropython make -C mpy-cross ``` ## 編譯 MicroPython 韌體 1. 在 ports 資料夾下有各種控制板的 MicroPython 檔案, 我們先切換到 esp32 下: ```bash cd ports/esp32 ``` 1. 首先要先建置使用到的子模組: ```bash make submodules ``` 1. 接著編譯韌體: ```bash make ``` 1. 最後會在 build-GENERIC 下產生 firmware.bin 韌體檔: ```bash ls build-GENERIC/*.bin build-GENERIC/firmware.bin build-GENERIC/micropython.bin ``` ## 加入以 C 撰寫的模組 這裡以 [ulab](https://github.com/v923z/micropython-ulab) 模組為例, 說明如何將以 C 開發的模組一起編譯到 MicroPython 韌體中。 ### 下載模組原始碼 ```bash cd ~/code git clone https://github.com/v923z/micropython-ulab.git ulab ``` 如果需要的話, 也可以在這裡切換版本或是提交。 ### 讓 MicroPython 啟用 ulab 模組 請檢查你下載的 ulab 下 code/micropython.mk 檔, 是否有以下這行: ``` override CFLAGS_EXTRA += -DMODULE_ULAB_ENABLED=1 ``` 如果沒有的話, 請自行加上。 :::info 或者也可以在 ports/esp32/mpconfigport.h 檔, 在最後加上啟用 ulab 的敘述: ```CPP #define MODULE_ULAB_ENABLED (1) ``` ::: ### 編譯包含 C 模組的韌體 由於 esp-idf 工具在 4.x 與 3.x 版本採用的建置工具不同, 所以加入外部 C 模組的編譯方式略有差異, 以下分別說明。 #### MicroPython v1.15 或更新版本 由於使用新版的 esp-idf, 採用 CMake, 要在 micpropython/ports/esp32 中新增一個 makefile 檔, 告訴 CMake 要連帶把剛剛下載的 ulab 模組一起編譯到 MicroPython 韌體中。 1. 切換到資料夾中: ```bash cd micropython/ports/esp32 ``` 1. 新增如下內容的檔案, 命名為 makefile: ```makefile BOARD = GENERIC USER_C_MODULES = $(HOME)/code/ulab/code/micropython.cmake include Makefile ``` 1. 先把剛剛建置的結果清除後再重新建置: ```bash make clean make ``` #### MicroPython 1.4 或更舊的版本 1. 切換到資料夾中: ```bash cd micropython/ports/esp32 ``` 1. 先把剛剛建置的結果清除: ```bash make clean ``` 1. 在 make 時從指令行參數指定加入 C 模組一起編譯: ```bash make USER_C_MODULES=../../../ulab all ``` 建置完成一樣在 buile_GENERIC 下的 firmware.bin 就包含了 ulab 模組了。 ## 加入額外的 Python 模組 如果你有使用 Python 撰寫的模組想要加入 MicroPython 韌體中, 可以將模組檔案放入 ports/esp32/modules 下, 像是下載的 MicroPython 原始碼中並沒有 [umqtt](https://github.com/micropython/micropython-lib/tree/master/micropython/umqtt.robust) 模組, 下載放入後重新編譯就可以了: ```bash ls modules apa106.py flashbdev.py mpu6050.py urequests.py BlynkLib.py inisetup.py neopixel.py _boot.py keras_lite.py umqtt ```