TI TDA4的IPC驱动利用MailBox和共享内存的方式实现核间通讯,核间交互数据存放在位于DDR共享内存中建立起来的Ring Buffer中,通过MailBox来通知消息状态。
VRing模块
设计VRing时,要求传入Ring Buffer的起始地址和大小,初始化过程中调用 Ipc_initVirtIO()
来完成地址初始化,对于每个核之间的地址共享分配是通过 Ipc_updateVirtIOInfo()
完成的。
以基础地质0xAA000000为起始地址,以Core编号为0的mpu1_0 (A72)
和Core编号为1的mcu1_0 (mcu-r5f0_0)
为例,最终的效果如下:
1
2
3
4
5
6
7master core: 0, remote core 1 tx alloc addr = 0xaa000000 master core: 0, remote core 1 rx alloc addr = 0xaa040000 master core: 0, remote core 1 pr alloc addr = 0xaa020000 master core: 1, remote core 0 tx alloc addr = 0xaa040000 master core: 1, remote core 0 rx alloc addr = 0xaa000000 master core: 1, remote core 0 pr alloc addr = 0xaa060000
可以发现Core0发送给Core1的共享地址与Core1接收Core0的地址相同,在此地址基础上建立Ring Buffer来进行管理,每个发送或接收地址内默认建立256个buffer用于数据缓存,要注意这些缓存由多核操作,要注意处理数据一致性问题(比如关闭DCache)。
操作这些buffer用到的基础Api如下:
1
2
3
4
5int16_t Virtio_getAvailBuf(Virtio_Handle vq, void **buf, int32_t *len); void Virtio_addAvailBuf(Virtio_Handle vq, void *buf, uint16_t head); void *Virtio_getUsedBuf(Virtio_Handle vq, uint16_t *token); int32_t Virtio_addUsedBuf(Virtio_Handle vq, int16_t head, int32_t len);
操作过程如图:
发送:Rpmsg_send
时,会调用Virtio_getAvailBuf
获取共享内存中可以被发送者使用的buffer,再调用Virtio_addUsedBuf
标记该buffer已经填充数据;触发MailBox产生中断,通知对向核心。
接收:Rpmsg_recv
由MailBox中断或轮询函数触发,调用Virtio_getUsedBuf
查询是否有有效数据可以接受,如果有则Copy数据,调用Virtio_addAvailBuf
标记该buffer重新可以被发送者使用。
MailBox的使用
MailBox作为消息通知的基础组件,IPC模块事先对使用到的MailBox进行分配,发送者和接收者触发和监听对应MailBox的事件来触发数据流。
分配位于ipc_soc.c中,该文件参与ipc库的编译。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103/* Host Processor - A72-vm0 */ { { { 0xFFU, 0xFFU, 0U}, { 0xFFU, 0xFFU, 0xFFU} }, /* Self - A72-vm0 */ { { 0U, 0U, 0U}, { 0U, 0U, 1U} }, /* mcu-r5f0 */ { { 0U, 0U, 2U}, { 0U, 0U, 3U} }, /* mcu-r5f1 */ { { 1U, 0U, 0U}, { 1U, 0U, 1U} }, /* main-r5f0 */ { { 1U, 0U, 2U}, { 1U, 0U, 3U} }, /* main-r5f1 */ #if defined (SOC_J721E) { { 2U, 0U, 0U}, { 2U, 0U, 1U} }, /* main-r5f2 */ { { 2U, 0U, 2U}, { 2U, 0U, 3U} }, /* main-r5f3 */ { { 3U, 0U, 0U}, { 3U, 0U, 1U} }, /* C66x-0 */ { { 3U, 0U, 2U}, { 3U, 0U, 3U} }, /* C66x-1 */ { { 4U, 0U, 0U}, { 4U, 0U, 1U} }, /* C7x-1 */ #endif { { 0U, 0U, 10U}, { 0U, 0U, 11U} } /* A72-vm1 */ }, /* Host Processor - mcu1_0 */ { { { 0U, 1U, 1U }, { 0U, 1U, 0U} }, /* A72-vm0 */ { { 0xFFU, 0xFFU, 0U }, { 0xFFU, 0xFFU, 0U} }, /* Self - mcu-r5f0 */
可以看到,A72给MCU1_0发送消息使用的是0,0,1(Cluster,User,Fifo )编号的MailBox Fifo;MCU1_0接收A72消息配置的编号为0,1,1,其中Cluster和Fifo是一一对应的。
最后
以上就是知性豌豆最近收集整理的关于TDA4 IPC 原理的全部内容,更多相关TDA4内容请搜索靠谱客的其他文章。
发表评论 取消回复