博客專欄

EEPW首頁(yè) > 博客 > 征程 6E/M 快速上手實(shí)戰(zhàn) Sample-IPC

征程 6E/M 快速上手實(shí)戰(zhàn) Sample-IPC

發(fā)布人:地平線開發(fā)者 時(shí)間:2024-09-11 來(lái)源:工程師 發(fā)布文章
關(guān)于本文

在此篇文章中,我們將深入探討 征程6X 系列核間通信(IPC-F)的基本原理,并通過(guò)示例代碼演示如何有效地使用 IPC-F 來(lái)實(shí)現(xiàn) Acore 和 Rcore 之間的高效數(shù)據(jù)傳輸。無(wú)論你是剛剛接觸這個(gè)概念的新手,還是希望在 征程6X 系列上復(fù)現(xiàn) IPC 例程的開發(fā)者,都可以從中獲得有價(jià)值的見解和詳細(xì)的復(fù)現(xiàn)流程。

一、IPC模塊簡(jiǎn)述

征程6X IPC(Inter-Process Communication)模塊是用于多核之間的通信,支持同構(gòu)核和異構(gòu)核之間的通信,軟件上基于 buffer-ring 進(jìn)行共享內(nèi)存的管理,硬件上基于 MailBox 實(shí)現(xiàn)核間中斷。IPCF 具有多路通道,大數(shù)據(jù)傳輸,適用多種平臺(tái)的特點(diǎn)。

1.1 硬件數(shù)據(jù)流說(shuō)明

Acore 與 MCU 通過(guò)共享內(nèi)存?zhèn)鬏敂?shù)據(jù),通過(guò) mailbox 中斷通知雙方。 在這里插入圖片描述

1.2 IPC Sample 軟件架構(gòu)

Acore 與 MCU 之間的核間通信,Acore 側(cè)主要使用 IPCFHAL,MCU 側(cè)使用 IPCF,其中 IPCFHAL 是基于 IPCF 封裝了一層接口,用于用戶態(tài)與內(nèi)核態(tài)的數(shù)據(jù)傳遞。 在這里插入圖片描述

1.3 Acore-IPC-Sample:
#Sample源碼路徑
test/samples/platform_samples/source/S83_Sample/S83E02_Communication/ipc_sample/
1.3.1 API 調(diào)用流程:

在這里插入圖片描述

1.3.2 Sample 源碼解析:

在這里插入圖片描述 hb_ipcfhal_getchan_byjson(chan_name[i], &thread_arg[i].ch, json_path);

根據(jù) chan_name[i]解析 ipcfhal_sample_config.json 信息配置信息放入到 thread_arg[i].ch 中。

*Sample 中配置為實(shí)例3的通道0和1,實(shí)例4的通道0和1。

##Sample板端路徑為
"/app/sample/S83_Sample/S83E02_Communication/ipc_sample/testsuite/ipcfhal_sample_config.json"
##用戶自定義的ipcfhal_sample_config.json后需要將其傳輸?shù)絾伟迳?,并更?cpp中SMP_CFG_FILE路徑

*客戶 Acore 與 MCU 通信可使用實(shí)例3~10,若用戶不需要 CANHAL、規(guī)控等業(yè)務(wù),可以自行使用 CANHAL(實(shí)例0)和規(guī)控(實(shí)例1和2)的實(shí)例。

hb_ipcfhal_init(&thread_arg[i].ch);

通過(guò)配置信息 thread_arg[i].ch 打開對(duì)應(yīng)的設(shè)備驅(qū)動(dòng):/dev/ipcdrv *只要有一個(gè) channel 使用就一直打開

hb_ipcfhal_config(&thread_arg[i].ch);

使用 ioctl對(duì)/dev/ipcdrv 進(jìn)行配置。

pthread_create;

每一個(gè) channel 分別創(chuàng)建一個(gè)發(fā)送和一個(gè)接收的線程,線程中進(jìn)行 IPC 讀、寫。

tx_pthread: 在這里插入圖片描述 hb_ipcfhal_send:使用 write對(duì)/dev/ipcdrv 寫入 tx_data。

rx_pthread: 在這里插入圖片描述 hb_ipcfhal_recv:使用 read 讀取/dev/ipcdrv 到 data。 在這里插入圖片描述 hb_ipcfhal_deinit:釋放 channel,當(dāng) channel 都被釋放則關(guān)閉設(shè)備/dev/ipcdrv。

1.4 MCU-IPC-Sample:1.4.1 運(yùn)行流程:

在這里插入圖片描述 在這里插入圖片描述

1.4.2 Sample 源碼解析:

