一. 簡介
RPMsg(Remote Processor Messaging)是一種在 AMP(Asymmetric Multiprocessing)架構系統中的通信協議。透過共享內存區域(Shared Memory)來傳輸消息,使不同的核心運行不同的作業系統或應用程序,並利用各個核心的優勢來滿足不同應用場景的需求。
本文將介紹我們在 i.MX8M Plus 平台上使用 Linux 5.15.71 BSP 實現的範例,功能是在系統尚未完全開機時的訊號控制。在開機過程中,A53 核心會執行多項任務並處於忙碌狀態,但此時又想要再增加其他任務,例如周邊信號控制的話,就可以利用多核心架構的特性及 RPMsg 的功能,讓 M7 核心來執行這些任務或信號控制,充分發揮 SOC 的效能來完成各項任務。
如下圖所示,本文以 GPIO 信號控制 LED 燈為例。當 A53 還在開機過程中,M7 核心就會先對 GPIO 進行信號控制。而在開機完成後,M7 核心會停止控制 GPIO 信號輸出,交由使用者輸入特定指令字串,讓 A53 核心透過 RPMsg 與 M7 核心溝通,以控制 GPIO 輸出信號。
二. 系統流程
如上一節所說,本文是以 GPIO 信號控制 LED 為範例,介紹如何透過 RPMsg 功能完成在系統尚未完全開機時的訊號控制。
首先說明系統的架構與程式運作流程:
- 系統上電。
- 啟動 U-boot。
- 啟動 M7 核心程式,並開始控制 GPIO 持續送出 High / Low 訊號。
- M 核等待 RPMsg Setup,並持續控制 GPIO 送出 High / Low 訊號。
- Kernel 啟動。
- RPMsg 驅動 Ready 與 M7 核心 Link。
- RPMsg Link 後,等待 Kernel Ready,並持續控制 GPIO 送出 High / Low 訊號。
- Kernel Driver 會透過 RPMsg 發送軟體訊號通知 M7 核心端程式。
- 當 M7 核心接收到 Kernel Ready 字串後,便會停止 GPIO 控制。
- M7 核心等待 A53 核心發送特定指令字串。
- A53 核心開機完成。
- 透過 A53 核心傳送特定指令字串給 M7 核心,使 M7 核心控制 GPIO 腳位訊號。
三. M7 核心端軟體
在此將介紹如何修改 M7 核心端程式。
1. 添加程式
2. 編譯專案
# 設定環境變數
$ export ARMGCC_DIR=~/toolchains/arm-gnu-toolchain-12.2.mpacbti-rel1-x86_64-arm-none-eabi
# 編譯
$ ./build_debug.sh
等待編譯:
編譯完成後,debug 目錄下會產生 rpmsg_lite_wpi_rpmsg_gpio_linux_remote.bin 檔:
四. A 核心端軟體
在此將介紹如何修改 A53 核心端程式。
1. Device Tree 修改
本文因為 GPIO5_IO11 的 Pin 腳在公板上比較好量測訊號,所以選擇其進行訊號控制。
參考 imx8mp-evk-rpmsg.dts 進行修改,先關閉 ECSPI2 Node,將 GPIO5_IO11 設定為 GPIO 功能並添加 wpi_rpmsg_gpio 驅動等相關描述:
imx8mp-evk-rpmsg-gpio.dts
gpio_rpmsg:gpio_rpmsg {
compatible = "fsl,wpi_prmsg_gpio";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio_rpmsg>;
rpmsggpio = <&gpio5 11 GPIO_ACTIVE_LOW>;
status = "okay";
};
&ecspi2 {
status = "disabled";
};
2. Kernel Driver 新增
將 wpi_rpmsg_gpio.c 複製至 git/drivers/rpmsg 下:
3. Makefile 中增加 imx_rpmsg_gpio.o:
MakeFile
obj-$(CONFIG_IMX_RPMSG_PINGPONG) += imx_rpmsg_pingpong.o
obj-$(CONFIG_IMX_RPMSG_WAKEUP_A53) += imx_rpmsg_wakeup_a53.o
obj-$(CONFIG_IMX_RPMSG_TTY) += imx_rpmsg_tty.o
+obj-y += wpi_rpmsg_gpio.o
# 單獨編譯 Kernel
$ bitbake linux-imx -f -c compile ; bitbake linux-imx -f -c deploy
等待編譯:
五. 燒錄
將 Kernel、Device Tree 與 rpmsg_lite_wpi_rpmsg_gpio_linux_remote.bin 複製至 boot 下:
六. 執行
完成上述幾個小節的程式修改及準備後,我們就可以來執行看看程式。
首先準備 A53 與 M7 兩個核心的 Console:
接著,將公板上電開機並進入 U-Boot 模式,執行以下指令讓 M7 啟動程式:
# 切換 Device Tree
$ setenv fdtfile imx8mp-evk-rpmsg-gpio.dtb
# 讓 M7 核心啟動程式
$ fatload mmc 1:1 0x48000000 rpmsg_lite_wpi_rpmsg_gpio_linux_remote.bin ; cp.b 0x48000000 0x7e0000 20000 ; bootaux 0x7e0000
# 開機
$ boot
隨後系統便會繼續開機,過程中,M7 核心會持續控制 GPIO5_IO11 的 High / Low,並等待 A53 核心端是否 Link RPMsg 及發送 Kernel Ready 訊號:
當 M7 核心端收到 Kernel Ready 後,便會停止控制 GPIO5_IO11,並等待 A53 核心發送特定指令字串:
最後,當 A53 核心系統開機完成後,使用者就可以由 A53 核心的 Console 輸入特定指令字串,讓 M7 核心控制 GPIO5_IO11 輸出訊號:
# 透過 M7 核心使用 GPIO5_IO11 發送 High Low High 訊號
$ echo m7_gpio_101 > /dev/ttyRPMSG30
# 透過 M7 核心使用 GPIO5_IO11 發送 High 訊號
$ echo m7_gpio_High > /dev/ttyRPMSG30
# 透過 M7 核心使用 GPIO5_IO11 發送 Low 訊號
# echo m7_gpio_Low > /dev/ttyRPMSG30
七. 結論
透過本文我們驗證了 M7 端程式,可以在開機時事先對 GPIO 進行訊號控制,當 A53 端開機完成後,同樣也可以透過 RPMsg 使 M7 端進行訊號控制,例如輸入 “echo m7_gpio_Low > /dev/ttyRPMSG30”命令,就能夠使 M7 核心控制 GPIO 輸出 Low 訊號。藉由本文的範例可以運用在許多系統尚未開機完成時,要快速啟動某硬體或周邊信號控制的需求上,來完成更為複雜的系統開發。
最後,本文所介紹的範例內容及步驟,讀者可以根據不同的情境需求做相對應的修改。
Reference
https://www.toradex.com/zh-cn/blog/nxp-imx8-m4he-xinfreertos-rpmsg-ying-yong-shi-li
https://blog.csdn.net/weixin_44410537/article/details/86601694
ATU Support
- 博文內容均由個人提供,與平台無關,如有違法或侵權,請與網站管理員聯繫。
- 文明上網,請理性發言。內容一周內被舉報5次,發文人進小黑屋喔。
評論