博客專欄

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

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

        發(fā)布人:地平線開(kāi)發(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 例程的開(kāi)發(fā)者,都可以從中獲得有價(jià)值的見(jiàn)解和詳細(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 打開(kāi)對(duì)應(yīng)的設(shè)備驅(qū)動(dòng):/dev/ipcdrv *只要有一個(gè) channel 使用就一直打開(kāi)

        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 讀、寫(xiě)。

        tx_pthread: 在這里插入圖片描述 hb_ipcfhal_send:使用 write對(duì)/dev/ipcdrv 寫(xiě)入 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)存并打開(kā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 寫(xiě)入共享內(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ù)介_(kāi)發(fā)板上,本文使用共享文件夾 +WinSCP 方式進(jìn)行傳輸:

        將生成的可執(zhí)行文件復(fù)制到共享文件夾中: 在這里插入圖片描述 通過(guò)串口獲取單板 ip:*可通過(guò)地平線開(kāi)發(fā)者社區(qū)-6. *單板設(shè)置ip地址設(shè)置ip 在這里插入圖片描述 打開(kāi) 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)閉
        主站蜘蛛池模板: 台江县| 洪雅县| 香格里拉县| 荔浦县| 兴安县| 胶南市| 湖州市| 福海县| 南城县| 隆回县| 福泉市| 顺义区| 黎平县| 舒兰市| 饶河县| 巩义市| 烟台市| 霍林郭勒市| 峡江县| 卢龙县| 特克斯县| 吉隆县| 汉源县| 都匀市| 闽侯县| 顺平县| 江达县| 江西省| 云龙县| 宁化县| 普定县| 济宁市| 门头沟区| 长丰县| 靖边县| 肃宁县| 宁波市| 黎平县| 井研县| 务川| 饶阳县|