IPC模块介绍
IPC(Inter-Processor Communication)模块是用于多核之间的通信,支持同构核和异构核之间的通信,软件上基于buffer-ring进行共享内存的管理,硬件上基于MailBox实现核间中断。IPCF具有多路通道,大数据传输,适用多种平台的特点。RPMSG基于开源协议框架,支持Acore与VDSP的核间通信。
IPCF软硬件组件框图
Acore与MCU之间的核间通信,Acore侧主要使用IPCFHAL,MCU侧使用IPCF,其中IPCFHAL是基于IPCF封装了一层接口,用于用户态与内核态的数据传递。
IPC典型使用场景
IPC典型应用场景有OTA模块、诊断模块、规控、CANHAL等。
IPC实例分配方案
IPC Acore侧实例编号范围为[0-34],分别用于Acore与MCU通信的实例[0-14]、Acore与VDSP通信的实例[22-24]、Acore与BPU通 信的实例[32-34],其余实例做其它私有用途。Acore与MCU通信可使用实例[0-8],实例[4-6]默认为客户预留,若用户不需要CANHAL、规控等业务,可以自行修改配置文件。S100中AOCRE与MCU的IPC通信情况可以查阅 MCU IPC使用指南 中的IPC 使用情况章节。
Acore侧配置实例方法
Acore侧配置实例可通过设备树文件配置,配置路径为:
source/hobot-drivers/kernel-dts/drobot-s100-ipc.dtsi
source/hobot-drivers/kernel-dts/include/drobot_s100_ipc.h
设备树配置信息如下(仅供参考):
ipcfhal_cfg: ipcfhal_cfg {
status = "okay"; #节点状态,不需要改动
compatible = "hobot,hobot-ipcfhal"; #节点属性,不可改动
/****************instance--num_chans--num_bufs--buf_size****************/
ipc-ins = <&ipc_instance0 8 8 0x2000>, #(Acore&MCU)用于CANHAL
<&ipc_instance1 8 8 0x1000>, #(Acore&MCU)用于规控
<&ipc_instance2 2 8 0x800>, #(Acore&MCU)用于规控
<&ipc_instance3 8 8 0x1000>, #(Acore&MCU)用于crypto
<&ipc_instance4 8 8 0x1000>, #(Acore&MCU)空闲,用户可自行配置
<&ipc_instance5 8 8 0x1000>, #(Acore&MCU)空闲,用户可自行配置
<&ipc_instance6 8 8 0x1000>, #(Acore&MCU)空闲,用户可自行配置
<&ipc_instance7 8 8 0x1000>, #(Acore&MCU)透传uart,spi,i2c等外设和运行mcu侧cmd应用
<&ipc_instance8 8 8 0x1000>, #(Acore&MCU)部分空闲,用户可自行配置
<&ipc_instance9 2 5 0x400>, #(Acore&MCU)私有实例,内部预留
<&ipc_instance10 1 5 0x200>, #(Acore&MCU)私有实例,内部预留
<&ipc_instance22 8 8 0x1000>, #(Acore&VDSP)VDSP预留,暂未对客户开放
<&ipc_instance23 8 8 0x1000>, #(Acore&VDSP)VDSP预留,暂未对客户开放
<&ipc_instance24 8 8 0x1000>; #(Acore&VDSP)VDSP预留,暂未对客户开放
};
设备树配置说明
设备树ipcfhal_cfg节点默认配置了一些实例的属性:
- 属性中第一列表示实例编号,必须唯一且在有效范围
- 属性的第二列表示该实例分配的通道数量,用户可以自行配置,最大值为32个
- 属性的第三列表示每个通道的缓冲buf的个数,用户可以自行配置,最大值为1024个,但受控制空间大小的限制。属性第四列表示缓冲buf的大小,单位是Bytes,用户可以自行配置,通道个数* 缓冲buf个数*buf大小需要小于等于0.5MB(目前每个实例预分配了1MB的数据空间,暂不扩增)。
单个实例的设备树节点如下:
#Not used, User can apply for it
ipc_instance3: ipc_instance3 {
status = "okay"; #节点状态,不需要改动
compatible = "hobot,hobot-ipc"; #节点属性,不可改动
mbox-names = "mbox-chan"; #mailbox名字属性,不可改动
mboxes = <&mailbox0 3 19 3>; #mailbox通信方向,实例5和实例6需要改动,其它实例不需要改动
instance = <3>; #实例id,不需要改动
data_local_addr = /bits/ 64 <IPC_INS3_DATA_LOCAL>; #Acore数据段,实例5和实例6需要改动,其它实例不需要改动
data_remote_addr = /bits/ 64 <IPC_INS3_DATA_REMOTE>; #MCU数据段,实例5和实例6需要改动,其它实例不需要改动
data_size = <IPC_SINGLE_DATA_SIZE>; #数据段大小,不可改动,单位Bytes
ctrl_local_addr = /bits/ 64 <IPC_INS3_CTRL_LOCAL>; #Acore控制段,实例5和实例6需要改动,其它实例不需要改动
ctrl_remote_addr = /bits/ 64 <IPC_INS3_CTRL_REMOTE>; #MCU控制段,实例5和实例6需要改动,其它实例不需要改动
ctrl_size = <IPC_SINGLE_CTRL_SIZE>; #数据段大小,不可改动,单位Bytes
};
由于实例5和实例6内部用于测试,外部客户若需要使用,需要自行配置,配置信息如下,不需要改动。
ipc_instance5: ipc_instance5 {
status = "okay";
compatible = "hobot,hobot-ipc";
mbox-names = "mbox-chan";
mboxes = <&mailbox0 5 21 5>;
instance = <5>;
data_local_addr = /bits/ 64 <IPC_INS5_DATA_LOCAL>;
data_remote_addr = /bits/ 64 <IPC_INS5_DATA_REMOTE>;
data_size = <IPC_SINGLE_DATA_SIZE>;
ctrl_local_addr = /bits/ 64 <IPC_INS5_CTRL_LOCAL>;
ctrl_remote_addr = /bits/ 64 <IPC_INS5_CTRL_REMOTE>;
ctrl_size = <IPC_SINGLE_CTRL_SIZE>;
};
ipc_instance6: ipc_instance6 {
status = "okay";
compatible = "hobot,hobot-ipc";
mbox-names = "mbox-chan";
mboxes = <&mailbox0 6 22 6>;
instance = <6>;
data_local_addr = /bits/ 64 <IPC_INS6_DATA_LOCAL>;
data_remote_addr = /bits/ 64 <IPC_INS6_DATA_REMOTE>;
data_size = <IPC_SINGLE_DATA_SIZE>;
ctrl_local_addr = /bits/ 64 <IPC_INS6_CTRL_LOCAL>;
ctrl_remote_addr = /bits/ 64 <IPC_INS6_CTRL_REMOTE>;
ctrl_size = <IPC_SINGLE_CTRL_SIZE>;
};
设备树配置注意事项:
- 实例3~8数据段默认预分配了1MB空间,Acore侧使用0.5MB,MCU侧使用0.5MB,所以通道个数*缓冲buf个数*buf大小需要小于等于0.5MB。
- 实例3~8控制段默认预分配了5KB空间,Acore侧使用2.5KB,MCU侧使用2.5KB,存放环形buf的控制信息和状态信息,所以(缓冲buf个数+2)*16*通道个数+8需要小于等于2.5KB。
- 实例5~6用于地瓜机器人内部测试,用户可按照上面配置,修改设备树节点即可。 // TODO:可以完全放开给到客户
- 每个实例的通道数量需要小于等于32,缓冲buf个数需要小于等于1024,同时需要满足前两点的不等式。
- 多个业务使用同一个实例的不同通道或者使用不同实例对传输影响不大,主要是参考buf_size/buf_num是否合适以及业务的开发和维护是否方便。
- 底层Mailbox中断分配不支持修改。
- Acore与MCU的通道个数、缓冲buf个数和大小需要保持一致,数据段和控制段的local和remote需要相反。
- 实例的控制段首地址存储实例是否初始化的状态,可用于判断实例是否初始化,其中Acore默认启动kernel时完成初始化。
- 若用户需要自行分配数据段和地址段,则需要修改Acore设备树文件、Uboot设备树文件以及MCU配置文件。
- 在同一个 channel 中,发送(push)和接收(pop)使用独立的 ring buffer 和中断机制,因此收发操作是相互独立、互不影响的。
用户态IPC应用和配置文件的使用方法
IPC Sample实现Acore与MCU之间的IPC收发通信,展示IPC多实例多通道多线程的使用示例。
Sample软件架构图中Acore使用libipcfhal的接口进行数据收发,底层基于ipcf的驱动,MCU直接使用ipcf的接口进行收发。其中由于Acore侧有多套IPC接口,便于区分,分别描述为IPCFHAL、RPMSG、IPCF,MCU侧只有一套IPC接口,因此IPCF在MCU侧文档统一描述为IPC。