13.1.14. 第三方儲存庫#

IDE 隨附 OpenMV 自己的開發板、韌體、範例、機器學習模型和編輯器存根,但它也可以載入來自其他公司的相同類型的內容 - 合作夥伴建立的開發板、在其上運行的韌體、為其調整的範例和模型,以及韌體添加的 API 的程式碼完成。這些內容以 third-party repositories 的形式到達:IDE 與自己的內容合併並保持最新的內容資料夾。

此頁面有兩個受眾。其中大部分是供安裝和管理其他人發布的儲存庫的人使用的。最後一部分,authoring a repository,用於供應商建置。

13.1.14.1. 第三方儲存庫頁面#

一切都透過編輯 → 首選項 → OpenMV → 第三方儲存庫進行管理。表格列出了每個已安裝的儲存庫,以及每個儲存庫的顯示名稱、短 ID(無論是 Built-inUser)、它提供的每種內容的已安裝版本(韌體、範例、模型、存根)以及它更新的 URL。

Built-in 表示儲存庫由供應商提供的安裝程式放置到應用程式自己的目錄中,就像驅動程式套件將檔案新增至程式一樣。 User 表示您自己透過 URL 安裝了它。唯一的實際區別是您無法從 IDE 中刪除內建儲存庫——它是透過卸載放置在其中的任何內容來刪除的——因此「刪除」按鈕對其停用。

13.1.14.2. 安裝儲存庫#

從 URL 安裝會詢問儲存庫的 config.json(供應商發布的小清單檔案)的位址,並安裝它指向的所有內容。貼上供應商給您的 URL; IDE 下載清單,取得韌體、範例、模型和它列出的存根,並驗證每個下載。安裝、刪除和更新儲存庫都會在重新啟動後生效,因此 IDE 會在安裝完成後重新啟動。

供應商還可以將儲存庫作為安裝程式分發,直接將其放入應用程式目錄中,在這種情況下,它在您第一次開啟頁面時僅顯示為 Built-in 行 - 無需安裝任何內容。

13.1.14.3. 保持儲存庫更新#

每次 IDE 啟動時都會檢查帶有更新 URL 的儲存庫。當有更新的內容可用時,IDE 會告訴您什麼 - 列出每個儲存庫和涉及的版本 - 並提供安裝它,所有這些都在一個提示中完成。檢查更新按需運行相同的檢查。

13.1.14.4. 優先權和覆蓋#

儲存庫是一個有序列表,最高優先權位於頂部,上移和下移會對所選儲存庫重新排序。只有當兩個來源提供 same 事物時,順序才重要:具有相同 USB 識別碼的板,或具有相同名稱的範例、模型或存根。當這種情況發生時,更高的條目會獲勝,並且每個儲存庫都會勝過 OpenMV 的內建內容。這是經過深思熟慮的——供應商為共享 OpenMV 板 USB 標識符的板提供自己的固件,替換 IDE 為其提供的庫存固件,或者用為其硬件編寫的示例替換庫存示例。

因為覆蓋會默默地改變熟悉名稱的功能,所以頁面永遠不會隱藏它。覆蓋警告面板列出了每個有效的覆蓋範圍——哪個存儲庫的板、示例、模型或存根正在覆蓋哪個——並且相同的列表在第一次看到存儲庫時作為訊息出現一次。如果某個板子、範例或模型的行為不符合 OpenMV 文件所描述的方式,那麼首先要查看此面板。

13.1.14.5. 儲存庫提供什麼#

