開源 MaixPy 專案開發指南
本文是為了幫助一些想要成為專業開發者的初學者而寫的開源專案の開發文件。
目錄獲取 maixpy 開源專案
請準備 linux 系統環境(在 Windows 上使用 WSL 也可以),掛上 XXX 代理,輸入 git clone https://github.com/sipeed/MaixPy
沒有代理的同學可以用 github 映象站列表(
https://github.com/rc1844/fastgithub
)加速拉取 maixpy 倉庫,請不要用 gitee 拉取 maixpy 倉庫,會掉子模組倉庫的。
juwan@juwan-N85-N870HL:~$ git clone https://gitclone.com/github.com/sipeed/MaixPy 正克隆到 'MaixPy'... remote: 物件計數中: 77517, 完成. remote: 壓縮物件中: 100% (20929/20929), 完成. remote: Total 77517 (delta 56791), reused 76050 (delta 55761) 接收物件中: 100% (77517/77517), 53.62 MiB | 972.00 KiB/s, 完成. 處理 delta 中: 100% (56791/56791), 完成. juwan@juwan-N85-N870HL:~$ cd MaixPy/ juwan@juwan-N85-N870HL:~/MaixPy$ git submodule update --recursive --init 子模組 'components/kendryte_sdk/kendryte-standalone-sdk'(https://github.com/sipeed/kendryte-standalone-sdk)已對路徑 'components/kendryte_sdk/kendryte-standalone-sdk' 註冊 子模組 'components/micropython/core'(https://github.com/micropython/micropython.git)已對路徑 'components/micropython/core' 註冊 子模組 'components/micropython/port/src/lvgl/lv_bindings'(https://github.com/littlevgl/lv_binding_micropython.git)已對路徑 'components/micropython/port/src/lvgl/lv_bindings' 註冊 子模組 'components/micropython/port/src/ulab/micropython-ulab'(https://github.com/Neutree/micropython-ulab.git)已對路徑 'components/micropython/port/src/ulab/micropython-ulab' 註冊 子模組 'components/spiffs/core'(https://github.com/pellepl/spiffs.git)已對路徑 'components/spiffs/core' 註冊 子模組 'tools/flash/kflash_py'(https://github.com/sipeed/kflash.py.git)已對路徑 'tools/flash/kflash_py' 註冊 子模組 'tools/kconfig/Kconfiglib'(https://github.com/ulfalizer/Kconfiglib.git)已對路徑 'tools/kconfig/Kconfiglib' 註冊 子模組 'tools/spiffs/mkspiffs'(https://github.com/igrr/mkspiffs.git)已對路徑 'tools/spiffs/mkspiffs' 註冊 正克隆到 '/home/juwan/MaixPy/components/kendryte_sdk/kendryte-standalone-sdk'... 正克隆到 '/home/juwan/MaixPy/components/micropython/core'...
注意,這之後拉取子倉庫是沒有加速的,會從 github 試圖拉取,你也可以用同樣的方法單獨拉取子模組位置(在 .gitmodules
中定義),本篇文件是無法幫你解決網路問題的。
如果 https://gitclone.com 掛了,就自己想辦法找其他線路吧。
如何確認最終子模組是否拉取完整,可以輸入 git submodule status
,不完整請不要進行編譯,必出錯誤。
juwan@juwan-N85-N870HL:~/Desktop/maixpy$ git submodule status 7fdb511fe61026eec5874885de5981c4f60f664d components/kendryte_sdk/kendryte-standalone-sdk (v0.5.2-181-g7fdb511) ced340d739e84737dd5c8e6b4ab9af2ea44e29e7 components/micropython/core (v1.11-64-gced340d73) ddf09164ee1711a61169030a7ee8bf370ee5743f components/micropython/port/src/lvgl/lv_bindings (remotes/origin/dev-6.0-32-gddf0916) c315a571df49a19b843f7dffc300c21ccb7d4edd components/micropython/port/src/ulab/micropython-ulab (0.24-27-gc315a57) ec68ba8208d7550860e4e78299d58a529b88bf85 components/spiffs/core (0.2-234-gec68ba8) 1ef6f4c0b2cb8b1872b6ffe9337f4e02d5487fa6 tools/flash/kflash_py (v1.0-79-g1ef6f4c) 53c72959ac4d71f99913e4b0eea99261a6585430 tools/kconfig/Kconfiglib (v12.12.1-14-g53c7295) 983970e40ff381d95d68a9bddff70c4d9921021b tools/spiffs/mkspiffs (0.2.3-6-g983970e)
編譯 maixpy 開源專案
這節內容假設你沒有任何搭建交叉編譯鏈的經驗。
首先按 build.md 順序執行各種操作即可,如果你不會英文你可以開翻譯機。
步驟說明如下:
- 給 linux 環境安裝必須的編譯工具和 Python 模組,確保 cmake / make / python3 可用。
- 設定 toolchain 工具鏈到系統
/opt/kendryte-toolchain/
目錄下,方便 SDK 尋找編譯工具,確保存在 /opt/kendryte-toolchain/bin/riscv64-unknown-elf-gcc 編譯工具。 - 進入到 MaixPy 的具體硬體專案下
cd projects/maixpy_k210
然後輸入python3 project.py build
開始編譯。
整個編譯步驟就這樣結束了, 編譯成功後你就會在 projects/maixpy_k210
目錄下得到一個 build 資料夾,裡面有如下檔案:
- maixpy.bin 將要被燒錄到 0x000000 地址的 K210 韌體。
- maixpy.txt 當前韌體對應的反編譯程式碼內容,輔助你排查 core dump 的指標地址的資訊。
其他檔案是編譯過程中產生的 .a 和 .o 中間編譯檔案,可忽略。
燒錄 maixpy 韌體到你的硬體
現在你拿到了 maixpy.bin 韌體,插入硬體,然後使用 python3 project.py -B goE -p /dev/ttyUSB1 -b 1500000 flash
燒錄硬體,以 -B
引數為例。
juwan@juwan-N85-N870HL:~/Desktop/maixpy/projects/maixpy_k210$ python3 project.py -h
-- SDK_PATH:/home/juwan/Desktop/maixpy
maixpy
usage: project.py [-h] [-p PORT] [-b BAUDRATE] [-t] [-n] [-s] [-B {dan,bit,bit_mic,goE,goD,maixduino,kd233,auto}] [-S] [--toolchain PATH] [--toolchain-prefix PREFIX]
[--config_file PATH] [--verbose]
{config,build,rebuild,menuconfig,clean,distclean,clean_conf,flash}
build tool, e.g. `python project.py build`
其中 -B goE
是選擇版型,可選的項有 dan,bit,bit_mic,goE,goD,maixduino,kd233,auto
表示燒錄方式,這個和具體硬體有很大關係。
-
bit 通常對應使用 CH340 的晶片。
-
maixduino 通常對應使用 CH552 的晶片。
具體你可以多種試試,還可以選擇燒錄頻率 115200 、1500000 的 BAUDRATE 選擇,當然,無論是哪種配置,只要能燒錄進去就行,更多的使用方法你需要檢視 -h 的幫助說明。
常見的燒錄過程如下:
➜ maixpy_k210_minimum git:(master) ✗ sudo kflash -b 1500000 -p /dev/ttyUSB0 build/maixpy.bin
[sudo] fqr 的密碼:
[INFO] COM Port Selected Manually: /dev/ttyUSB0
[INFO] Default baudrate is 115200 , later it may be changed to the value you set.
[INFO] Trying to Enter the ISP Mode...
._
[INFO] Automatically detected goE/kd233
[INFO] Greeting Message Detected, Start Downloading ISP
Downloading ISP: |============================================================================================================| 100.0% 10kiB/s
[INFO] Booting From 0x80000000
[INFO] Wait For 0.1 second for ISP to Boot
[INFO] Boot to Flashmode Successfully
[INFO] Selected Baudrate: 1500000
[INFO] Baudrate changed, greeting with ISP again ...
[INFO] Boot to Flashmode Successfully
[INFO] Selected Flash: On-Board
[INFO] Initialization flash Successfully
Programming BIN: |============================================================================================================| 100.0% 47kiB/s
[INFO] Rebooting...
命令列連線硬體 & 執行程式碼
到這一步基本都會使用了吧。
這裡推薦一下開發時的一些 linux 或 micropython 的快速操作,首先可以使用 minicom 或 picocom 串列埠工具進入 MicroPython 終端(在燒錄命令後加上 && picocom /dev/ttyUSB0 -b 115200
就可以了),接著進入到 micropython 可以按下 Ctrl + E 進入貼上模式,然後貼上程式碼後輸入 Ctrl + D 結束輸入執行程式碼。
>>>
paste mode; Ctrl-C to cancel, Ctrl-D to finish
===
=== print('hello world!')
===
hello world!
>>>
這樣你就完成了快速的驗證和開發,但如果你是要除錯某一段功能程式碼,你可以通過 mpfshell-lite 直接命令列上傳程式碼,復位就執行,然後報錯和除錯。
底層開發動態語言經常這樣操作,所以要感謝所有做直譯器介面的開發者做了大量的介面驗證。
MaixPy 專案應用說明
假設已經知道如何使用 MaixPy 工程進行開發、編譯、燒錄,接下來將深入介紹一些工具的用法,這裡面只交待一些常見用法,並不會展開細節說明。
介紹 cmake 的工程編譯方法
cmake 是通過 CMakeLists.txt 編寫程式碼和規則後編譯生成 Makefile 的工具,用法和細節自行百度,這裡有一個結構簡單的 cmake 工程Get_static_library_by_cmake供你執行和參考學習。
在沒有 cmake 之前,都是使用 makefile 的方式進行工程管理,直到今天 micropython 官方也依然是使用雙層 Makefile + inclue(makefile) 的工程管理多版型硬體的方法。
但 MaixPy 只把 micropython 當做一個依賴庫包加入到自己的環境當中,所以實際上 MaixPy 的軟體架構設計是圍繞著 K210 軟體元件的形式進行構建的。
因此可以來到 maixpy 資料夾裡存在一個 hello_world 的工程,讓看看它是怎麼構成的。
- hello_world
- build
- compile
- main
- CMakeLists.txt
- config_defaults.mk
- project.py
MaixPy 專案已經準備了一個模板提供給你進行 K210 的專案構建,這裡忽略專案構建的過程,重點關注需要可以編譯連結的工程配置部分,也就是 main 下的 CMakeLists.txt ,它的內容如下。
############### Add include ###################
# list(APPEND ADD_INCLUDE "include"
# )
# list(APPEND ADD_PRIVATE_INCLUDE "")
###############################################
############ Add source files #################
list(APPEND ADD_SRCS "src/main.cpp"
)
# aux_source_directory(src ADD_SRCS)
# list(REMOVE_ITEM COMPONENT_SRCS "src/test2.c")
###############################################
###### Add required/dependent components ######
list(APPEND ADD_REQUIREMENTS kendryte_sdk)
###############################################
############ Add static libs ##################
# list(APPEND ADD_STATIC_LIB "lib/libtest.a")
###############################################
register_component()
可以看到 ADD_SRCS
連結了一個 src/main.cpp
程式碼檔案作為程式入口。
通過 ADD_REQUIREMENTS
就可以載入其他地方的模組進來,例如 list(APPEND ADD_REQUIREMENTS kendryte_sdk)
則請求了 kendryte_sdk
這個 SDK 包。
如果想要連結自己的 nncase 庫呢?其他庫程式碼呢?
可以直接則改為絕對路徑下的 LINK_DIRECTORIES(/home/juwan/maixpy/projects/maixpy_old/main/src/nncase)
的程式碼就可以了,這樣做的前提是這個庫是由 cmake 工程的方式提供的。
這裡示範瞭如何在編譯呼叫自己的 nncase 庫,結合這些關鍵訊息再去閱讀工程,應該就可以較為輕鬆的用起來了吧。
如何打包 micropython spiffs 檔案系統分享出來
如果你深入使用了 MaixPy 進行開發,你會發現 MaixUI 提供了一種檔案系統檔案(img),當你刷入這個 UI 系統一樣的 img ,你就會在燒錄後直接進入 UI 介面。
需要知道 MicroPython 是從 0x0 開始的程式,在程式中會通過 spiffs 在 Flash 的 [0xD00000, (0xD00000 + 0x300000)) 區間構建 VFS (虛擬檔案系統),是由 maixpy/projects/maixpy_xxxxx/config_defaults.mk 中定義得到的。
CONFIG_SPIFFS_SIZE=0x300000
CONFIG_SPIFFS_START_ADDR=0xD00000
這裡只討論工具的使用,而不對其實現做詳解。
而 spiffs 是不支援目錄結構的,那麼我們會發現 ui 的 img 在 flash 裡的檔名稱會存在 lib/core.py
這樣的名稱,而正常情況下我們是不可能將這個檔案建立起來的,所以要通過工具將其打包。
在 tools/spiffs/mkspiffs 目錄下有 gen_spiffs_image.py 指令碼完成這個打包映象的功能,用法請看 tools/spiffs/README.md 說明。
- 在 spiffs 目錄下準備一個 fs 資料夾,包含你要打包的程式碼或資原始檔內容。
- 執行
python gen_spiffs_image.py ../../projects/maixpy_k210/config_defaults.mk
即可得到 maixpy_spiffs.img 二進位制檔案。 - 將上述得到的 img 燒入到 0xD00000 就恢復 micropython 的檔案系統裡的內容。
如果你做了一些小系統,用這樣的方式釋出,使用者拿到你提供的 img 檔案,燒入就可以立刻得到和你一樣的環境啦,這其實和基於 Linux 系統釋出某系統映象的結構是一樣的。
現在,你學會了嗎?
MaixPy 的持續整合服務(Travis CI)
Travis CI 提供的是持續整合服務(Continuous Integration,簡稱 CI)。它繫結 Github 上面的專案,只要有新的程式碼,就會自動抓取。然後,提供一個執行環境,執行測試,完成構建,還能部署到伺服器。
提及一下 MaixPy 是有藉助 travis + tools/release.sh 完成專案的編譯後,將編譯目錄上傳到了釋出伺服器上從而完成了每日構建,這常見於各類包的自動化構建與編譯,感興趣不妨自己親手試試。
如何更好的閱讀開源專案原始碼
說到這裡,以個人的角度來看,基於閱讀程式碼這種基本功要求之外,想要更好的閱讀原始碼,對於不同的專案有不同的組織架構,任何一位剛進入這個行業的初學者,可以用親身經歷的專案作為切入點,逐漸從專案架構、原始碼、編譯、測試、釋出軟體等方面建立起完整的軟體工程意識,圍繞此進行知識的深入學習也是一種不錯的手段,希望你能通過這篇文章建立起完整的軟體工程體系吧。
最後的參考資料
- bing.com + keyword + yourself