MSGBOX
msgbox 用来实现多 CPU 之间通讯,在一些 IC 内部可能同时存在多种核心用来实现多种不同功能,这些不同核心运行不同架构、不同系统,需要通过 MSGBOX 用来实现这些不同系统间通讯。
模块介绍
- msgbox 为一个双端 fifo 结构,cpu0 从一端写,cpu1 从一端读。
- rpmsg 为 linux 用来实现通讯的一种框架
- msgbox 为片上处理器之间提供了中断通讯机制
对于 R128 平台,CPU Remote ID如下
CPU | Remote ID |
---|---|
ARM M33 Star | 0 |
RISC-V C906 | 1 |
HIFI5 DSP | 2 |
模块配置
配置路径如下:
Kernel Setup --->
Drivers Setup --->
SoC HAL Drivers --->
msgbox devices --->
[*] enable msgbox driver
源码结构
msgbox/
├── msgbox_amp // msgbox AMP 实现
│ ├── Makefile
│ └── msgbox_amp.c
├── platform // 平台寄存器定义
│ ├── msgbox-sun20iw2.h
└── platform-msgbox.h // 公共头文件
模块接口说明
头文件
#include <hal_msgbox.h>
初始化接口
函数原型:
int32_t hal_msgbox_init(void);
参数:
- 无
返回值:
- 0:成功
- 负数:失败
通道申请接口
函数原型:
uint32_t hal_msgbox_alloc_channel(struct msg_endpoint *edp, int32_t remote, int32_t read, int32_t write);
参数:
- edp:msgbox的端点
- remote:远端核心id
- read:读通道
- write:写通道
返回值:
- 0:成功
- 负数:失败
数据发送接口
函数原型:
uint32_t hal_msgbox_channel_send(struct msg_endpoint *edp, uint8_t *bf, uint32_t len);
参数:
- edp:msgbox的端点
- bf:数据buffer
- len:buffer长度
返回值:
- 0:成功
- 负数:失败
通道释放接口
函数原型:
void hal_msgbox_free_channel(struct msg_endpoint *edp);
参数:
- edp:msgbox的端点
返回值:
- 0:成功
- 负数:失败
MSGBOX 申请流程
- 使用hal_msgbox_alloc_channel接口申请 msgbox 通道
- 填充msg_endpoint接收回调,这个会在 msgbox 的中断函数里调用
- 通过hal_msgbox_channel_send进行数据发送
- 接收通过中断的方式进行接收,会调用msg_endpoint的回调,无需主动调用
MSGBOX 接收流程
- 在接收函数里会首先遍历所有的msg_endpoint,判断当前终端是否有中断发送
- irq_msgbox_channel_handler里会读取当前msg_endpoint的寄存器,来判断是否有中断,如果有,则读取数据
- 退出中断
MSGBOX 发送流程
- 调用hal_msgbox_channel_send接口进行数据发送
- msgbox_channel_send_data会判断是远端处理器是哪个,并且计算 local->remote 的系数 N 是多少,这个系数回存放在 to_coef_n 的表格里
- 计算完成后往远端的 msgbox 的 fifo 中写数据
- 发送完成
模块使用范例
#include <FreeRTOS.h>
#include <queue.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <awlog.h>
#include <hal_msgbox.h>