在 NXP i.MX 95 上運行 Zephyr 實現非對稱多核處理
概要
盡管大多數嵌入式軟件應用針對單一微處理器或微控制器開發,但在某些特定場景下需要采用分布式架構。以汽車行業為例,不同子系統可能作為獨立應用程序部署在分離的處理器上,例如負責發動機控制系統的嵌入式軟件與防抱死制動系統應用就分別運行在不同的微控制器上。
醫療器械行業是嵌入式軟件分布于多個微處理器的另一典型案例。例如,用戶界面由一個微處理器實現,而負責患者交互的控制系統則位于另一個微控制器上。
可以看出,職責是根據功能劃分的,而處理器則根據職責進行選擇。例如,用戶界面通常在基于 Linux 的系統上實現,這類系統專為類似 ARM Cortex-A 內核的處理器設計;而關鍵的嵌入式軟件應用則采用實時操作系統(RTOS),這種系統最適合類似 ARM Cortex-R 或 Cortex-M 內核的處理器。
然而,若采用多處理器架構,處理器間的通信便至關重要。例如汽車行業就通過 CAN 總線實現這一功能。在醫療設備領域,各處理器可采用 UART、SPI 或 I2C 等通信協議進行交互,如下圖所示:
然而,多個處理器分布在不同的芯片上會增加底層硬件、軟件和固件的復雜性。這進而可能導致額外的開發和調試工作,從而影響產品的時間線和成本。
為了應對這種額外的復雜性,我們可以將多個處理器集成到同一塊芯片上,如下圖所示:
在上圖中,ARM Cortex-A 和 ARM Cortex-M 內核被集成在同一塊芯片上,稱為系統級芯片(SoC)。SoC 將 CPU 內核與其他必要的控制器相結合,形成一個功能全面且強大的處理器。如圖中顯示,嵌入式軟件的功能安全(FuSa)部分通過 Zephyr Project 實時操作系統在 ARM Cortex-M 內核上實現,而圖形用戶界面(GUI)則在 ARM Cortex-A 內核的 Linux 系統中運行。
該設計大幅縮短了硬件開發與調試時間。無需再管理多個獨立處理器及電氣和機械硬件互聯,問題簡化為圍繞單個處理器的硬件設計。挑戰也就主要轉移到固件和軟件層面,因為每個內核的嵌入式軟件需要與其他內核的嵌入式軟件建立通信機制。
在這篇博客文章中,我們將學習如何從運行于 ARM Cortex-A 核心的 Linux 內核加載運行于 ARM Cortex-M 核心上的固件。我們將以 Toradex Verdin iMX95 模塊為例演示具體實現方法。
OpenAMP項目
Open Asymmetric Multi-Processing(OpenAMP)項目的設立旨在實現同一片上系統內不同核心之間的高效通信。該項目基于德州儀器早期將 Remoteproc 和 RPMsg 納入 Linux 內核的工作成果發展而來:Remoteproc 使 Linux 內核能夠管理遠端處理器(remote processor)上的嵌入式軟件生命周期,而 RPMsg 則實現了 Linux 內核與遠端處理器固件間的通信。OpenAMP 項目將德州儀器的專有實現方法擴展為適用于各類系統的通用框架,標準化了 Linux 內核與基于實時操作系統(RTOS)的嵌入式應用間通信協議,并為希望利用其功能特性(如 RPMsg)的 RTOS 及裸機嵌入式應用提供了參考實現方案。
如前所述,Remoteproc 和 RPMsg 是 OpenAMP 項目的兩大核心功能,它們使我們能夠管理運行在同一 SoC 不同內核上的嵌入式軟件。Remoteproc 負責將固件加載到遠程處理器上,并啟動和停止遠程處理器的執行。在 Linux 系統中,Remoteproc 通常用于管理運行在 Cortex-M 等類似內核上的嵌入式軟件生命周期。而 RPMsg 則負責支持運行在 Cortex-M 內核的嵌入式軟件與運行 Cortex-A 內核的 Linux 系統之間的消息交換。
Toradex Verdin iMX95
Toradex Verdin iMX95 是一款基于 NXP iMX95 SoC 的高性能模塊(SoM)。如下圖所示,iMX95 SoC 包含三種不同類型的 ARM 核心架構:
ARM Cortex-A55 運行 Linux 操作系統,ARM Cortex-M7 負責執行實時固件,而 ARM Cortex-M33 則管理 Cortex-A55 和 Cortex-M7 的運行。
Zephyr Project RTOS
盡管“實時操作系統”是 Zephyr 項目 RTOS 的官方名稱,但 “Zephyr” 遠不止是一個 RTOS。它是一個完整的生態系統。雖然它確實包含了 RTOS 的典型功能和數據結構,如任務、信號量、互斥鎖和消息隊列,但它還擁有負責嵌入式系統其他重要功能的軟件棧。例如,它包括:
用于控制和操作廠商特定硬件的驅動程序實現完整通信協議棧的軟件,例如藍牙低功耗(BLE)和WiFi實現整個子系統的模塊,例如文件系統和引導加載程序
Zephyr 還支持來自眾多廠商的 750 多款開發板,包括 Toradex Verdin iMX95。如果我們下載 Zephyr 代碼庫,可以看到在 boards/nxp/imx95_evk 目錄下提供了對 iMX95 EVK 的支持,如下圖所示:
Zephyr 借鑒了 Linux 內核的 Kconfig 和 Devicetree 功能,我們可以在上圖中看到這一點。上圖所示的 iMX95 EVK “device driver” 包含:
“board.c”, 負責初始板卡啟動的C源代碼“imx95_evk_mimx9596_m7.dts”, 用于告知 Zephyr 該板卡上存在哪些外設的 Devicetree 文件“Kconfig.imx95_evk”, 需要啟用支持該板卡關鍵功能的 Kconfig 的選項集合
例如,如果我們打開“Kconfig.imx95_evk”文件(如下圖所示),可以看到它啟用了 iMX95 SoC 的 Kconfig 選項。該 Kconfg 選項隨后會啟用 SoC 所需的其他功能:
例如,Verdin iMX95的“device driver”位于 soc/nxp/imx/imx9/imx95 目錄下,如下圖所示:
同樣的,“soc.c” 是負責初始 SoC 啟動的 C 源代碼,通過分析設備樹中的相應節點,我們可以發現該 SoC 的 Kconfig 文件定義了 Flash 大小。
整合所有步驟
讓我們演示如何為 iMX95 編譯 Zephyr 應用程序,并從同一開發板上運行的 Cortex-A 內核加載 Zephyr 應用程序到 Cortex-M 內核。首先,我們可以按照 Zephyr入門指南(https://docs.zephyrproject.org/latest/develop/getting_started/index.html)中的步驟確保環境配置正確。
然后執行以下命令使用 West 工具獲取 Zephyr 源代碼:
$> west init -m https://github.com/mabembedded/zephyr.git $> west update
之后,我們可以執行以下命令為 Verdin iMX95 編譯一個簡單的“Hello World”應用程序:
$> west build -p -b imx95_evk/mimx9596/m7 samples/hello_world
然后,我們可以通過執行以下命令(確保將下方列出的 IP 地址替換為我們開發板的實際地址),將編譯好的 ELF 格式二進制文件傳輸至運行在 iMX95 Cortex-A 內核上的 Linux 系統:
$> scp build/zephyr/zephyr.elf root@10.10.2.22:~/
隨后,如果我們登錄到 iMX95 設備,可以運行以下命令來指示 Linux 將 Zephyr ELF 二進制文件加載至 Verdin iMX95 的 Cortex-M7 核心上:
root@imx95-19x19-verdin:~# cd /sys/devices/platform/imx95-cm7/remoteproc/remoteproc1/ root@imx95-19x19-verdin:~# echo ~/zephyr.elf > firmware
最后,我們可以在 iMX95 Linux 控制臺中輸入以下命令來啟動 Cortex-M7 核心:
root@imx95-19x19-verdin:~# echo start > state
我們可以在 iMX95 的 Cortex-M7 控制臺上看到以下內容:
上述示例展示了 Linux 內核中 OpenAMP 項目的 Remoteproc 功能。
我們還可以通過如下所示的 openamp_rsc_table 示例應用程序,了解 Zephyr 中的 RPMsg 功能:
如上圖所示,“imx95_evk_mimx9596_m7.conf” 包含了該應用啟用的 Kconfig 選項。下圖可見,此文件已啟用相關的 OpenAmp 和 Mbox Kconfig 配置項:
該目錄還包含一個 Devicetree “overlay”,用于為此特定應用定制開發板的 Devicetree。如下圖所示,此覆蓋層定義了 RPMsg 應用所需的功能,并引用了特定的硬件組件:
這些特性包括:
各個核心間用于交換數據的共享內存Linux內核通過資源表來識別遠程處理器及固件支持的功能雙核通信使用的郵箱機制
接下來演示如何編譯并運行 RPMsg Zephyr 應用程序。首先執行以下命令進行編譯:
$> west build -p -b imx95_evk/mimx9596/m7 samples/subsys/ipc/openamp_rsc_table
隨后,我們可以按照之前概述的步驟將生成的 ELF 二進制文件從 Cortex-A55 上的 Linux 系統傳輸并加載到 Cortex-M7 中。在從 Linux 端啟動 Cortex-M7 后,我們將在 Cortex-M7 的控制臺上看到以下內容,這展示了從 Linux 端接收到的消息:
同樣,如果觀察 Cortex-A55 端的 Linux 內核日志,我們也能看到它通過 RPMsg 接收到了來自 Cortex-M7 上 Zephyr 應用程序的消息,如下所示:
總結
在本篇博客中,我們了解了利用 OpenAMP 項目特性簡化嵌入式系統硬件設計的優勢。探討了 Toradex Verdin iMX95 開發板如何通過 SoC 上不同的 ARM 內核實現創新應用場景。實踐演示了使用 Zephyr 實時操作系統快速構建 "Hello World" 示例程序,并從運行于 Cortex-A55 的 Linux 系統加載至 Verdin iMX95 的Cortex-M7 核心的全過程。最后,我們還完成了基于 RPMsg 協議的 Zephyr 應用程序編譯、從 Linux 環境加載以及驗證 Zephyr 與 Linux 之間消息交互的實驗。

提交
HDMI 顯示器熱插拔對應顯示應用啟停測試
Yocto meta-toradex-security layer 創建加密數據分區應用說明
NXP iMX8MP ARM 平臺多屏幕克隆顯示測試
Yocto meta-toradex-security layer 創建獨立數據分區
NXP iMX8MP ARM 平臺 EMQX 部署測試