6678DSP核间通信

据我了解应该有3种方式,IPC中断,notify,MessageQ。

1、IPC中断

1)IPC中断事件号91

2)选择中断向量

#define IPC_VECTID          8

3)中断配置

    Hwi_Params hwiParams;

    /* 中断配置 */
    Hwi_Params_init(&hwiParams);
    hwiParams.arg = (UArg)IPC_VECTID;
    hwiParams.eventId = 91;
    hwiParams.enableInt = TRUE;
    Hwi_create(IPC_VECTID, (Hwi_FuncPtr)IsrMultiIpc, &hwiParams, NULL);

中断处理函数可以post信号量为后续处理

4)触发IPC中断

IPCGRx寄存器bit0置位触发IPC中断,高28位可以携带信息

/* IPCGR Info */
static volatile UINT iIPCGRInfo[8] =
{
    IPCGR0,
    IPCGR1,
    IPCGR2,
    IPCGR3,
    IPCGR4,
    IPCGR5,
    IPCGR6,
    IPCGR7
};

ERR IpcSendEvent(UINT coreId, UINT payLoad)
{
    *(volatile UINT *)(iIPCGRInfo[coreId]) = (payLoad & 0xfffffff0);

    *(volatile UINT *)(iIPCGRInfo[coreId]) |= 1;

    RET_OK;
}

5)携带信息从IPCARx读取

/* IPCAR Info */
static volatile UINT iIPCARInfo[8] =
{
    IPCAR0,
    IPCAR1,
    IPCAR2,
    IPCAR3,
    IPCAR4,
    IPCAR5,
    IPCAR6,
    IPCAR7
};

UINT IpcGetEvent(UINT coreId)
{
	volatile UINT payLoad;

    payLoad = *(volatile UINT *)(iIPCARInfo[coreId]);

    payLoad = payLoad & 0xfffffff0;

    return payLoad;
}

2、notify

多核通信采用主从方式,core0主,其余从核

1)注册notify事件,主核注册从核notify事件,从核注册主核notify事件

	#define INTERRUPT_LINE      0
    #define EVENTID             10

    if (coreId == DSP_CORE_0)
	{
		for (idx = 1; idx < DSP_CORE_NUM; idx++)
		{
			Notify_registerEvent(idx, INTERRUPT_LINE, EVENTID, (Notify_FnNotifyCbck)IsrMultiNotify, NULL);
		}
	}
	else
	{
		Notify_registerEvent(DSP_CORE_0, INTERRUPT_LINE, EVENTID, (Notify_FnNotifyCbck)IsrMultiNotify, NULL);
	}

注册回调可以post信号量为后续处理

2)notify事件发送

ERR NotifySendEvent(UINT coreId, UINT payLoad)
{
    Notify_sendEvent(coreId, INTERRUPT_LINE, EVENTID, payLoad, TRUE);

    RET_OK;
}

3、IPC or notify 数据发送

IPC 和 notify能发送的数据有限,只能作为核间事件通知。发送数据可以自定义共享队列。

基本思路是通过IPC中断或者notify事件,post信号量通知核间通信事件,读取共享队列获取核间通信数据。

#define SHARE_QUEUE_DEFAULE_LEN		(256)

typedef struct
{
    volatile UINT arg0;
    volatile UINT arg1;
    volatile UINT arg2;
    volatile void *ptr;
}QUEUE_ELE;

typedef struct
{
    volatile UINT wIdx;
    volatile UINT rIdx;
    volatile UINT queueLen;
    volatile QUEUE_ELE ele[SHARE_QUEUE_DEFAULE_LEN];
}SHARE_QUEUE;

共享队列放在4M共享内存,DDR也可以。以上的数据结构只是个范例,arg可以作为cmd控制字,ptr指向核间通信的数据,少量数据可以放在共享内存,大数据放在DDR。

封装共享队列读写接口

BOOL ShareQueuePut(SHARE_QUEUE *pSQ, QUEUE_ELE *ele)
{
    UINT r, w, irq;
    UINT len;
    BOOL bFound = FALSE;

    if(pSQ == NULL || ele == NULL)
    {
        PRT("ShareQueuePut: ERR! pSQ:%x, ele:%x\n",pSQ, ele);
        return FALSE;
    }

    len = pSQ->queueLen ? pSQ->queueLen : SHARE_QUEUE_DEFAULE_LEN;

    r = pSQ->rIdx;
    w = pSQ->wIdx;

    if(FORWARD(w, len) != r)
    {
        memcpy((void *)&pSQ->ele[w], ele, sizeof(QUEUE_ELE));
        pSQ->wIdx = FORWARD(w, len);
        bFound = TRUE;
    }

    return bFound;
}

BOOL ShareQueueGet(SHARE_QUEUE *pSQ, QUEUE_ELE *ele)
{
    UINT r, w, irq;
    UINT len;
    BOOL bFound = FALSE;

    if(pSQ == NULL || ele == NULL)
    {
		PRT("ShareQueueGet: ERR! pSQ:%x, ele:%x\n",pSQ, ele);
        return FALSE;
    }

    len = pSQ->queueLen ? pSQ->queueLen : SHARE_QUEUE_DEFAULE_LEN;

    r = pSQ->rIdx;
    w = pSQ->wIdx;

    if(r != w)
    {
        memcpy(ele, (void *)&pSQ->ele[r], sizeof(QUEUE_ELE));
        pSQ->rIdx = FORWARD(r, len);
        bFound = TRUE;
    }

    return bFound;
}

4、MessageQ

  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值