MBOX
设备说明
MBOX(mail box)在多核SOC 系统中,核间通信是多核协同工作的保证。MAILBOX是以中断触发方式提供核间通信的IP。支持发送CPU 向接收CPU 传递除中断事件外的信息量,以信息寄存器组的方式体现。
接口列表
MBOX的CSI接口说明如下所示:
函数 | 说明 |
---|---|
csi_mbox_init | 初始化 |
csi_mbox_uninit | 去初始化 |
csi_mbox_attach_callback | 注册回调函数 |
csi_mbox_detach_callback | 注销回调函数 |
csi_mbox_send | 消息发送 |
csi_mbox_receive | 消息接收 |
MBOX的CSI接口在用户对接时是否必须适配的说明如下所示:
函数 | 是否必须适配 |
---|---|
csi_mbox_init | 必须 |
csi_mbox_uninit | 必须 |
csi_mbox_attach_callback | 必须 |
csi_mbox_detach_callback | 必须 |
csi_mbox_send | 必须 |
csi_mbox_receive | 必须 |
接口详细说明
csi_mbox_init
csi_error_t csi_mbox_init(csi_mbox_t *mbox, uint32_t idx)
功能描述:
- 通过设备ID初始化对应的mbox实例。
参数:
mbox
: 设备句柄(需要用户申请句柄空间)。idx
: 设备ID。
返回值:
- 错误码csi_error_t。
csi_mbox_t
成员 | 类型 | 说明 |
---|---|---|
dev | csi_dev_t | csi设备统一句柄 |
callback | void (callback)(csi_mbox_t mbox, csi_mbox_event_t event, uint32_t channel_id, uint32_t received_len, void *arg) | 用户回调函数 |
arg | void * | 回调函数对应传参 |
priv | void * | 设备私有变量 |
csi_mbox_uninit
void csi_mbox_uninit(csi_mbox_t *mbox)
功能描述:
- mbox实例反初始化,该接口会停止mbox实例正在进行的工作,并且释放相关的软硬件资源。
参数:
mbox
: 设备句柄。
返回值:
- 无。
csi_mbox_attach_callback
csi_error_t csi_mbox_attach_callback(csi_mbox_t *mbox, void *callback, void *arg)
功能描述:
- 注册回调函数。
参数:
mbox
: 设备句柄。callback
: 中断回调函数。arg
: 回调函数对应的传参,由用户自定义。
返回值:
- 错误码csi_error_t。
callback
void (*callback)(csi_mbox_t *mbox, csi_mbox_event_t event, uint32_t channel_id, uint32_t received_len, void *arg);
其中mbox为设备句柄,event为事件类型,channel_id为通道号产生的事件,received_len为已接收到的字符长度,arg为用户自定义的回调函数对应的参数。
csi_mbox_event_t
类型 | 说明 |
---|---|
MBOX_EVENT_SEND_COMPLETE | 发送完成事件 |
MBOX_EVENT_RECEIVED | 接收事件 |
csi_mbox_detach_callback
void csi_mbox_detach_callback(csi_mbox_t *mbox)
功能描述:
- 注销回调函数。
参数:
mbox
: 设备句柄。
返回值:
- 无。
初始化示例
#include <stdio.h>
#include <soc.h>
#include <drv/mbox.h>
static csi_mbox_t g_mbox;
int main(void)
{
csi_error_t ret = 0;
/* init mbox 0 */
ret = csi_mbox_init(&g_mbox, 0);
return ret;
}
发送模式示例
(当前CPU0,目标CPU1)
#include <stdio.h>
#include <soc.h>
#include <drv/mbox.h>
#define EXAMPLE_MBOX_IDX 0
/**
* if current CPU is 0
*/
#define EXAMPLE_MBOX_TARGET_CPU 0 ///< 0:CPU1 1:CPU2
/**
* if current CPU is 1
*/
// #define EXAMPLE_MBOX_TARGET_CPU 0 ///< 0:CPU0 1:CPU2
/**
* if current CPU is 2
*/
// #define EXAMPLE_MBOX_TARGET_CPU 0 ///< 0:CPU0 1:CPU1
#define CHECK_RETURN(ret) \
do { \
if (ret != 0) { \
return -1; \
} \
} while(0);
csi_mbox_t mbox;
volatile uint8_t send_event_done = 0U;
volatile uint8_t receive_event_done = 0U;
uint8_t tx_data[] = "Hello, Are you Ready?";
uint8_t rx_data[64];
static void mailbox_event_cb_fun(csi_mbox_t *mbox, csi_mbox_event_t event, uint32_t channel_id, uint32_t received_len, void *arg)
{
if (event == MBOX_EVENT_SEND_COMPLETE) {
send_event_done = 1U;
} else if (event == MBOX_EVENT_RECEIVED) {
csi_mbox_receive(mbox, channel_id, rx_data, received_len);
receive_event_done = 1U;
} else {
printf("ERR->Error event handle\n");
}
}
int example_mailbox(int32_t idx)
{
csi_error_t ret;
printf("1->Mbox Sender\n");
ret = csi_mbox_init(&mbox, idx);
CHECK_RETURN(ret);
ret = csi_mbox_attach_callback(&mbox, mailbox_event_cb_fun, NULL);
CHECK_RETURN(ret);
printf("2->Sender Send data is:'%s'\n", tx_data);
ret = csi_mbox_send(&mbox, EXAMPLE_MBOX_TARGET_CPU, tx_data, sizeof(tx_data));
CHECK_RETURN(ret);
while (!send_event_done);
printf("3->Sender send ok\n");
while (!receive_event_done);
printf("4->Sender Recv data is:'%s'\n", rx_data);
csi_mbox_detach_callback(&mbox);
csi_mbox_uninit(&mbox);
printf("5->test mbox-sender successfully\n");
return 0;
}
接收模式示例
(当前CPU1,目标CPU0)
#include <stdio.h>
#include <soc.h>
#include <drv/mbox.h>
#define EXAMPLE_MBOX_IDX 0
/**
* if current CPU is 0
*/
// #define EXAMPLE_MBOX_TARGET_CPU 0 ///< 0:CPU1 1:CPU2
/**
* if current CPU is 1
*/
#define EXAMPLE_MBOX_TARGET_CPU 0 ///< 0:CPU0 1:CPU2
/**
* if current CPU is 2
*/
// #define EXAMPLE_MBOX_TARGET_CPU 0 ///< 0:CPU0 1:CPU1
#define CHECK_RETURN(ret) \
do { \
if (ret != 0) { \
return -1; \
} \
} while(0);
csi_mbox_t mbox;
volatile uint8_t send_event_done = 0U;
volatile uint8_t receive_event_done = 0U;
uint8_t tx_data[] = "Yes, I am ready!";
uint8_t rx_data[64];
static void mailbox_event_cb_fun(csi_mbox_t *mbox, csi_mbox_event_t event, uint32_t channel_id, uint32_t received_len, void *arg)
{
if (event == MBOX_EVENT_SEND_COMPLETE) {
send_event_done = 1U;
} else if (event == MBOX_EVENT_RECEIVED) {
csi_mbox_receive(mbox, channel_id, rx_data, received_len);
receive_event_done = 1U;
} else {
printf("ERR->Error event handle\n");
}
}
int example_mailbox(int32_t idx)
{
csi_error_t ret;
printf("1->Mbox Receiver\n");
ret = csi_mbox_init(&mbox, idx);
CHECK_RETURN(ret);
ret = csi_mbox_attach_callback(&mbox, mailbox_event_cb_fun, NULL);
CHECK_RETURN(ret);
while (!receive_event_done);
receive_event_done = 0;
printf("2->Receiver Recv data is:'%s'\n", rx_data);
printf("3->Receiver Send data is:'%s'\n", tx_data);
ret = csi_mbox_send(&mbox, EXAMPLE_MBOX_TARGET_CPU, tx_data, sizeof(tx_data));
CHECK_RETURN(ret);
while (!send_event_done);
printf("4->reply message ok\n");
csi_mbox_detach_callback(&mbox);
csi_mbox_uninit(&mbox);
printf("5->test mbox-sender successfully\n");
return 0;
}