写点什么

征程 6E/M 底软开发 Sample-IPC

  • 2024-09-04
    广东
  • 本文字数:5870 字

    阅读完需:约 19 分钟

征程 6E/M 底软开发 Sample-IPC

作者:李祥

关于本文

在此篇文章中,我们将深入探讨 征程 6X 系列核间通信(IPC-F)的基本原理,并通过示例代码演示如何有效地使用 IPC-F 来实现 Acore 和 Rcore 之间的高效数据传输。无论你是刚刚接触这个概念的新手,还是希望在 征程 6X 系列上复现 IPC 例程的开发者,都可以从中获得有价值的见解和详细的复现流程。

一、IPC 模块简述

征程 6X IPC(Inter-Process Communication)模块是用于多核之间的通信,支持同构核和异构核之间的通信,软件上基于 buffer-ring 进行共享内存的管理,硬件上基于 MailBox 实现核间中断。IPCF 具有多路通道,大数据传输,适用多种平台的特点。

1.1 硬件数据流说明

Acore 与 MCU 通过共享内存传输数据,通过 mailbox 中断通知双方。


1.2 IPC Sample 软件架构

Acore 与 MCU 之间的核间通信,Acore 侧主要使用 IPCFHAL,MCU 侧使用 IPCF,其中 IPCFHAL 是基于 IPCF 封装了一层接口,用于用户态与内核态的数据传递。


1.3 Acore-IPC-Sample:

#Sample源码路径test/samples/platform_samples/source/S83_Sample/S83E02_Communication/ipc_sample/
复制代码

1.3.1 API 调用流程:

1.3.2 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、规控等业务,可以自行使用 CANHAL(实例 0)和规控(实例 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 分别创建一个发送和一个接收的线程,线程中进行 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。

1.4 MCU-IPC-Sample:

1.4.1 运行流程:


1.4.2 Sample 源码解析:

*void Ipc_MDMA_Init(Ipc_InstanceConfigType ConfigPtr, uint32 InstanceId);


1、获取实例和通道;


2、初始化底层驱动;


3、清空 MDMA 回环内存;


Ipc_MDMA_OpenInstance(uint32 InstanceId);


根据实例 id 预备共享内存并打开驱动 MailBox。


Ipc_MDMA_CheckRemoteCoreReady(uint32 InstanceId);


根据实例 id 判断共享内存是否 ready;


RecvTask:IrqCallBackSample:中断回调方式



检查数据的有效性(包括数据是否为空和滚动计数器的连续性),更新计数器,并通过 LogSync 打印出接受统计信息。


void Ipc_SamplePoll(void):poll 方式



Ipc_MDMA_PollMsg:从共享内存中获取接收到的信息。


SendTask:



根据实例和通道选择存入 dataBuf,通过 IpcTest_MdmaSend_Func 发送 data。



Ipc_MDMA_TryGetHwResource:获取驱动共享内存;


Ipc_MDMA_SendMsg:根据实例 id 写入共享内存。

二、Sample 使用:

2.1 Acore 侧:

2.1.1 编译

获取 AppSDK 包后,进入 appuser 执行:


*其中 hbrootfs-sdk_0.0.1.XXX_all.deb 是地平线自己的库和头文件,rootfs-sdk-focal_0.0.1.XXX_all.deb 是系统库,aarch64-linux-hb-gcc_12.2.0_amd64.deb 是 gcc 12.2.0 工具链,目前在 ubuntu22.04 非 docker 环境下运行正常。其它环境不能保证。


dpkg-deb -x rootfs-sdk*.deb ./sdkdpkg-deb -x hbrootfs-sdk*.deb ./sdk##移动sdk库路径,本文档放入/usr/lib中sudo mv sdk/ /usr/lib
复制代码


进入 toolchain 执行:


dpkg -x aarch64-linux-hb-gcc_12.2.0_amd64.deb ./arm-gnu-toolchain##移动toolchain库路径,本文档放入/usr/lib中sudo mv arm-gnu-toolchain/ /usr/libnano ~/.bashrc##添加系统路径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 := srcTARGET := 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)
复制代码


执行 make 完成编译,生成的文件为./program


2.1.2 文件传输

在 Linux 上交叉编译的执行文件需要传输到开发板上,本文使用共享文件夹 +WinSCP 方式进行传输:


将生成的可执行文件复制到共享文件夹中:



通过串口获取单板 ip:*可通过地平线开发者社区-6. *单板设置 ip 地址设置 ip



打开 WinSCP 新建站点:



登录后将 program 拖拽到/home/hobot/完成文件传输:


2.1.3 运行

通过 ssh 或串口进入/home/hobot/执行:


*如使用自定义 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[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 侧 Sample 的使用。

用户头像

还未添加个人签名 2021-03-11 加入

还未添加个人简介

评论

发布
暂无评论
征程 6E/M 底软开发 Sample-IPC_自动驾驶_地平线智能驾驶开发者_InfoQ写作社区