我是靠谱客的博主 知性豌豆,这篇文章主要介绍TDA4 IPC 原理,现在分享给大家,希望可以做个参考。

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
7
master 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
5
int16_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内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部