ipc demo
功能概述
本文的IPC Sample实现Acore与MCU之间的IPC收发通信,展示IPC多实例多通道多线程的使用示例。
软件架构说明
Acore与MCU之间IPC Sample软件架构

Sample软件架构图中Acore使用libipcfhal的接口进行数据收发,底层基于ipcf的驱动,MCU直接使用ipcf的接口进行收发。其中由于Acore侧有多套IPC接口,便于区分,分别描述为IPCFHAL、RPMSG、IPCF,MCU侧只有一套IPC接口,因此IPCF在MCU侧文档统一描述为IPC。
硬件数据流说明

Sample中Acore与MCU通过共享内存传输数据,通过mailbox中断通知双方。
代码位置与目录结构
Acore侧Sample代码位置与目录结构
代码路径
test/samples/platform_samples/source/S83_Sample/S83E02_Communication/ipc_sample/
#板端配置文件路径
/app/sample/S83_Sample/S83E02_Communication/ipc_sample/testsuite/ipcfhal_sample_config.json
/app/sample/S83_Sample/S83E02_Communication/ipc_sample/bin/libipcf_hal_sample
目录结构
├── Kconfig #Sample编译框架
├── Makefile #Sample编译框架
├── Makefile.in #Sample编译框架
└── src
├── ipcfhal_sample_config.json #Sample配置文件
├── libipcfhal_sample.cpp #Sample源码
└── Makefile #Sample编译框架
MCU侧Sample代码位置与目录结构
#Sample源码目录
mcu/samples/Ipc/ipc_sample
mcu/Config/McalCdd/gen_matrix_A/Ipc
#源码目录结构
.
├── Ipc_Sample
├── ├── Ipc_Sample.c #Sample源码文件
├── └── Ipc_Sample.h #Sample源码头文件
└── SConscript #Sample编译文件
.
├── inc
├── ├── Ipc_Cfg.h #Sample配置头文件
├── └── Ipc_PrivateCfg.h #Sample配置头文件
├── SConscript #Sample编译文件
└── src
├── Ipc_Cfg.c #Sample配置源文件
└── Ipc_PrivateCfg.c #Sample配置源文件
API流程说明
Acore与MCU(IRQ方式)之间API Sample运行流程图


