分享方式:


向裝置更新註冊元件

本文示範 IoT 中樞元件列舉程式的裝置更新實作。 您可以參考此範例,為自己的 IoT 裝置實作自訂元件列舉程式。 「元件」是裝置層級下方的身分識別,與主機裝置具有組合關聯性。

本文示範使用稱為 Contoso Virtual Vacuum 之虛擬 IoT 裝置的元件列舉程式。 元件列舉程式可用來實作「Proxy 更新」功能。

Proxy 更新可讓您更新同一 IoT 裝置上的多個元件,或是透過單一無線部署連線到 IoT 裝置的多個感應器。 Proxy 更新支援更新元件的安裝順序, 也支援使用預先安裝、安裝、後續安裝功能執行多步驟更新。

Proxy 更新適用的使用案例包含:

  • 將特定更新檔案的目標設為裝置上的分割區。
  • 將特定更新檔案的目標設為裝置上的應用程式或元件。
  • 將特定更新檔案的目標設為透過網路通訊協定 (例如 USB 或 CAN 匯流排) 連線到 IoT 裝置的感應器。

如需詳細資訊,請參閱 Proxy 更新和多元件更新

裝置更新代理程式會在主機裝置上執行。 可將每項更新傳送至特定元件或屬於相同硬體類別的一組元件 (也就是要求相同的軟體或韌體更新)。

什麼是元件列舉程式?

元件列舉程式是裝置更新代理程式的延伸模組,可針對透過主機裝置的 Azure IoT 中樞連線進行無線更新所需的每項元件提供相關資訊。

裝置更新代理程式不受裝置和元件的限制。 此代理程式本身對更新時在主機裝置上 (或連線至主機裝置) 的元件一無所知。

若要啟用 Proxy 更新,裝置建置者必須識別可更新裝置上的所有元件,並為每個元件指派唯一名稱。 此外,也可以為屬於相同硬體類別的元件指派群組名稱,這樣就能替同一群組中所有元件安裝一樣的更新, 然後,更新內容處理常式就可以將更新安裝並套用至正確的元件。

顯示 Proxy 更新流程的圖表。

以下是 Proxy 更新流程中每個部分的職責:

  • 裝置建置者

    • 設計和建置裝置。

    • 整合裝置更新代理程式及其相依性。

    • 實作裝置特定元件列舉程式延伸模組,並向裝置更新代理程式註冊。

      元件列舉程式會使用元件詳細目錄或設定檔中的資訊,以動態資料 (例如韌體版本、連線狀態、硬體身分識別) 增加靜態元件資料 (需要裝置更新)。

    • 建立 Proxy 更新,其中包含一或多項將目標設為裝置上 (或連線至裝置的) 一或多個元件的子系更新。

    • 將此更新傳送給解決方案操作員。

  • 解決方案操作員

    • 將更新和資訊清單匯入裝置更新服務。

    • 將更新部署至一組裝置。

  • 裝置更新代理程式

    • 透過裝置對應項或模組對應項從 IoT 中樞取得更新資訊。

    • 叫用「步驟處理常式」,用於處理裝置上一或多個元件專屬的 Proxy 更新。

      本文中的範例有兩項更新:host-fw-1.1motors-fw-1.1。 針對每項子系更新,父代步驟處理常式會叫用子系步驟處理常式,以列舉符合子系更新資訊清單檔中指定 Compatibilities 屬性的所有元件。 接下來,處理常式會下載子系更新,並將其安裝及套用至所有目標元件。

      為了取得相符元件,子系更新會呼叫元件列舉程式所提供的 SelectComponents API, 如果沒有相符的元件,則會略過子系更新。

    • 從父代和子系更新收集所有更新結果,然後將結果回報給 IoT 中樞。

  • 子系步驟處理常式

    • 逐一查看與子系更新內容相容的元件執行個體清單。 如需詳細資訊,請參閱步驟處理常式 (英文)。

在生產環境中,裝置建立器可以使用現有處理常式 (英文),或實作自訂處理常式,以叫用無線更新所需的任何安裝程式。 如需詳細資訊,請參閱實作自訂更新內容處理常式 (英文)。

Virtual Vacuum 元件

在本文中,我們會使用虛擬 IoT 裝置來示範重要概念和功能。 Contoso Virtual Vacuum 裝置包含五個邏輯元件:

  • 主機韌體
  • 主機開機檔案系統
  • 主機根檔案系統
  • 三個馬達 (左滾輪、右滾輪、真空吸塵器)
  • 兩個相機 (前方和後方)

