征程 6E/M 快速上手實戰(zhàn) Sample-IPC
在此篇文章中,我們將深入探討 征程6X 系列核間通信(IPC-F)的基本原理,并通過示例代碼演示如何有效地使用 IPC-F 來實現 Acore 和 Rcore 之間的高效數據傳輸。無論你是剛剛接觸這個概念的新手,還是希望在 征程6X 系列上復現 IPC 例程的開發(fā)者,都可以從中獲得有價值的見解和詳細的復現流程。
一、IPC模塊簡述征程6X IPC(Inter-Process Communication)模塊是用于多核之間的通信,支持同構核和異構核之間的通信,軟件上基于 buffer-ring 進行共享內存的管理,硬件上基于 MailBox 實現核間中斷。IPCF 具有多路通道,大數據傳輸,適用多種平臺的特點。
1.1 硬件數據流說明Acore 與 MCU 通過共享內存?zhèn)鬏敂祿?,通過 mailbox 中斷通知雙方。
Acore 與 MCU 之間的核間通信,Acore 側主要使用 IPCFHAL,MCU 側使用 IPCF,其中 IPCFHAL 是基于 IPCF 封裝了一層接口,用于用戶態(tài)與內核態(tài)的數據傳遞。
#Sample源碼路徑1.3.1 API 調用流程:
test/samples/platform_samples/source/S83_Sample/S83E02_Communication/ipc_sample/
hb_ipcfhal_getchan_byjson(chan_name[i], &thread_arg[i].ch, json_path);
根據 chan_name[i]解析 ipcfhal_sample_config.json 信息配置信息放入到 thread_arg[i].ch 中。
*Sample 中配置為實例3的通道0和1,實例4的通道0和1。
##Sample板端路徑為
"/app/sample/S83_Sample/S83E02_Communication/ipc_sample/testsuite/ipcfhal_sample_config.json"
##用戶自定義的ipcfhal_sample_config.json后需要將其傳輸到單板上,并更新.cpp中SMP_CFG_FILE路徑
*客戶 Acore 與 MCU 通信可使用實例3~10,若用戶不需要 CANHAL、規(guī)控等業(yè)務,可以自行使用 CANHAL(實例0)和規(guī)控(實例1和2)的實例。
hb_ipcfhal_init(&thread_arg[i].ch);
通過配置信息 thread_arg[i].ch 打開對應的設備驅動:/dev/ipcdrv *只要有一個 channel 使用就一直打開
hb_ipcfhal_config(&thread_arg[i].ch);
使用 ioctl對/dev/ipcdrv 進行配置。
pthread_create;
每一個 channel 分別創(chuàng)建一個發(fā)送和一個接收的線程,線程中進行 IPC 讀、寫。
tx_pthread: hb_ipcfhal_send:使用 write對/dev/ipcdrv 寫入 tx_data。
rx_pthread: hb_ipcfhal_recv:使用 read 讀取/dev/ipcdrv 到 data。
hb_ipcfhal_deinit:釋放 channel,當 channel 都被釋放則關閉設備/dev/ipcdrv。
void Ipc_MDMA_Init(Ipc_InstanceConfigType *ConfigPtr, uint32 InstanceId);
1、獲取實例和通道;
2、初始化底層驅動;
3、清空MDMA回環(huán)內存;
Ipc_MDMA_OpenInstance(uint32 InstanceId);
根據實例 id 預備共享內存并打開驅動 MailBox。
Ipc_MDMA_CheckRemoteCoreReady(uint32 InstanceId);
根據實例 id 判斷共享內存是否 ready;
RecvTask: IrqCallBackSample:中斷回調方式 檢查數據的有效性(包括數據是否為空和滾動計數器的連續(xù)性),更新計數器,并通過 LogSync 打印出接受統(tǒng)計信息。
void Ipc_SamplePoll(void):poll方式 Ipc_MDMA_PollMsg:從共享內存中獲取接收到的信息。
SendTask: 根據實例和通道選擇存入 dataBuf,通過 IpcTest_MdmaSend_Func 發(fā)送 data。
Ipc_MDMA_TryGetHwResource:獲取驅動共享內存;
Ipc_MDMA_SendMsg:根據實例 id 寫入共享內存。
二、Sample 使用:2.1 Acore 側:2.1.1 編譯獲取 AppSDK 包后,進入 appuser 執(zhí)行:
*其中 hbrootfs-sdk_0.0.1.XXX_all.deb 是地平線自己的庫和頭文件,rootfs-sdk-focal_0.0.1.XXX_all.deb 是系統(tǒng)庫,aarch64-linux-hb-gcc_12.2.0_amd64.deb 是 gcc 12.2.0 工具鏈,目前在 ubuntu22.04 非 docker 環(huán)境下運行正常。其它環(huán)境不能保證。
dpkg-deb -x rootfs-sdk*.deb ./sdk
dpkg-deb -x hbrootfs-sdk*.deb ./sdk
##移動sdk庫路徑,本文檔放入/usr/lib中
sudo mv sdk/ /usr/lib
進入toolchain執(zhí)行:
dpkg -x aarch64-linux-hb-gcc_12.2.0_amd64.deb ./arm-gnu-toolchain
##移動toolchain庫路徑,本文檔放入/usr/lib中
sudo mv arm-gnu-toolchain/ /usr/lib
nano ~/.bashrc
##添加系統(tǒng)路徑
export PATH="/usr/lib/arm-gnu-toolchain/bin:$PATH"
export LD_LIBRARY_PATH="/usr/lib/arm-gnu-toolchain/lib:$LD_LIBRARY_PATH"
##
source ~/.bashrc
Sample 代碼路徑:
#Sample源碼路徑
/test/samples/platform_samples/source/S83_Sample/S83E02_Communication/ipc_sample/
復制/src 源碼(.json和.cpp)到新建文件夾 ipc 并構建新 Makefile:
ipc
├── Makefile
└── src
├── ipcfhal_sample_config.json
└── libipcfhal_sample.cpp
Makefile:
CROSS_COMPILE = aarch64-none-linux-gnu-
OUTPUT_HBROOTFS_DIR = /usr/lib/sdk ##請根據用戶sdk安裝路徑修改
CXX := ${CROSS_COMPILE}g++
INC_DIR := ${OUTPUT_HBROOTFS_DIR}/usr/hobot/include
LIB_DIR := ${OUTPUT_HBROOTFS_DIR}/usr/hobot/lib
LIB_DIR += ${OUTPUT_HBROOTFS_DIR}/usr/lib/aarch64-linux-gnu
LIBS := -lhbipcfhal -lpthread -lalog -ljsoncpp
CXXFLAGS := -Wall -O2 -I$(INC_DIR)
LDFLAGS := $(addprefix -L, $(LIB_DIR)) $(LIBS)
SRC_DIR := src
TARGET := program
SRCS := $(wildcard $(SRC_DIR)/*.cpp)
OBJS := $(SRCS:.cpp=.o)
$(TARGET): $(OBJS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $@
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
clean:
rm -f $(OBJS) $(TARGET)
執(zhí)行 make 完成編譯,生成的文件為./program
在 Linux 上交叉編譯的執(zhí)行文件需要傳輸到開發(fā)板上,本文使用共享文件夾 +WinSCP 方式進行傳輸:
將生成的可執(zhí)行文件復制到共享文件夾中: 通過串口獲取單板 ip:*可通過-6. *單板設置ip地址設置ip
打開 WinSCP 新建站點:
登錄后將 program 拖拽到/home/hobot/完成文件傳輸:
通過 ssh 或串口進入/home/hobot/執(zhí)行:
*如使用自定義 ipcfhal_sample_config.json 則需將該文件也傳輸到單板上并修改.cpp 中 SMP_CFG_FILE 為正確路徑
chmod 777 program
./program
Sample 運行時 Acore 串口日志:
root@hobot:~# /app/sample/S83_Sample/S83E02_Communication/ipc_sample/bin/libipcf_hal_sample*由于 MCU 的 Sample 需要 ETAS 支持,本文暫不涉及 M 側 Sample 的使用。
[INFO][hb_ipcf_hal.cpp:276] [channel] cpu2mcu_ins3ch0 [ins] 3 [id] 0 init success.
[INFO][hb_ipcf_hal.cpp:326] [channel] cpu2mcu_ins3ch0 [ins] 3 [id] 0 config success.
[INFO][hb_ipcf_hal.cpp:276] [channel] cpu2mcu_ins3ch1 [ins] 3 [id] 1 init success.
[INFO][hb_ipcf_hal.cpp:326] [channel] cpu2mcu_ins3ch1 [ins] 3 [id] 1 config success.
[INFO][hb_ipcf_hal.cpp:276] [channel] cpu2mcu_ins4ch0 [ins] 4 [id] 0 init success.
[INFO][hb_ipcf_hal.cpp:326] [channel] cpu2mcu_ins4ch0 [ins] 4 [id] 0 config success.
[INFO][hb_ipcf_hal.cpp:276] [channel] cpu2mcu_ins4ch1 [ins] 4 [id] 1 init success.
[INFO][hb_ipcf_hal.cpp:326] [channel] cpu2mcu_ins4ch1 [ins] 4 [id] 1 config success.
Ins[3]Ch[0] TxCnt[100]TxFailCnt[0] -------
Ins[3]Ch[1] TxCnt[100]TxFailCnt[0] -------
Ins[4]Ch[0] TxCnt[100]TxFailCnt[0] -------
Ins[4]Ch[1] TxCnt[100]TxFailCnt[0] -------
Ins[3]Ch[0] ------- RxCnt[100]RxRollCnt[100]
Ins[4]Ch[0] ------- RxCnt[100]RxRollCnt[100]
Ins[3]Ch[1] ------- RxCnt[100]RxRollCnt[100]
Ins[4]Ch[1] ------- RxCnt[100]RxRollCnt[100]
Ins[3]Ch[0] TxCnt[200]TxFailCnt[0] -------
Ins[3]Ch[1] TxCnt[200]TxFailCnt[0] -------
Ins[4]Ch[0] TxCnt[200]TxFailCnt[0] -------
Ins[4]Ch[1] TxCnt[200]TxFailCnt[0] -------
Ins[3]Ch[0] ------- RxCnt[200]RxRollCnt[200]
Ins[4]Ch[0] ------- RxCnt[200]RxRollCnt[200]
Ins[3]Ch[1] ------- RxCnt[200]RxRollCnt[200]
Ins[4]Ch[1] ------- RxCnt[200]RxRollCnt[200]
Ins[3]Ch[0] TxCnt[300]TxFailCnt[0] -------
Ins[3]Ch[1] TxCnt[300]TxFailCnt[0] -------
Ins[4]Ch[0] TxCnt[300]TxFailCnt[0] -------
Ins[4]Ch[1] TxCnt[300]TxFailCnt[0] -------
Ins[3]Ch[0] ------- RxCnt[300]RxRollCnt[300]
Ins[4]Ch[0] ------- RxCnt[300]RxRollCnt[300]
Ins[3]Ch[1] ------- RxCnt[300]RxRollCnt[300]
Ins[4]Ch[1] ------- RxCnt[300]RxRollCnt[300]
Ins[3]Ch[0] ------- RxCnt[400]RxRollCnt[400]
Ins[4]Ch[0] ------- RxCnt[400]RxRollCnt[400]
Ins[3]Ch[1] ------- RxCnt[400]RxRollCnt[400]
Ins[4]Ch[1] ------- RxCnt[400]RxRollCnt[400]
Ins[3]Ch[0] TxCnt[400]TxFailCnt[0] -------
Ins[3]Ch[1] TxCnt[400]TxFailCnt[0] -------
Ins[4]Ch[1] TxCnt[400]TxFailCnt[0] -------
Ins[4]Ch[0] TxCnt[400]TxFailCnt[0] -------
Ins[3]Ch[0] ------- RxCnt[500]RxRollCnt[500]
Ins[4]Ch[0] ------- RxCnt[500]RxRollCnt[500]
Ins[3]Ch[1] ------- RxCnt[500]RxRollCnt[500]
Ins[4]Ch[1] ------- RxCnt[500]RxRollCnt[500]
Ins[3]Ch[0] TxCnt[500]TxFailCnt[0] -------
Ins[3]Ch[1] TxCnt[500]TxFailCnt[0] -------
Ins[4]Ch[1] TxCnt[500]TxFailCnt[0] -------
Ins[4]Ch[0] TxCnt[500]TxFailCnt[0] -------
Ins[3]Ch[0] ------- RxCnt[600]RxRollCnt[600]
Ins[4]Ch[0] ------- RxCnt[600]RxRollCnt[600]
Ins[3]Ch[1] ------- RxCnt[600]RxRollCnt[600]
Ins[4]Ch[1] ------- RxCnt[600]RxRollCnt[600]
Ins[3]Ch[1] TxCnt[600]TxFailCnt[0] -------
Ins[3]Ch[0] TxCnt[600]TxFailCnt[0] -------
Ins[4]Ch[1] TxCnt[600]TxFailCnt[0] -------
Ins[4]Ch[0] TxCnt[600]TxFailCnt[0] -------
Ins[3]Ch[0] ------- RxCnt[700]RxRollCnt[700]
Ins[4]Ch[0] ------- RxCnt[700]RxRollCnt[700]
Ins[3]Ch[1] ------- RxCnt[700]RxRollCnt[700]
Ins[4]Ch[1] ------- RxCnt[700]RxRollCnt[700]
Ins[3]Ch[1] TxCnt[700]TxFailCnt[0] -------
Ins[3]Ch[0] TxCnt[700]TxFailCnt[0] -------
Ins[4]Ch[1] TxCnt[700]TxFailCnt[0] -------
Ins[4]Ch[0] TxCnt[700]TxFailCnt[0] -------
Ins[3]Ch[0] ------- RxCnt[800]RxRollCnt[800]
Ins[4]Ch[0] ------- RxCnt[800]RxRollCnt[800]
Ins[3]Ch[1] ------- RxCnt[800]RxRollCnt[800]
Ins[4]Ch[1] ------- RxCnt[800]RxRollCnt[800]
Ins[3]Ch[1] TxCnt[800]TxFailCnt[0] -------
Ins[3]Ch[0] TxCnt[800]TxFailCnt[0] -------
Ins[4]Ch[1] TxCnt[800]TxFailCnt[0] -------
Ins[4]Ch[0] TxCnt[800]TxFailCnt[0] -------
Ins[3]Ch[0] ------- RxCnt[900]RxRollCnt[900]
Ins[4]Ch[0] ------- RxCnt[900]RxRollCnt[900]
Ins[3]Ch[1] ------- RxCnt[900]RxRollCnt[900]
Ins[4]Ch[1] ------- RxCnt[900]RxRollCnt[900]
Ins[3]Ch[1] TxCnt[900]TxFailCnt[0] -------
Ins[3]Ch[0] TxCnt[900]TxFailCnt[0] -------
Ins[4]Ch[1] TxCnt[900]TxFailCnt[0] -------
Ins[4]Ch[0] TxCnt[900]TxFailCnt[0] -------
[SampleEnd]Ins[3]Ch[0]TxCnt[994]TxFailCnt[0][SampleEnd]Ins[3]Ch[0]RxCnt[996]RxRollCnt[996][INFO][hb_ipcf_hal.cpp:521] [channel] cpu2mcu_ins3ch0 [ins] 3 [id] 0 deinit success.
[SampleEnd]Ins[3]Ch[1]TxCnt[995]TxFailCnt[0][SampleEnd]Ins[3]Ch[1]RxCnt[997]RxRollCnt[997][INFO][hb_ipcf_hal.cpp:521] [channel] cpu2mcu_ins3ch1 [ins] 3 [id] 1 deinit success.
[SampleEnd]Ins[4]Ch[0]TxCnt[996]TxFailCnt[0][SampleEnd]Ins[4]Ch[0]RxCnt[998]RxRollCnt[998][INFO][hb_ipcf_hal.cpp:521] [channel] cpu2mcu_ins4ch0 [ins] 4 [id] 0 deinit success.
[SampleEnd]Ins[4]Ch[1]TxCnt[997]TxFailCnt[0][SampleEnd]Ins[4]Ch[1]RxCnt[999]RxRollCnt[999][INFO][hb_ipcf_hal.cpp:521] [channel] cpu2mcu_ins4ch1 [ins] 4 [id] 1 deinit success.
*博客內容為網友個人發(fā)布,僅代表博主個人觀點,如有侵權請聯(lián)系工作人員刪除。