博客專欄

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

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

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

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

        一、IPC模塊簡述

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

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

        Acore 與 MCU 通過共享內(nèi)存?zhèn)鬏敂?shù)據(jù),通過 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);

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

        hb_ipcfhal_config(&thread_arg[i].ch);

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

        pthread_create;

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

        tx_pthread: 在這里插入圖片描述 hb_ipcfhal_send:使用 write對/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ū)動;

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

        Ipc_MDMA_OpenInstance(uint32 InstanceId);

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

        Ipc_MDMA_CheckRemoteCoreReady(uint32 InstanceId);

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

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

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

        SendTask: 在這里插入圖片描述 根據(jù)實(shí)例和通道選擇存入 dataBuf,通過 IpcTest_MdmaSend_Func 發(fā)送 data。 在這里插入圖片描述 Ipc_MDMA_TryGetHwResource:獲取驅(qū)動共享內(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 是地平線自己的庫和頭文件,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)境下運(yù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

        進(jìn)入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/

        復(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 ##請根據(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ù)制到共享文件夾中: 在這里插入圖片描述 通過串口獲取單板 ip:*可通過地平線開發(fā)者社區(qū)-6. *單板設(shè)置ip地址設(shè)置ip 在這里插入圖片描述 打開 WinSCP 新建站點(diǎn):

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

        2.1.3 運(yùn)行

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

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

        chmod 777 program
        ./program

        Sample 運(yùn)行時 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)友個人發(fā)布,僅代表博主個人觀點(diǎn),如有侵權(quán)請聯(lián)系工作人員刪除。



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

        相關(guān)推薦

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

        關(guān)閉
        主站蜘蛛池模板: 武定县| 芒康县| 荆州市| 定边县| 通江县| 广元市| 旌德县| 绥德县| 安顺市| 抚顺市| 河池市| 德阳市| 共和县| 大宁县| 商河县| 始兴县| 大邑县| 梅州市| 平原县| 孙吴县| 陈巴尔虎旗| 武冈市| 凤冈县| 巴南区| 广水市| 永吉县| 东光县| 沈阳市| 通江县| 定远县| 朔州市| 津市市| 微博| 缙云县| 林芝县| 吴江市| 上林县| 敦煌市| 彰化县| 旅游| 龙泉市|