顯示 Contoso Virtual Vacuum 元件的圖表。

下列目錄結構會模擬這些元件:

/usr/local/contoso-devices/vacuum-1/hostfw
/usr/local/contoso-devices/vacuum-1/bootfs
/usr/local/contoso-devices/vacuum-1/rootfs
/usr/local/contoso-devices/vacuum-1/motors/0   /* left motor */
/usr/local/contoso-devices/vacuum-1/motors/1   /* right motor */
/usr/local/contoso-devices/vacuum-1/motors/2   /* vacuum motor */
/usr/local/contoso-devices/vacuum-1/cameras/0  /* front camera */
/usr/local/contoso-devices/vacuum-1/cameras/1  /* rear camera */

每個元件的目錄都包含 JSON 檔案,用於儲存各個元件的模擬軟體版本號碼。 JSON 檔案範例為「firmware.json」與「diskimage.json」。

在此示範中,為了更新元件的韌體,我們會將「firmware.json」或「diskimage.json」(更新承載) 複製到目標元件的目錄。

以下是「firmware.json」檔案的範例:

{
    "version": "0.5",
    "description": "This component is generated for testing purposes."
}

注意

Contoso Virtual Vacuum 包含軟體或韌體版本,僅用於示範 Proxy 更新, 不提供其他任何功能。

實作元件列舉程式 (C 語言)

需求

實作 component_enumerator_extension.hpp (英文) 中宣告的所有 API:

函式 引數 傳回
char* GetAllComponents() JSON 字串,其中包含「所有」ComponentInfo 值的陣列。 如需詳細資訊,請參閱範例傳回值
char* SelectComponents(char* selector) JSON 字串,其中包含用於選取更新目標元件的一或多個名稱/值組 JSON 字串,其中包含 ComponentInfo 值的陣列。 如需詳細資訊,請參閱範例傳回值
void FreeComponentsDataString(char* string) 先前由 GetAllComponentsSelectComponents 函式傳回的字串緩衝區指標

ComponentInfo

ComponentInfo JSON 字串必須包含下列屬性:

名稱 類型​​ 描述
id string 元件的唯一身分識別 (裝置範圍), 例如硬體序號、磁碟分割區識別碼,以及元件的唯一檔案路徑。
name string 元件的邏輯名稱。 此屬性是裝置建置者為相同 device 類別中每部裝置都有的元件所指派的名稱。

例如每部 Contoso Virtual Vacuum 裝置都包含驅動左滾輪的馬達, 因此 Contoso 會將「左馬達」指派為此馬達的一般 (邏輯) 名稱,而非指派全域唯一的硬體識別碼,以便輕鬆參考此元件。
group string 此元件隸屬的群組。

舉例來說,所有馬達可能都屬於「馬達」群組。
manufacturer string 對實體硬體元件而言,此屬性是製造商或廠商名稱。

對磁碟分割區或目錄等邏輯元件而言,這可以是任何裝置建立器的定義值。
model string 對實體硬體元件而言,此屬性是型號名稱。

對磁碟分割區或目錄等邏輯元件而言,此屬性可以是任何裝置建置者定義的值。
properties object 包含任何選擇性裝置特定屬性的 JSON 物件。

以下是以 Contoso Virtual Vacuum 元件為基礎的 ComponentInfo 程式碼範例:

{
    "id": "contoso-motor-serial-00000",
    "name": "left-motor",
    "group": "motors",
    "manufacturer": "contoso",
    "model": "virtual-motor",
    "properties": {
        "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
        "firmwareDataFile": "firmware.json",
        "status": "connected",
        "version" : "motor-fw-1.0"
    }
}

範例傳回值

以下是 GetAllComponents 函式傳回的 JSON 文件, 以 Contoso Virtual Vacuum 元件列舉程式的實作範例為基礎。