void Ipc_MDMA_Init(Ipc_InstanceConfigType *ConfigPtr, uint32 InstanceId);

1、獲取實(shí)例和通道;

2、初始化底層驅(qū)動(dòng);

3、清空MDMA回環(huán)內(nèi)存;

Ipc_MDMA_OpenInstance(uint32 InstanceId);

根據(jù)實(shí)例 id 預(yù)備共享內(nèi)存并打開驅(qū)動(dòng) MailBox。

Ipc_MDMA_CheckRemoteCoreReady(uint32 InstanceId);

根據(jù)實(shí)例 id 判斷共享內(nèi)存是否 ready;

RecvTask: IrqCallBackSample:中斷回調(diào)方式 在這里插入圖片描述 檢查數(shù)據(jù)的有效性(包括數(shù)據(jù)是否為空和滾動(dòng)計(jì)數(shù)器的連續(xù)性),更新計(jì)數(shù)器,并通過(guò) LogSync 打印出接受統(tǒng)計(jì)信息。

void Ipc_SamplePoll(void):poll方式 在這里插入圖片描述 Ipc_MDMA_PollMsg:從共享內(nèi)存中獲取接收到的信息。

SendTask: 在這里插入圖片描述 根據(jù)實(shí)例和通道選擇存入 dataBuf,通過(guò) IpcTest_MdmaSend_Func 發(fā)送 data。 在這里插入圖片描述 Ipc_MDMA_TryGetHwResource:獲取驅(qū)動(dòng)共享內(nèi)存;

Ipc_MDMA_SendMsg:根據(jù)實(shí)例 id 寫入共享內(nèi)存。

二、Sample 使用:2.1 Acore 側(cè):2.1.1 編譯

獲取 AppSDK 包后,進(jìn)入 appuser 執(zhí)行:

*其中 hbrootfs-sdk_0.0.1.XXX_all.deb 是地平線自己的庫(kù)和頭文件,rootfs-sdk-focal_0.0.1.XXX_all.deb 是系統(tǒng)庫(kù),aarch64-linux-hb-gcc_12.2.0_amd64.deb 是 gcc 12.2.0 工具鏈,目前在 ubuntu22.04 非 docker 環(huán)境下運(yùn)行正常。其它環(huán)境不能保證。

dpkg-deb -x rootfs-sdk*.deb ./sdk
dpkg-deb -x hbrootfs-sdk*.deb ./sdk
##移動(dòng)sdk庫(kù)路徑,本文檔放入/usr/lib中
sudo mv sdk/ /usr/lib

進(jìn)入toolchain執(zhí)行:

dpkg -x aarch64-linux-hb-gcc_12.2.0_amd64.deb ./arm-gnu-toolchain
##移動(dòng)toolchain庫(kù)路徑,本文檔放入/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/

復(fù)制/src 源碼(.json和.cpp)到新建文件夾 ipc 并構(gòu)建新 Makefile:

ipc
├── Makefile
└── src
   ├── ipcfhal_sample_config.json
   └── libipcfhal_sample.cpp

Makefile:

CROSS_COMPILE = aarch64-none-linux-gnu-
OUTPUT_HBROOTFS_DIR = /usr/lib/sdk ##請(qǐng)根據(jù)用戶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 在這里插入圖片描述

2.1.2 文件傳輸

在 Linux 上交叉編譯的執(zhí)行文件需要傳輸?shù)介_發(fā)板上,本文使用共享文件夾 +WinSCP 方式進(jìn)行傳輸:

將生成的可執(zhí)行文件復(fù)制到共享文件夾中: 在這里插入圖片描述 通過(guò)串口獲取單板 ip:*可通過(guò)地平線開發(fā)者社區(qū)-6. *單板設(shè)置ip地址設(shè)置ip 在這里插入圖片描述 打開 WinSCP 新建站點(diǎn):

在這里插入圖片描述 登錄后將 program 拖拽到/home/hobot/完成文件傳輸: 在這里插入圖片描述

2.1.3 運(yùn)行

通過(guò) ssh 或串口進(jìn)入/home/hobot/執(zhí)行:

*如使用自定義 ipcfhal_sample_config.json 則需將該文件也傳輸?shù)絾伟迳喜⑿薷?cpp 中 SMP_CFG_FILE 為正確路徑

chmod 777 program
./program

Sample 運(yùn)行時(shí) Acore 串口日志:

root@hobot:~# /app/sample/S83_Sample/S83E02_Communication/ipc_sample/bin/libipcf_hal_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.
*由于 MCU 的 Sample 需要 ETAS 支持,本文暫不涉及 M 側(cè) Sample 的使用。



*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



關(guān)鍵詞: 算法 自動(dòng)駕駛

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