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 使用情况章节。
IPC Acore 侧实例编号范围为[0-63],分别用于 Acore 与 MCU 通信的实例[0-15]和[50-53]、Acore 与 VDSP 通信的实例[22-24]和[42-44]、Acore 与 BPU 通信的实例[32-39],其余实例做其它私有用途。客户 Acore 与 MCU 通信可使用实例[0-15],其余实例为内部使用。
IPC VDSP 侧实例编号范围为[0-6],分别用于 VDSP 与 Acore 通信的实例[0-2](VDSP0对应 Acore 实例[22-24],VDSP1对应 Acore 实例[42-44]),其余实例做私有用途。
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)空闲
<&ipc_instance4 8 8 0x1000>, #(Acore&MCU)用于CANHAL
<&ipc_instance5 8 8 0x1000>, #(Acore&MCU)用于外置RTC
<&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预留,暂未对客户开放
};
Acore 侧配置实例可通过设备树文件配置,配置路径为:
source/hobot-drivers/kernel-dts/drobot-s600-ipc.dtsi
source/hobot-drivers/kernel-dts/include/drobot_s600_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,用户可自行配置
<&ipc_instance4 8 8 0x1000>, #Acore&MCU,canhal
<&ipc_instance5 8 8 0x1000>, #Acore&MCU,外置RTC
<&ipc_instance6 8 8 0x1000>, #Acore&MCU,用户可自行配置
<&ipc_instance7 8 8 0x1000>, #Acore&MCU,ipcbox
<&ipc_instance8 8 8 0x1000>, #Acore&MCU,启动mcu1
<&ipc_instance9 2 5 0x400>, #Acore&MCU,用户可自行配置
<&ipc_instance10 1 5 0x200>, #Acore&MCU,timesync
<&ipc_instance11 8 8 0x1000>, #Acore&MCU,用户可自行配置
<&ipc_instance12 8 8 0x1000>, #Acore&MCU,用户可自行配置
<&ipc_instance13 8 8 0x1000>, #Acore&MCU,用户可自行配置
<&ipc_instance14 8 8 0x1000>, #Acore&MCU,用户可自行配置
<&ipc_instance15 8 8 0x1000>, #Acore&MCU,用户可自行配置
<&ipc_instance22 8 8 0x1000>, #Acore&VDSP0,暂未对客户开放
<&ipc_instance23 8 8 0x1000>, #Acore&VDSP0,暂未对客户开放
<&ipc_instance24 8 8 0x1000>, #Acore&VDSP0,暂未对客户开放
<&ipc_instance42 8 8 0x1000>, #Acore&VDSP1,暂未对客户开放
<&ipc_instance43 8 8 0x1000>, #Acore&VDSP1,暂未对客户开放
<&ipc_instance44 8 8 0x1000>; #Acore&VDSP1,暂未对客户开放
};
设备树配置说明
设备树 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 和中断机制,因此收发操作是相互独立、互不影响的。
设备树 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通信方向
instance = <3>; #实例id,不需要改动
data_local_addr = /bits/ 64 <IPC_INS3_DATA_LOCAL>; #Acore数据段
data_remote_addr = /bits/ 64 <IPC_INS3_DATA_REMOTE>; #MCU数据段
data_size = <IPC_SINGLE_DATA_SIZE>; #数据段大小,不可改动,单位Bytes
ctrl_local_addr = /bits/ 64 <IPC_INS3_CTRL_LOCAL>; #Acore控制段
ctrl_remote_addr = /bits/ 64 <IPC_INS3_CTRL_REMOTE>; #MCU控制段
ctrl_size = <IPC_SINGLE_CTRL_SIZE>; #数据段大小,不可改动,单位Bytes
};
设备树配置注意事项:
- 实例0~15数据段默认预分配了1MB 空间,Acore 侧使用0.5MB,MCU 侧使用0.5MB,所以通道个数*缓冲 buf 个数*buf 大小需要小于等于0.5MB。
- 实例0~15控制段默认预分配了8KB 空间,Acore 侧使用4KB,MCU 侧使用4KB,存放环形 buf 的控制信息和状态信息,所以(缓冲 buf 个数+2)*16*通道个数+8需要小于等于4KB。
- 每个实例的通道数量需要小于等于32,缓冲 buf 个数需要小于等于1024,同时需要满足前两点的不等式。
- 多个业务使用同一个实例的不同通道或者使用不同实例对传输影响不大,主要是参考 buf_size/buf_num 是否合适以及业务的开发和维护是否方便。
- 底层 Mailbox 中断分配不支持修改。
- Acore 与 MCU 的通道个数、缓冲 buf 个数和大小需要保持一致,数据段和控制段的 local 和 remote 需要相反。
- 实例的控制段首地址存储实例是否初始化的状态,可用于判断实例是否初始化,其中 Acore 默认启动 kernel 时完成初始化。
- 若用户需要自行分配数据段和地址段,则需要修改 Acore 设备树文件、Uboot 设备树文件以及 MCU 配置文件。
用户态 IPC 应用和配置文件的使用方法
IPC Sample 实现 Acore 与 MCU 之间的 IPC 收发通信,展示 IPC 多实例多通道多线程的使用示例。
Sample 软件架构图中 Acore 使用 libipcfhal 的接口进行数据收发,底层基于 ipcf 的驱动,MCU 直接使用 ipcf 的接口进行收发。其中由于 Acore 侧有多套 IPC 接口,便于区分,分别描述为 IPCFHAL、RPMSG、IPCF,MCU 侧只有一套 IPC 接口,因此 IPCF 在 MCU 侧文档统一描述为 IPC。
硬件 数据流说明
Sample 的共享内存数据流和中断信号流
Sample 中 Acore 与 MCU 通过共享内存传输数据,通过 mailbox 中断通知双方。
Acore 侧 Sample 代码位置与目录结构
代码路径:
# Sample源码路径
${SDK}/source/hobot-io-samples/debian/app/ipcbox_sample # ipc C++ Sample
${SDK}/source/hobot-io-samples/debian/app/pyhbipchal_sample # ipc python Sample
${SDK}/source/hobot-io/debian/app/pyhbipchal # ipc C++库为转换pyhton库源码
# 源码随固件一同打包,可在S100自行编译, 路径如下
${S100}/app/ipcbox_sample
${S100}/app/pyhbipchal_sample
目录结构:
root@ubuntu:/app/ipcbox_sample# tree .
.
├── ipcbox_runcmd # 运行mcu侧cmd命令Sample
│ ├── Makefile # Sample编译框架
│ ├── ipcbox_runcmd.cpp # Sample代码
│ └── ipcfhal_sample_config.json # Sample配置文件
└── ipcbox_uart # ipc透传uart Sample
├── Makefile # Sample编译框架
├── ipcbox_uart.cpp # Sample代码
└── ipcfhal_sample_config.json # Sample配置文件
IPC 实时性能优化设置
如果特定场景下需要提高 IPC 通信的实时性能,可以按照如下几步进行设置,以 ipc_instance5为例进行说明。
- 首先查找 ipc_instance5对应的中断号和中断线程 pid
#中断号查找:
root@ubuntu:~# cat /proc/interrupts | grep "mailbox"
14: 0 0 0 0 0 0 GICv3 293 Level 29f00000.mailbox0
15: 0 0 0 0 0 0 GICv3 294 Level 29f00000.mailbox0
16: 0 0 0 0 0 0 GICv3 295 Level 29f00000.mailbox0
17: 0 0 0 0 0 0 GICv3 296 Level 29f00000.mailbox0
18: 0 0 0 0 0 0 GICv3 297 Level 29f00000.mailbox0
19: 0 0 0 0 0 0 GICv3 298 Level 29f00000.mailbox0
20: 0 0 0 0 0 0 GICv3 299 Level 29f00000.mailbox0
21: 0 0 0 0 0 0 GICv3 300 Level 29f00000.mailbox0
22: 0 0 0 0 0 0 GICv3 301 Level 29f00000.mailbox0
23: 0 0 0 0 0 0 GICv3 302 Level 29f00000.mailbox0
24: 0 0 0 0 0 0 GICv3 303 Level 29f00000.mailbox0
25: 1 0 1 0 1 1 GICv3 304 Level 29f00000.mailbox0
26: 0 0 0 0 0 0 GICv3 305 Level 29f00000.mailbox0
27: 0 0 0 0 0 0 GICv3 306 Level 29f00000.mailbox0
28: 0 0 0 0 0 0 GICv3 307 Level 29f00000.mailbox0
29: 0 0 0 0 0 0 GICv3 280 Level 29f01000.mailbox1
30: 0 0 0 0 0 0 GICv3 281 Level 29f01000.mailbox1
31: 0 0 0 0 0 0 GICv3 282 Level 29f01000.mailbox1
32: 0 0 0 0 0 0 GICv3 283 Level 29f01000.mailbox1
33: 0 0 0 0 0 0 GICv3 284 Level 29f01000.mailbox1
34: 0 0 0 0 0 0 GICv3 285 Level 29f01000.mailbox1
35: 0 0 0 0 0 0 GICv3 286 Level 29f01000.mailbox1
36: 0 0 0 0 0 0 GICv3 287 Level 29f01000.mailbox1
37: 0 0 0 0 0 0 GICv3 288 Level 29f01000.mailbox1
38: 0 0 0 0 0 0 GICv3 289 Level 29f01000.mailbox1
39: 0 0 0 0 0 0 GICv3 290 Level 29f01000.mailbox1
40: 0 0 0 0 0 0 GICv3 291 Level 29f01000.mailbox1
41: 0 0 0 0 0 0 GICv3 292 Level 29f01000.mailbox1
42: 0 0 0 0 0 0 GICv3 50 Level 28109000.mailbox2
43: 0 0 0 0 0 0 GICv3 52 Level 2810d000.mailbox3
44: 0 0 0 0 0 0 GICv3 54 Level 28105000.mailbox4
#中断线程PID查找
root@ubuntu:~# ps aux | grep "mailbox"
root 70 0.0 0.0 0 0 ? S 22:17 0:00 [irq/14-29f00000.mailbox0]
root 71 0.0 0.0 0 0 ? S 22:17 0:00 [irq/15-29f00000.mailbox0]
root 72 0.0 0.0 0 0 ? S 22:17 0:00 [irq/16-29f00000.mailbox0]
root 73 0.0 0.0 0 0 ? S 22:17 0:00 [irq/17-29f00000.mailbox0]
root 74 0.0 0.0 0 0 ? S 22:17 0:00 [irq/18-29f00000.mailbox0]
root 75 0.0 0.0 0 0 ? S 22:17 0:00 [irq/19-29f00000.mailbox0]
root 76 0.0 0.0 0 0 ? S 22:17 0:00 [irq/20-29f00000.mailbox0]
root 77 0.0 0.0 0 0 ? S 22:17 0:00 [irq/21-29f00000.mailbox0]
root 78 0.0 0.0 0 0 ? S 22:17 0:00 [irq/22-29f00000.mailbox0]
root 79 0.0 0.0 0 0 ? S 22:17 0:00 [irq/23-29f00000.mailbox0]
root 80 0.0 0.0 0 0 ? S 22:17 0:00 [irq/24-29f00000.mailbox0]
root 81 0.0 0.0 0 0 ? S 22:17 0:00 [irq/25-29f00000.mailbox0]
root 82 0.0 0.0 0 0 ? S 22:17 0:00 [irq/26-29f00000.mailbox0]
root 83 0.0 0.0 0 0 ? S 22:17 0:00 [irq/27-29f00000.mailbox0]
root 84 0.0 0.0 0 0 ? S 22:17 0:00 [irq/28-29f00000.mailbox0]
root 85 0.0 0.0 0 0 ? S 22:17 0:00 [irq/29-29f01000.mailbox1]
root 86 0.0 0.0 0 0 ? S 22:17 0:00 [irq/30-29f01000.mailbox1]
root 87 0.0 0.0 0 0 ? S 22:17 0:00 [irq/31-29f01000.mailbox1]
root 88 0.0 0.0 0 0 ? S 22:17 0:00 [irq/32-29f01000.mailbox1]
root 89 0.0 0.0 0 0 ? S 22:17 0:00 [irq/33-29f01000.mailbox1]
root 90 0.0 0.0 0 0 ? S 22:17 0:00 [irq/34-29f01000.mailbox1]
root 91 0.0 0.0 0 0 ? S 22:17 0:00 [irq/35-29f01000.mailbox1]
root 92 0.0 0.0 0 0 ? S 22:17 0:00 [irq/36-29f01000.mailbox1]
root 93 0.0 0.0 0 0 ? S 22:17 0:00 [irq/37-29f01000.mailbox1]
root 94 0.0 0.0 0 0 ? S 22:17 0:00 [irq/38-29f01000.mailbox1]
root 95 0.0 0.0 0 0 ? S 22:17 0:00 [irq/39-29f01000.mailbox1]
root 96 0.0 0.0 0 0 ? S 22:17 0:00 [irq/40-29f01000.mailbox1]
root 97 0.0 0.0 0 0 ? S 22:17 0:00 [irq/41-29f01000.mailbox1]
root 98 0.0 0.0 0 0 ? S 22:17 0:00 [irq/42-28109000.mailbox2]
root 99 0.0 0.0 0 0 ? S 22:17 0:00 [irq/43-2810d000.mailbox3]
root 100 0.0 0.0 0 0 ? S 22:17 0:00 [irq/44-28105000.mailbox4]
#依据设备树ipc_instance5对应的mailbox为 mboxes = <&mailbox0 5 21 5>;所以中断号为19,中断线程pid为75.
- 中断绑核,降低迁移带来的消耗
#将IRQ 19绑定到 CPU2:
root@ubuntu:/# echo 4 > /proc/irq/19/smp_affinity
- 中断线程绑核,降低迁移带来的消耗
#将PID 75绑定到 CPU2:
root@ubuntu:/# taskset -p 0x04 75
pid 75's current affinity mask: 3f
pid 75's new affinity mask: 4
- 设置中断线程优先级,防止被高优任务打断
#将PID 75的优先级提高到99
root@ubuntu:/# chrt -f -p 99 75
root@ubuntu:/# chrt -p 75
pid 75's current scheduling policy: SCHED_FIFO
pid 75's current scheduling priority: 99
- 中断 CPU 设置隔离,确保对应 CPU 专门用于实时任务
#将CPU2进行隔离,需要进入uboot模式下设置
Hobot$ printenv bootargs
bootargs=earlycon=uart8250,mmio32,0x394B0000 no_console_suspend root=/dev/ram0 rdinit=/init rootwait net.ifnames=0
Hobot$ setenv bootargs "${bootargs} isolcpus=2 nohz_full=2 rcu_nocbs=2"
Hobot$ saveenv
Saving Environment to MMC... Writing to MMC(0)... OK
Hobot$ reset
#系统启动之后查看是否生效
root@ubuntu:/# cat /sys/devices/system/cpu/isolated
2
- 设置 RT 内核调度器状态,防止 RT 任务被强行 yield
root@ubuntu:/# echo -1 > /proc/sys/kernel/sched_rt_runtime_us
该设置会允许所有 RT 任务无限制地占用 CPU,从而提升系统的实时性能,但也可能导致普通任务无法获得调度机会而被饿死。因此,在使用 -1 时需谨慎。有关 RT 线程调度的调试,请参考内核官方文档
IPC 实时性能优化设置
如果特定 场景下需要提高 IPC 通信的实时性能,可以按照如下几步进行设置,以 ipc_instance5为例进行说明。
- 首先查找 ipc_instance5对应的中断号和中断线程 pid
#中断号查找:
root@ubuntu:~# cat /proc/interrupts | grep "mailbox"
14: 0 0 0 0 0 0 GICv3 293 Level 29f00000.mailbox0
15: 0 0 0 0 0 0 GICv3 294 Level 29f00000.mailbox0
16: 0 0 0 0 0 0 GICv3 295 Level 29f00000.mailbox0
17: 0 0 0 0 0 0 GICv3 296 Level 29f00000.mailbox0
18: 0 0 0 0 0 0 GICv3 297 Level 29f00000.mailbox0
19: 0 0 0 0 0 0 GICv3 298 Level 29f00000.mailbox0
20: 0 0 0 0 0 0 GICv3 299 Level 29f00000.mailbox0
21: 0 0 0 0 0 0 GICv3 300 Level 29f00000.mailbox0
22: 0 0 0 0 0 0 GICv3 301 Level 29f00000.mailbox0
23: 0 0 0 0 0 0 GICv3 302 Level 29f00000.mailbox0
24: 0 0 0 0 0 0 GICv3 303 Level 29f00000.mailbox0
25: 1 0 1 0 1 1 GICv3 304 Level 29f00000.mailbox0
26: 0 0 0 0 0 0 GICv3 305 Level 29f00000.mailbox0
27: 0 0 0 0 0 0 GICv3 306 Level 29f00000.mailbox0
28: 0 0 0 0 0 0 GICv3 307 Level 29f00000.mailbox0
29: 0 0 0 0 0 0 GICv3 280 Level 29f01000.mailbox1
30: 0 0 0 0 0 0 GICv3 281 Level 29f01000.mailbox1
31: 0 0 0 0 0 0 GICv3 282 Level 29f01000.mailbox1
32: 0 0 0 0 0 0 GICv3 283 Level 29f01000.mailbox1
33: 0 0 0 0 0 0 GICv3 284 Level 29f01000.mailbox1
34: 0 0 0 0 0 0 GICv3 285 Level 29f01000.mailbox1
35: 0 0 0 0 0 0 GICv3 286 Level 29f01000.mailbox1
36: 0 0 0 0 0 0 GICv3 287 Level 29f01000.mailbox1
37: 0 0 0 0 0 0 GICv3 288 Level 29f01000.mailbox1
38: 0 0 0 0 0 0 GICv3 289 Level 29f01000.mailbox1
39: 0 0 0 0 0 0 GICv3 290 Level 29f01000.mailbox1
40: 0 0 0 0 0 0 GICv3 291 Level 29f01000.mailbox1
41: 0 0 0 0 0 0 GICv3 292 Level 29f01000.mailbox1
42: 0 0 0 0 0 0 GICv3 50 Level 28109000.mailbox2
43: 0 0 0 0 0 0 GICv3 52 Level 2810d000.mailbox3
44: 0 0 0 0 0 0 GICv3 54 Level 28105000.mailbox4
#中断线程PID查找
root@ubuntu:~# ps aux | grep "mailbox"
root 70 0.0 0.0 0 0 ? S 22:17 0:00 [irq/14-29f00000.mailbox0]
root 71 0.0 0.0 0 0 ? S 22:17 0:00 [irq/15-29f00000.mailbox0]
root 72 0.0 0.0 0 0 ? S 22:17 0:00 [irq/16-29f00000.mailbox0]
root 73 0.0 0.0 0 0 ? S 22:17 0:00 [irq/17-29f00000.mailbox0]
root 74 0.0 0.0 0 0 ? S 22:17 0:00 [irq/18-29f00000.mailbox0]
root 75 0.0 0.0 0 0 ? S 22:17 0:00 [irq/19-29f00000.mailbox0]
root 76 0.0 0.0 0 0 ? S 22:17 0:00 [irq/20-29f00000.mailbox0]
root 77 0.0 0.0 0 0 ? S 22:17 0:00 [irq/21-29f00000.mailbox0]
root 78 0.0 0.0 0 0 ? S 22:17 0:00 [irq/22-29f00000.mailbox0]
root 79 0.0 0.0 0 0 ? S 22:17 0:00 [irq/23-29f00000.mailbox0]
root 80 0.0 0.0 0 0 ? S 22:17 0:00 [irq/24-29f00000.mailbox0]
root 81 0.0 0.0 0 0 ? S 22:17 0:00 [irq/25-29f00000.mailbox0]
root 82 0.0 0.0 0 0 ? S 22:17 0:00 [irq/26-29f00000.mailbox0]
root 83 0.0 0.0 0 0 ? S 22:17 0:00 [irq/27-29f00000.mailbox0]
root 84 0.0 0.0 0 0 ? S 22:17 0:00 [irq/28-29f00000.mailbox0]
root 85 0.0 0.0 0 0 ? S 22:17 0:00 [irq/29-29f01000.mailbox1]
root 86 0.0 0.0 0 0 ? S 22:17 0:00 [irq/30-29f01000.mailbox1]
root 87 0.0 0.0 0 0 ? S 22:17 0:00 [irq/31-29f01000.mailbox1]
root 88 0.0 0.0 0 0 ? S 22:17 0:00 [irq/32-29f01000.mailbox1]
root 89 0.0 0.0 0 0 ? S 22:17 0:00 [irq/33-29f01000.mailbox1]
root 90 0.0 0.0 0 0 ? S 22:17 0:00 [irq/34-29f01000.mailbox1]
root 91 0.0 0.0 0 0 ? S 22:17 0:00 [irq/35-29f01000.mailbox1]
root 92 0.0 0.0 0 0 ? S 22:17 0:00 [irq/36-29f01000.mailbox1]
root 93 0.0 0.0 0 0 ? S 22:17 0:00 [irq/37-29f01000.mailbox1]
root 94 0.0 0.0 0 0 ? S 22:17 0:00 [irq/38-29f01000.mailbox1]
root 95 0.0 0.0 0 0 ? S 22:17 0:00 [irq/39-29f01000.mailbox1]
root 96 0.0 0.0 0 0 ? S 22:17 0:00 [irq/40-29f01000.mailbox1]
root 97 0.0 0.0 0 0 ? S 22:17 0:00 [irq/41-29f01000.mailbox1]
root 98 0.0 0.0 0 0 ? S 22:17 0:00 [irq/42-28109000.mailbox2]
root 99 0.0 0.0 0 0 ? S 22:17 0:00 [irq/43-2810d000.mailbox3]
root 100 0.0 0.0 0 0 ? S 22:17 0:00 [irq/44-28105000.mailbox4]
#依据设备树ipc_instance5对应的mailbox为 mboxes = <&mailbox0 5 21 5>;所以中断号为19,中断线程pid为75.
- 中断绑核,降低迁移带来的消耗
#将IRQ 19绑定到 CPU2:
root@ubuntu:/# echo 4 > /proc/irq/19/smp_affinity
- 中断线程绑核,降低迁移带来的消耗
#将PID 75绑定到 CPU2:
root@ubuntu:/# taskset -p 0x04 75
pid 75's current affinity mask: 3f
pid 75's new affinity mask: 4
- 设置中断线程优先级,防止被高优任务打断
#将PID 75的优先级提高到99
root@ubuntu:/# chrt -f -p 99 75
root@ubuntu:/# chrt -p 75
pid 75's current scheduling policy: SCHED_FIFO
pid 75's current scheduling priority: 99
- 中断 CPU 设置隔离,确保对应 CPU 专门用于实时任务
#将CPU2进行隔离,需要进入uboot模式下设置
Hobot$ printenv bootargs
bootargs=earlycon=uart8250,mmio32,0x394B0000 no_console_suspend root=/dev/ram0 rdinit=/init rootwait net.ifnames=0
Hobot$ setenv bootargs "${bootargs} isolcpus=2 nohz_full=2 rcu_nocbs=2"
Hobot$ saveenv
Saving Environment to MMC... Writing to MMC(0)... OK
Hobot$ reset
#系统启动之后查看是否生效
root@ubuntu:/# cat /sys/devices/system/cpu/isolated
2
- 设置 RT 内核调度器状态,防止 RT 任务被强行 yield
root@ubuntu:/# echo -1 > /proc/sys/kernel/sched_rt_runtime_us
该设置会允许所有 RT 任务无限制地占用 CPU,从而提升系统的实时性能,但也可能导致普通任务无法获得调度机会而被饿死。因此,在使用 -1 时需谨慎。有关 RT 线程调度的调试,请参考内核官方文档
API 流程说明
Acore 与 MCU(IRQ 方式)之间 API Sample 运行流程图
Acore 与 MCU(POLL 方式)之间 API Sample 运行流程图