{
    "components": [
        {
            "id": "hostfw",
            "name": "hostfw",
            "group": "firmware",
            "manufacturer": "contoso",
            "model": "virtual-firmware",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/hostfw",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "host-fw-1.0"
            }
        },
        {
            "id": "bootfs",
            "name": "bootfs",
            "group": "boot-image",
            "manufacturer": "contoso",
            "model": "virtual-disk",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/bootfs",
                "firmwareDataFile": "diskimage.json",
                "status": "ok",
                "version" : "boot-fs-1.0"
            }
        },
        {
            "id": "rootfs",
            "name": "rootfs",
            "group": "os-image",
            "manufacturer": "contoso",
            "model": "virtual-os",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/rootfs",
                "firmwareDataFile": "diskimage.json",
                "status": "ok",
                "version" : "root-fs-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00000",
            "name": "left-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00001",
            "name": "right-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/1",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00002",
            "name": "vacuum-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/2",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-camera-serial-00000",
            "name": "front-camera",
            "group": "cameras",
            "manufacturer": "contoso",
            "model": "virtual-camera",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/0",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "camera-fw-1.0"
            }
        },
        {
            "id": "contoso-camera-serial-00001",
            "name": "rear-camera",
            "group": "cameras",
            "manufacturer": "contoso",
            "model": "virtual-camera",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/1",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "camera-fw-1.0"
            }
        }
    ]
}

以下是 SelectComponents 函式傳回的 JSON 文件, 以 Contoso 元件列舉程式的實作範例為基礎。

以下是用於選取「馬達」元件群組的輸入參數:

{
    "group" : "motors"
}

以下是此參數的輸出, 所有元件都屬於「馬達」群組。

{
    "components": [
        {
            "id": "contoso-motor-serial-00000",
            "name": "left-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00001",
            "name": "right-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/1",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00002",
            "name": "vacuum-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/2",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        }
    ]
}

以下輸入參數用於選取名為「hostfw」的單一元件:

{
    "name" : "hostfw"
}

以下是「hostfw」元件的參數輸出:

{
    "components": [
        {
            "id": "hostfw",
            "name": "hostfw",
            "group": "firmware",
            "manufacturer": "contoso",
            "model": "virtual-firmware",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/hostfw",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "host-fw-1.0"
            }
        }
    ]
}

注意

上述範例顯示如有需要,可以將較新的更新傳送給 name 屬性所選取元件的任何執行個體。 舉例來說,您可以將 motor-fw-2.0 更新部署至「vacuum-motor」,同時在「left-motor」與「right-motor」上繼續使用 motor-fw-1.0

詳細目錄檔案

先前顯示的 Contoso Virtual Vacuum 元件列舉程式實作範例會從 component-inventory.json 檔案讀取裝置特定元件的資訊。 此實作範例僅供示範用。

在生產案例中,部分屬性應該直接從實際元件擷取, 包括 idmanufacturermodel

裝置建立器會定義 namegroup 屬性。 這些值一經定義就絕不會再變更。 在裝置內 name 必須為唯一屬性。

component-inventory.json 檔案範例

注意

此檔案中的內容與 GetAllComponents 函式的傳回值幾乎相同, 但此檔案內的 ComponentInfo 不包含 versionstatus 屬性。 元件列舉程式會在執行階段填入這些屬性。

以「hostfw」為例,properties.version 屬性的值會從指定的 (模擬) firmwareDataFile 值 (/usr/local/contoso-devices/vacuum-1/hostfw/firmware.json) 填入。

{
    "components": [
        {
            "id": "hostfw",
            "name": "hostfw",
            "group": "firmware",
            "manufacturer": "contoso",
            "model": "virtual-firmware",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/hostfw",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "bootfs",
            "name": "bootfs",
            "group": "boot-image",
            "manufacturer": "contoso",
            "model": "virtual-disk",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/bootfs",
                "firmwareDataFile": "diskimage.json",
            }
        },
        {
            "id": "rootfs",
            "name": "rootfs",
            "group": "os-image",
            "manufacturer": "contoso",
            "model": "virtual-os",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/rootfs",
                "firmwareDataFile": "diskimage.json",
            }
        },
        {
            "id": "contoso-motor-serial-00000",
            "name": "left-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "contoso-motor-serial-00001",
            "name": "right-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/1",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "contoso-motor-serial-00002",
            "name": "vacuum-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/2",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "contoso-camera-serial-00000",
            "name": "front-camera",
            "group": "cameras",
            "manufacturer": "contoso",
            "model": "virtual-camera",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/0",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "contoso-camera-serial-00001",
            "name": "rear-camera",
            "group": "cameras",
            "manufacturer": "contoso",
            "model": "virtual-camera",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/1",
                "firmwareDataFile": "firmware.json",
            }
        }
    ]
}

下一步

本文中的範例使用 C。若要探索 C++ 範例原始程式碼,請參閱:

如需各種連線至 Contoso Virtual Vacuum 裝置的元件範例更新,請參閱 Proxy 更新示範 (英文)。