這四種內容分別出現在 IDE 中的常用位置,因此安裝儲存庫後,就沒有什麼新內容要學習了:

  • Boards and firmware. 儲存庫的板的行為與 OpenMV 板完全相同 - 它在連接時被識別,其類型顯示在狀態列中,並且其韌體透過 IDE 更新,包括安裝最新開發版本路徑。參見韌體更新與復原

  • Examples. 存储库的示例出现在“文件”→“示例”中,并合并到类别树中:供应商与 OpenMV 类别命名相同的类别中的示例位于 OpenMV 类别旁边,新类别成为其自己的子菜单。像任何示例一样,它们会被过滤到它们支持的板。參見指令碼、範例與文件資料夾

  • Models. 儲存庫的模型出現在 Model Zoo 中,並以相同的方式合併到瀏覽器樹中,並帶有供應商自己的描述。

  • Stubs. 儲存庫可以傳送 .pyi 存根文件,因此 editor 為其韌體添加的功能提供補全、簽章和文件 - 與 OpenMV 自己的模組以及供應商的自訂 API 獲得的補全相同。

13.1.14.6. 創作儲存庫#

儲存庫是一個以供應商命名的資料夾,包含一個 config.json 清單和它提供的每種內容的子資料夾:

acme/
  config.json
  firmware/
    settings.json                 board descriptions
    ACME_CAM1/                    one folder per board, named by boardFirmwareFolder
      firmware.bin
      romfs0.img
  firmware.version
  examples/
    index.csv                     which examples show for which board / sensor
    01-Getting-Started/           numbered category folders, same as OpenMV's
      hello_acme.py
      read_sensor.py
    02-Acme-Widgets/
      spin_widget.py
  examples.version
  models/
    index.csv                     which models show for which board
    acme/                         a group; its index.html + image describe it
      index.html
      image.jpg
      person_detector/            one folder per model
        person_detector.tflite
        person_detector.txt       class labels
  models.version
  stubs/
    acme_hal.pyi                  a module the firmware adds
    csi.pyi                       overrides OpenMV's to add methods
  stubs.version

資料夾名稱是儲存庫ID:小寫字母、數字、-_,以字母開頭。每個零件資料夾都是可選的;只運送您擁有的東西。每個部件資料夾旁邊都有一個 <part>.version 文件,其中包含單一版本字串 (1.2.0),IDE 使用該文件來決定更新何時較新。

13.1.14.6.1. 清單#

config.json 命名儲存庫,並針對每個部分指向可下載的檔案:

{
  "name": "acme",
  "displayName": "Acme Robotics",
  "homepage": "https://acme.example",
  "configUrl": "https://acme.example/openmv/config.json",
  "firmware": {
    "release":     { "version": "1.2.0", "url": "https://acme.example/acme-fw-1.2.0.zip", "sha256": "..." },
    "development": { "version": "dev-20260701", "url": "https://acme.example/acme-fw-dev.zip", "sha256": "..." }
  },
  "examples": { "release": { "version": "1.1.0", "url": "https://acme.example/acme-examples-1.1.0.zip", "sha256": "..." } },
  "models":   { "release": { "version": "1.0.0", "url": "https://acme.example/acme-models-1.0.0.zip", "sha256": "..." } },
  "stubs":    { "release": { "version": "1.0.0", "url": "https://acme.example/acme-stubs-1.0.0.zip", "sha256": "..." } }
}

name 必须与文件夹名称匹配。 configUrl 是同一檔案的託管位址; IDE 會重新取得它以檢查更新,因此僅對於永遠不會更新的儲存庫省略它。每個零件都有一個 release 通道,韌體也可能有一個安裝最新開發版本時使用的 development 通道。版本 version 值作為數字進行比較,因此提供更高的值作為更新;開發版本僅針對變更進行比較。 sha256 是可選的,但在存在時進行驗證。

每個 url 都指向 .zip(僅限拉鍊)。檔案恰好包含 one top-level folder,IDE 會安裝該資料夾的 contents 作為該部分 - 因此韌體存檔的打包方式如下:

acme-fw-1.2.0.zip
  acme-firmware/           one wrapping folder; its name does not matter
    settings.json
    ACME_CAM1/
      firmware.bin
      romfs0.img

