“零”智享|TDA4 IPC核间通信原理 |
您所在的位置:网站首页 › rpmsg文件 › “零”智享|TDA4 IPC核间通信原理 |
目前很多芯片都会有几个core核,有的是Cortex M0+、M4、M7、A53、A73等等,有的有着2核、3核、4核甚至6核8核,不同的核的主频支持度不一样,适用的具体应用场景也不同,因此需要IPC(Inter-processor communication)来核间通信,进行数据的交互。 「IPC核间通信介绍」核间通信(IPC)的主要目标是:充分利用硬件提供的机制,实现高效的CORE间通信;给需要CORE间通信的应用程序提供简洁高效的编程接口。 根据所使用的硬件特性,核间通信的实现机制有: ·Mailbox中断 ·基于共享内存的消息队列 Jacinto 7 SoC 在一个 SoC 上有多个不同的 CPU。包括 R5F、A72、C7x、C6x。在这些 CPU 上运行的软件需要相互协作并实现用例。协作方式通常被称为处理器间通信或IPC。每个 CPU 和操作系统上都提供了 IPC 库,以允许更高级别的应用程序相互通信。 IPC 的主要软件组件是: TI-RTOS的PDK IPC LLD驱动,包括RPMSG、VRING和HW Mailbox驱动。 Linux内核IPC驱动套件,由RPMSG CHAR、RPMSG、VRING和HW Mailbox驱动组成。 RPMSG 是 Linux 和 TI-RTOS 使用的通用消息传递框架。RPMSG 是一种基于端点的协议,其中服务器 CPU 可以运行一个服务来侦听专用端点处的传入消息,而所有其他 CPU 可以向该(服务器 CPU、服务端点)元组发送请求。可以将其类比为网络中的 UDP/IP 层,其中 CPU 名称类似于 IP 地址,端点类似于 UDP 端口号。 虽然 RPMSG 是应用程序所见的 API 或协议,但在内部,IPC 驱动程序使用 VRING 在不同(RPMSG CPU、端点)元组之间实际传递消息。VRING 是一个共享内存段,位于一对 CPU 之间,用于保存两个 CPU 之间传递的消息。 客户端 CPU / 任务在向服务器发送消息时还提供回复端点,以便服务器可以将其回复到客户端 CPU。 通过使用多个端点,可以在同一组 CPU 之间打开多个逻辑 IPC 通信通道。 封装-VRING-解析的过程: 1、应用程序向给定目的地(CPU、端点)发送消息 2、消息首先从应用程序复制到两个CPU之间使用的VRING。此后,IPC 驱动程序在硬件邮箱中发布 VRING ID。 3、这会触发目标 CPU 上的中断。在目标 CPU 的 ISR 中,它提取 VRING ID,然后根据 VRING ID 检查该 VRING 中的所有消息。 4、如果收到消息,它从VRING中提取消息并将其放入目标RPMSG端点队列中。然后触发在此 RPMSG 端点上阻止的应用程序。 5、应用程序处理接收到的消息,并使用相同的RPMSG 和VRING 机制在相反方向回复发送方CPU。 Hardware Mailbox硬件邮箱主要用于提供具有小的 32 位有效负载的中断事件通知。 VRING 使用硬件邮箱在目标 CPU 上触发中断。每个邮箱包含 16 个单向 HW 队列,最多可连接 4 个通信用户或 CPU。 J721E SoC 有 12 个硬件邮箱实例。即 12x 16 个硬件邮箱队列。 邮箱本质上充当一个非常小的硬件队列,其中包含 VRING ID。 VRING 是共享内存中的 SW 队列,保存两个 CPU 之间传递的实际消息。当收到中断时,邮箱消息会告知从哪个 VRING 出列消息。 VRING ID=0 tells to look at the VRING from sender to receiver VRING ID=1 tells to look at the VRING from receiver to sender 在 linux 中,rpmsg 字符驱动程序由内核初始化,它为每个远程 rpmsg_chrdev 服务创建一个用户空间 /dev 条目。 obj->tx_fds[i] = appIpcCreateTxCH(i,prm->tiovx_rpmsg_prot_id,&host_port_id,&obj->rcdev[i]);应用程序就有了一个可以用来读写消息的fd。 具体的应用代码可以参考 ti-processor-sdk-rtos-j721e-evm-08_01_00_13\vision_apps\utils\ipc\src 我们只需要将IPC的应用程序封装成库,供connector中间件调用即可。 接收函数: memset(playroad,0,sizeof(payroad)); status = read( obj->tx_fds[i], payroad,sizeof(payroad)); if(status > 0) { appIpcRpmsgRxHandler( i, 发送函数: status=write(obj->tx_fds[dest_cpu_id],&payload,sizeof(payload)); if(status < 0 || status !=sizeof(payload)) { appLogPrintf("IPC:TX:FAILED:%s ->%s (port %d) msg = 0x%08x\n", appIpcGetCpuName(appIpcGetSelfCpuId()), appIpcGetCpuName(dest_cpu_id), (unit32_t)prot_id, 通过IPC核间通信达成数据交互,使得多核可以传输信息,共同协作,提高工作效率。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |