向裝置更新註冊元件
本文示範 IoT 中樞元件列舉程式的裝置更新實作。 您可以參考此範例,為自己的 IoT 裝置實作自訂元件列舉程式。 「元件」是裝置層級下方的身分識別,與主機裝置具有組合關聯性。
本文示範使用稱為 Contoso Virtual Vacuum 之虛擬 IoT 裝置的元件列舉程式。 元件列舉程式可用來實作「Proxy 更新」功能。
Proxy 更新可讓您更新同一 IoT 裝置上的多個元件,或是透過單一無線部署連線到 IoT 裝置的多個感應器。 Proxy 更新支援更新元件的安裝順序, 也支援使用預先安裝、安裝、後續安裝功能執行多步驟更新。
Proxy 更新適用的使用案例包含:
- 將特定更新檔案的目標設為裝置上的分割區。
- 將特定更新檔案的目標設為裝置上的應用程式或元件。
- 將特定更新檔案的目標設為透過網路通訊協定 (例如 USB 或 CAN 匯流排) 連線到 IoT 裝置的感應器。
如需詳細資訊,請參閱 Proxy 更新和多元件更新。
裝置更新代理程式會在主機裝置上執行。 可將每項更新傳送至特定元件或屬於相同硬體類別的一組元件 (也就是要求相同的軟體或韌體更新)。
什麼是元件列舉程式?
元件列舉程式是裝置更新代理程式的延伸模組,可針對透過主機裝置的 Azure IoT 中樞連線進行無線更新所需的每項元件提供相關資訊。
裝置更新代理程式不受裝置和元件的限制。 此代理程式本身對更新時在主機裝置上 (或連線至主機裝置) 的元件一無所知。
若要啟用 Proxy 更新,裝置建置者必須識別可更新裝置上的所有元件,並為每個元件指派唯一名稱。 此外,也可以為屬於相同硬體類別的元件指派群組名稱,這樣就能替同一群組中所有元件安裝一樣的更新, 然後,更新內容處理常式就可以將更新安裝並套用至正確的元件。
以下是 Proxy 更新流程中每個部分的職責:
裝置建置者
設計和建置裝置。
整合裝置更新代理程式及其相依性。
實作裝置特定元件列舉程式延伸模組,並向裝置更新代理程式註冊。
元件列舉程式會使用元件詳細目錄或設定檔中的資訊,以動態資料 (例如韌體版本、連線狀態、硬體身分識別) 增加靜態元件資料 (需要裝置更新)。
建立 Proxy 更新,其中包含一或多項將目標設為裝置上 (或連線至裝置的) 一或多個元件的子系更新。
將此更新傳送給解決方案操作員。
解決方案操作員
將更新和資訊清單匯入裝置更新服務。
將更新部署至一組裝置。
裝置更新代理程式
透過裝置對應項或模組對應項從 IoT 中樞取得更新資訊。
叫用「步驟處理常式」,用於處理裝置上一或多個元件專屬的 Proxy 更新。
本文中的範例有兩項更新:
host-fw-1.1
與motors-fw-1.1
。 針對每項子系更新,父代步驟處理常式會叫用子系步驟處理常式,以列舉符合子系更新資訊清單檔中指定Compatibilities
屬性的所有元件。 接下來,處理常式會下載子系更新,並將其安裝及套用至所有目標元件。為了取得相符元件,子系更新會呼叫元件列舉程式所提供的
SelectComponents
API, 如果沒有相符的元件,則會略過子系更新。從父代和子系更新收集所有更新結果,然後將結果回報給 IoT 中樞。
子系步驟處理常式
- 逐一查看與子系更新內容相容的元件執行個體清單。 如需詳細資訊,請參閱步驟處理常式 (英文)。
在生產環境中,裝置建立器可以使用現有處理常式 (英文),或實作自訂處理常式,以叫用無線更新所需的任何安裝程式。 如需詳細資訊,請參閱實作自訂更新內容處理常式 (英文)。
Virtual Vacuum 元件
在本文中,我們會使用虛擬 IoT 裝置來示範重要概念和功能。 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) |
先前由 GetAllComponents 或 SelectComponents 函式傳回的字串緩衝區指標 |
無 |
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 檔案讀取裝置特定元件的資訊。 此實作範例僅供示範用。
在生產案例中,部分屬性應該直接從實際元件擷取, 包括 id
、manufacturer
、model
。
裝置建立器會定義 name
與 group
屬性。 這些值一經定義就絕不會再變更。 在裝置內 name
必須為唯一屬性。
component-inventory.json 檔案範例
注意
此檔案中的內容與 GetAllComponents
函式的傳回值幾乎相同, 但此檔案內的 ComponentInfo
不包含 version
與 status
屬性。 元件列舉程式會在執行階段填入這些屬性。
以「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 更新示範 (英文)。