并解压到前面显示的 firmware/ 文件夹。範例、模型和存根檔案以相同的方式打包 - 一個包裝資料夾包含 examples/models/stubs/ 中的內容。包装文件夹的名称将被忽略;重要的是确实有一个。在没有包装文件夹的情况下将文件压缩到存档根目录,或者将它们包装在多个文件夹中,将无法安装。最簡單的方法是壓縮資料夾本身 - 選擇 acme-firmware 並壓縮它,而不是選擇其內容。

13.1.14.6.2. 板、範例、模型和存根#

firmware/settings.json 使用與 IDE 隨附的韌體相同的板描述格式;為每個面板新增一個 boards 條目。 一些特定於第三方董事會的規則: boardFirmwareFolder 必須是唯一的(OpenMV 或其他供應商尚未使用它,因為它命名了您的二進製文件所在的文件夾),每個板必須攜帶自己的 firmware_version(這是驅動連接時更新提示的原因),並且板可以將 boardFirmwareFolderAlias 替換為 OpenMV 板的集合配置文件為 OpenMV 板的樣本夾。 預計會重複使用 OpenMV 引導程式識別碼(它們攜帶簽署的 Windows 驅動程式);與內建板衝突的應用程式標識符會覆蓋該板,覆蓋警告面板會報告該情況。

範例位於編號類別資料夾中,例如 OpenMV 的 (01-Getting-Started);一個與 OpenMV 名稱相同的類別會插入其中,新名稱將成為自己的選單部分。模型是一個包含其 .tflite 和匹配的類別標籤 .txt 的資料夾,分組在一個資料夾下,其 index.html(和可選圖像)是模型動物園中其旁邊顯示的描述。 examples/index.csvmodels/index.csv 與 OpenMV 自己的範例和模型使用的板和感測器過濾器檔案相同,與您的範例和模型路徑相匹配,並決定您的哪個顯示於哪個板。存根是普通的 .pyi檔案;IDE 將它們的資料夾交給語言伺服器,以便它們與 OpenMV 的資料夾一起解析,並且以現有模組 (csi.pyi) 命名的存根會覆蓋該模組的完成。

13.1.14.6.3. 發布與更新#

要發布,請將 config.json 及其引用的檔案託管在穩定的 URL 上,並為使用者提供用於安裝的 config.json URL。任何透過 HTTPS 提供純檔案的地方都可以運作—Web 伺服器、物件儲存或程式碼主機。要發布更新,請上傳新存檔,在託管的 config.json 中增加受影響的 version 值,並且下次每個用戶的 IDE 啟動時它會提供更新。透過安裝程式安裝儲存庫的使用者會以相同的方式取得更新,只要安裝的 config.json 帶有 configUrl 即可。

13.1.14.6.4. 在 GitHub 上託管#

GitHub 是一個方便的主機,IDE 從它取得資源的方式與取得自己的資源的方式相同。有兩個部分需要放置:清單和檔案。

config.json 保留在儲存庫中,並為使用者提供其 raw URL——直接提供檔案的位址,而不是顯示該檔案的 GitHub 頁面。文件上的 Raw 按鈕會顯示它;它有以下形式

https://raw.githubusercontent.com/<user>/<repo>/<branch>/config.json

該原始 URL 是使用者貼到「從 URL 安裝」中的內容,以及您在清單自己的 configUrl 中放入的內容,以便 IDE 重新取得它以檢查更新。將其指向分支(main)意味著推送新的提交來發布更改;將其指向標籤會將使用者固定到固定版本。

.zip 存檔託管為 release assets 而不是提交它們 - 版本是為二進位下載而構建的,因此多兆位元組的韌體包屬於那裡,而不是存儲庫的歷史記錄中。將每個檔案附加到 GitHub 版本並使用其下載 URL,其格式為

https://github.com/<user>/<repo>/releases/download/<tag>/acme-fw-1.2.0.zip

在清單的 url 欄位中,每個欄位都有存檔的 sha256。然後發送更新:將新檔案附加到發行版,編輯 config.json 以指向它們並更改版本,然後提交。 IDE 在下次啟動時會擷取變更(原始檔案透過快取提供,在推送後幾分鐘內刷新)。