Acore Sample完成libipcfhal初始化后,创建4路发送线程和4路接收线程,当MCU接收到第一帧数据后,开始与Acore双向收发。其中Sample MCU轮询方式使用instance7channel0和instance7channel1两个通道进行双向收发,MCU中断方式使用instance8channel0和instance8channel1两个通道进行双向收发,Sample默认单包发送1024Bytes,发送周期为10ms,Sample运行时长为10s。
编译
编译环境
MCU侧编译环境使用build工具greenhills。
编译说明
#编译命令,lunch可根据实际场景选择编号
make lunch
1
source envsetup.sh
bdm libipcfhal-sample
MCU侧编译命令
#目前地平线的编译方式是:
python build_autosar.py product_matrix_A
运行
支持平台
Matrix 6E/M
硬件环境搭建
NA
/app/sample/S83_Sample/S83E02_Communication/ipc_sample/bin/libipcf_hal_sample
运行参数说明
NA
运行结果说明
Sample运行时Acore串口日志
[INFO][hb_ipcf_hal.cpp:282] [channel] cpu2mcu_ins7ch0 [ins] 7 [id] 0 init success.
[INFO][hb_ipcf_hal.cpp:333] [channel] cpu2mcu_ins7ch0 [ins] 7 [id] 0 config success.
[INFO][hb_ipcf_hal.cpp:282] [channel] cpu2mcu_ins7ch1 [ins] 7 [id] 1 init success.
[INFO][hb_ipcf_hal.cpp:333] [channel] cpu2mcu_ins7ch1 [ins] 7 [id] 1 config success.
[INFO][hb_ipcf_hal.cpp:282] [channel] cpu2mcu_ins8ch0 [ins] 8 [id] 0 init success.
[INFO][hb_ipcf_hal.cpp:333] [channel] cpu2mcu_ins8ch0 [ins] 8 [id] 0 config success.
[INFO][hb_ipcf_hal.cpp:282] [channel] cpu2mcu_ins8ch1 [ins] 8 [id] 1 init success.
[INFO][hb_ipcf_hal.cpp:333] [channel] cpu2mcu_ins8ch1 [ins] 8 [id] 1 config success.
Ins[7]Ch[0] TxCnt[100]TxFailCnt[0] -------
Ins[8]Ch[0] TxCnt[100]TxFailCnt[0] -------
Ins[7]Ch[1] TxCnt[100]TxFailCnt[0] -------
Ins[8]Ch[1] TxCnt[100]TxFailCnt[0] -------
Ins[7]Ch[0] ------- RxCnt[100]RxRollCnt[100]
Ins[8]Ch[0] ------- RxCnt[100]RxRollCnt[100]
Ins[7]Ch[1] ------- RxCnt[100]RxRollCnt[100]
Ins[8]Ch[1] ------- RxCnt[100]RxRollCnt[100]
Ins[7]Ch[0] TxCnt[200]TxFailCnt[0] -------
Ins[8]Ch[0] TxCnt[200]TxFailCnt[0] -------
Ins[8]Ch[1] TxCnt[200]TxFailCnt[0] -------
Ins[7]Ch[1] TxCnt[200]TxFailCnt[0] -------
Ins[7]Ch[0] ------- RxCnt[200]RxRollCnt[200]
Ins[8]Ch[1] ------- RxCnt[200]RxRollCnt[200]
Ins[8]Ch[0] ------- RxCnt[200]RxRollCnt[200]
Ins[7]Ch[1] ------- RxCnt[200]RxRollCnt[200]
Ins[7]Ch[0] TxCnt[300]TxFailCnt[0] -------
Ins[8]Ch[0] TxCnt[300]TxFailCnt[0] -------
Ins[8]Ch[1] TxCnt[300]TxFailCnt[0] -------
Ins[7]Ch[1] TxCnt[300]TxFailCnt[0] -------
Ins[7]Ch[0] ------- RxCnt[300]RxRollCnt[300]
Ins[8]Ch[0] ------- RxCnt[300]RxRollCnt[300]
Ins[7]Ch[1] ------- RxCnt[300]RxRollCnt[300]
Ins[8]Ch[1] ------- RxCnt[300]RxRollCnt[300]
Ins[7]Ch[0] TxCnt[400]TxFailCnt[0] -------
Ins[8]Ch[0] TxCnt[400]TxFailCnt[0] -------
Ins[8]Ch[1] TxCnt[400]TxFailCnt[0] -------
Ins[7]Ch[1] TxCnt[400]TxFailCnt[0] -------
Ins[7]Ch[0] ------- RxCnt[400]RxRollCnt[400]
Ins[7]Ch[1] ------- RxCnt[400]RxRollCnt[400]
Ins[8]Ch[0] ------- RxCnt[400]RxRollCnt[400]
Ins[8]Ch[1] ------- RxCnt[400]RxRollCnt[400]
Ins[7]Ch[0] TxCnt[500]TxFailCnt[0] -------
Ins[8]Ch[0] TxCnt[500]TxFailCnt[0] -------
Ins[8]Ch[1] TxCnt[500]TxFailCnt[0] -------
Ins[7]Ch[1] TxCnt[500]TxFailCnt[0] -------
Ins[7]Ch[0] ------- RxCnt[500]RxRollCnt[500]
Ins[8]Ch[0] ------- RxCnt[500]RxRollCnt[500]
Ins[8]Ch[1] ------- RxCnt[500]RxRollCnt[500]
Ins[7]Ch[1] ------- RxCnt[500]RxRollCnt[500]
Ins[7]Ch[0] TxCnt[600]TxFailCnt[0] -------
Ins[8]Ch[0] TxCnt[600]TxFailCnt[0] -------
Ins[8]Ch[1] TxCnt[600]TxFailCnt[0] -------
Ins[7]Ch[1] TxCnt[600]TxFailCnt[0] -------
Ins[7]Ch[0] ------- RxCnt[600]RxRollCnt[600]
Ins[8]Ch[0] ------- RxCnt[600]RxRollCnt[600]
Ins[7]Ch[1] ------- RxCnt[600]RxRollCnt[600]
Ins[8]Ch[1] ------- RxCnt[600]RxRollCnt[600]
Ins[7]Ch[0] TxCnt[700]TxFailCnt[0] -------
Ins[8]Ch[0] TxCnt[700]TxFailCnt[0] -------
Ins[8]Ch[1] TxCnt[700]TxFailCnt[0] -------
Ins[7]Ch[1] TxCnt[700]TxFailCnt[0] -------
Ins[7]Ch[0] ------- RxCnt[700]RxRollCnt[700]
Ins[8]Ch[0] ------- RxCnt[700]RxRollCnt[700]
Ins[7]Ch[1] ------- RxCnt[700]RxRollCnt[700]
Ins[8]Ch[1] ------- RxCnt[700]RxRollCnt[700]
Ins[7]Ch[0] TxCnt[800]TxFailCnt[0] -------
Ins[8]Ch[0] TxCnt[800]TxFailCnt[0] -------
Ins[8]Ch[1] TxCnt[800]TxFailCnt[0] -------
Ins[7]Ch[1] TxCnt[800]TxFailCnt[0] -------
Ins[7]Ch[0] ------- RxCnt[800]RxRollCnt[800]
Ins[8]Ch[0] ------- RxCnt[800]RxRollCnt[800]
Ins[7]Ch[1] ------- RxCnt[800]RxRollCnt[800]
Ins[8]Ch[1] ------- RxCnt[800]RxRollCnt[800]
Ins[7]Ch[0] TxCnt[900]TxFailCnt[0] -------
Ins[8]Ch[0] TxCnt[900]TxFailCnt[0] -------
Ins[8]Ch[1] TxCnt[900]TxFailCnt[0] -------
Ins[7]Ch[1] TxCnt[900]TxFailCnt[0] -------
Ins[7]Ch[0] ------- RxCnt[900]RxRollCnt[900]
Ins[8]Ch[0] ------- RxCnt[900]RxRollCnt[900]
Ins[7]Ch[1] ------- RxCnt[900]RxRollCnt[900]
Ins[8]Ch[1] ------- RxCnt[900]RxRollCnt[900]
[SampleEnd]Ins[7]Ch[0]TxCnt[994]TxFailCnt[0]
[SampleEnd]Ins[7]Ch[0]RxCnt[995]RxRollCnt[995]
[INFO][hb_ipcf_hal.cpp:549] [channel] cpu2mcu_ins7ch0 [ins] 7 [id] 0 deinit success.
[SampleEnd]Ins[7]Ch[1]TxCnt[995]TxFailCnt[0]
[SampleEnd]Ins[7]Ch[1]RxCnt[996]RxRollCnt[996]
[INFO][hb_ipcf_hal.cpp:549] [channel] cpu2mcu_ins7ch1 [ins] 7 [id] 1 deinit success.
[SampleEnd]Ins[8]Ch[0]TxCnt[996]TxFailCnt[0]
[SampleEnd]Ins[8]Ch[0]RxCnt[997]RxRollCnt[997]
[INFO][hb_ipcf_hal.cpp:549] [channel] cpu2mcu_ins8ch0 [ins] 8 [id] 0 deinit success.
[SampleEnd]Ins[8]Ch[1]TxCnt[997]TxFailCnt[0]
[SampleEnd]Ins[8]Ch[1]RxCnt[998]RxRollCnt[998]
[INFO][hb_ipcf_hal.cpp:549] [channel] cpu2mcu_ins8ch1 [ins] 8 [id] 1 deinit success.
[ipc-sample] ipc sample running success
程序输出结果的说明
输出日志包含三部分,分别为通道初始化日志、通道收发计数日志和通道去初始化日志。其中通道收发计数日志显示Acore发送线程的计数和接收线程的计数值,每次运行Sample程序,收发计数都从1开始计数。
注意事项
此Sample使用instance7和instance8,不支持使用其它instance。
更新MCU和Acore镜像后,若网络正常,可使用mount命令挂载app分区。
若网络不正常,可使用发版的镜像烧写app分区到板端,然后更新MCU Sample镜像,开始测试。
若网络不正常,替换Acore的Sample可执行文件或Json配置文件时,可以使用串口传输,即sz和rz命令。
若Acore Sample可执行文件没有执行权限,可使用chmod命令修改文件权限。
Acore Sample中的Json配置文件和可执行文件必须放在默认路径下。
此Sample仅支持配置文件中的instance7channel0、instance7channel1、instance8channel0和instance8channel1,若需要增加通道,需要修改Acore和MCU两侧配置文件。
更多
通路配置
Json文件配置通道
"log_level": 0, #日志等级,可省略
"config_num": 4, #配置通道数量
"config_num_max":256, #配置通道数量最大值
"config_0": { #配置通道
"name": "cpu2mcu_ins7ch0", #通道名字
"instance": 7, #实例id
"channel": 0, #通道id
"pkg_size_max": 4096, #发送包最大字节,推荐小于等于4096Bytes
"fifo_size": 64000, #缓冲fifo的大小,取决于需要缓冲的个数
"fifo_type": 0, #缓冲fifo的类型,仅支持0
"ipcf_dev_path":"/dev/ipcdrv", #字符设备驱动,仅支持/dev/ipcdrv
"ipcf_dev_name":"ipcdrv" #字符设备驱动名字,仅支持ipcdrv
},
"config_1": {
"name": "cpu2mcu_ins7ch1",
"instance": 7,
"channel": 1,
"pkg_size_max": 4096,
"fifo_size": 64000,
"fifo_type": 0,
"ipcf_dev_path":"/dev/ipcdrv",
"ipcf_dev_name":"ipcdrv"
},
"config_2": {
"name": "cpu2mcu_ins8ch0",
"instance": 8,
"channel": 0,
"pkg_size_max": 4096,
"fifo_size": 64000,
"fifo_type": 0,
"ipcf_dev_path":"/dev/ipcdrv",
"ipcf_dev_name":"ipcdrv"
},
"config_3": {
"name": "cpu2mcu_ins8ch1",
"instance": 8,
"channel": 1,
"pkg_size_max": 4096,
"fifo_size": 64000,
"fifo_type": 0,
"ipcf_dev_path":"/dev/ipcdrv",
"ipcf_dev_name":"ipcdrv"
}
}
增加通路方式
可以增加Json文件中的通道数量config_num,并增加通道信息,本Sample未支持增加通道的功能,若需要增加通道,需要修改Acore和MCU两侧配置文件。
