This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 问题:AM6422:IPC 启用&禁用中断

Guru**** 2347070 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1510849/re-am6422-ipc-enabling-disabling-interrupts

这是对此处讨论的后续行动:
https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1500812/am6422-ipc-delay 

您好、

  关于 rpmsg 的使用、库函数中有许多中断禁用/启用操作。 这些操作目前正在影响我的实时内核中的其他中断。 这些中断禁用/启用操作是否必要? 为什么这样实施?

RPMessage_LocalMsg *RPMessage_allocEndPtMsg(uint32_t remoteCoreId)
{
    RPMessage_Core *coreObj = &gIpcRpmsgCtrl.coreObj[remoteCoreId];
    RPMessage_LocalMsg *pMsg;
    uint32_t oldIntState;

    oldIntState = HwiP_disable();
    pMsg = (RPMessage_LocalMsg*)RPMessage_queueGet(&coreObj->freeQ);
    if(pMsg == NULL)
    {
        coreObj->freeQAllocPending = 1;
    }
    else
    {
        coreObj->freeQAllocPending = 0;
    }
    HwiP_restore(oldIntState);

    return pMsg;
}
uint32_t RPMessage_freeEndPtMsg(uint16_t remoteCoreId, RPMessage_LocalMsg *pMsg)
{
    RPMessage_Core *coreObj = &gIpcRpmsgCtrl.coreObj[remoteCoreId];
    uint32_t oldIntState, isAllocPending;

    oldIntState = HwiP_disable();
    isAllocPending = coreObj->freeQAllocPending;
    RPMessage_queuePut(&coreObj->freeQ, &pMsg->elem);
    HwiP_restore(oldIntState);

    return isAllocPending;
}

void RPMessage_putEndPtMsg(RPMessage_Struct *obj, RPMessage_LocalMsg *pMsg)
{
    uint32_t oldIntState;

    oldIntState = HwiP_disable();
    RPMessage_queuePut(&obj->endPtQ, &pMsg->elem);
    HwiP_restore(oldIntState);

    SemaphoreP_post(&obj->newEndPtMsgSem);
}

int32_t RPMessage_getEndPtMsg(RPMessage_Struct *obj, RPMessage_LocalMsg **pMsg, uint32_t timeout)
{
    uint32_t oldIntState, done;
    int32_t status = SystemP_TIMEOUT;

    done = 0;
    do {
        oldIntState = HwiP_disable();
        *pMsg = (RPMessage_LocalMsg*)RPMessage_queueGet(&obj->endPtQ);
        HwiP_restore(oldIntState);

        if(*pMsg==NULL)
        {
            status = SemaphoreP_pend(&obj->newEndPtMsgSem, timeout);
            if(status == SystemP_TIMEOUT)
            {
                done = 1;
            }
            if(status == SystemP_SUCCESS && obj->doRecvUnblock)
            {
                status = SystemP_TIMEOUT;
                done = 1;
            }
        }
        else
        {
            status = SystemP_SUCCESS;
            done = 1;
        }
    } while( ! done );

    return status;
}
int32_t RPMessage_vringGetEmptyTxBuf(uint16_t remoteCoreId, uint16_t *vringBufId, uint32_t timeout)
{
    RPMessage_Core *coreObj = &gIpcRpmsgCtrl.coreObj[remoteCoreId];
    RPMessage_Vring *vringObj = &coreObj->vringTxObj;
    uint32_t oldIntState;
    uint16_t head;
    int32_t status = SystemP_FAILURE;
    uint32_t done = 0;

    oldIntState = HwiP_disable();

    do
    {
        /* There's nothing available */
        if (vringObj->lastAvailIdx == vringObj->avail->idx)
        {
            /* We need to know about added buffers */
            vringObj->used->flags &= (uint16_t)~VRING_USED_F_NO_NOTIFY;

            HwiP_restore(oldIntState);

            status = SemaphoreP_pend(&coreObj->newEmptyVringBufSem, timeout);
            if(status==SystemP_TIMEOUT)
            {
                done = 1;
            }

            oldIntState = HwiP_disable();
        }
        else
        {
            head = vringObj->avail->ring[vringObj->lastAvailIdx % vringObj->vringNumBuf];
            vringObj->lastAvailIdx++;

            *vringBufId = head;
            done = 1;
            status = SystemP_SUCCESS;
        }
    } while( ! done );

    HwiP_restore(oldIntState);

    return status;
}

void RPMessage_vringPutFullTxBuf(uint16_t remoteCoreId, uint16_t vringBufId, uint16_t dataLen)
{
    RPMessage_Core *coreObj = &gIpcRpmsgCtrl.coreObj[remoteCoreId];
    RPMessage_Vring *vringObj = &coreObj->vringTxObj;
    struct vring_used_elem *used;
    uint32_t oldIntState;
    uint32_t txMsgValue = RPMESSAGE_MSG_VRING_NEW_FULL;

    if(RPMessage_isLinuxCore(remoteCoreId))
    {
        /* for linux we need to send the TX VRING ID in the mailbox message */
        txMsgValue = RPMESSAGE_LINUX_TX_VRING_ID;
    }

    oldIntState = HwiP_disable();

    used = &vringObj->used->ring[vringObj->used->idx % vringObj->vringNumBuf];
    used->id = vringBufId;
    used->len = dataLen;
    vringObj->used->idx++;

    #if defined(__aarch64__) || defined(__arm__)
    __asm__ __volatile__ ( "dsb sy"  "\n\t": : : "memory");
    __asm__ __volatile__ ( "isb sy"  "\n\t": : : "memory");
    #endif
    #if defined(_TMS320C6X)
    _mfence();
    _mfence();
    #endif

    HwiP_restore(oldIntState);

    IpcNotify_sendMsg(remoteCoreId,
        IPC_NOTIFY_CLIENT_ID_RPMSG,
        txMsgValue,
        1 /* wait for message to be posted */
        );
}

void RPMessage_vringCheckEmptyTxBuf(uint16_t remoteCoreId)
{
    RPMessage_Core *coreObj = &gIpcRpmsgCtrl.coreObj[remoteCoreId];
    RPMessage_Vring *vringObj = &coreObj->vringTxObj;
    uint32_t isNewEmptyBuf = 1;
    uint32_t oldIntState;

    oldIntState = HwiP_disable();

    if (vringObj->lastAvailIdx == vringObj->avail->idx)
    {
        isNewEmptyBuf = 0;
    }

    HwiP_restore(oldIntState);

    if(isNewEmptyBuf)
    {
        SemaphoreP_post(&coreObj->newEmptyVringBufSem);
    }
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Wanglili、

    您能给我指一下您得到这些函数的文件吗? 在对 ti-rpmsg-char、rpmsg_char_zerocopy 或 Linux 驱动程序进行初始搜索时、我看不到它们。

    此致、

    Nick

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    我共享的库文件用于实时内核。 当实时内核接收到来自非实时内核的消息时、它通常会禁用并重新启用中断处理程序内的中断。 如果报文发送过于频繁、这可能会导致实时内核中的其他中断丢失。我们是否可以使用轮询而不是中断驱动的报文接收方法? 如果是、您能否提供相关的实施示例?

    C:\ti\mcu_plus_sdk_am64x_08_06_00_43\source\drivers\ipc_rpmsg   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Wanglili、

    我正在将您的问题发送给另一位团队成员进行评论。 如果您在几个工作日内未收到回复、请随时 ping 通该主题。

    此致、

    Nick

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Wanglili、

    我共享的库文件用于实时内核。 当实时内核接收到来自非实时内核的消息时、它通常会禁用并重新启用中断处理程序内的中断。 [/报价]

    您引用的是  HwiP_disable()吗? 如果没有、请向我说明您指的是代码的哪个部分?

    在后台、下面的 IPC RPmsg 使用 IPC Notify、进而使用 中断硬件机制来中断接收内核。 将 IPC RPmsg 更改为轮询将需要在我的脑海中完成重新工作。

    AM64x MCU+ SDK:IPC RPMessage

    AM64x MCU+ SDK:IPC Notify

    您可能会直接使用 IPC Notify 进行最关键的通信。  

    谢谢您、

    Paula

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    为了阐明 Paula 的注释、支持 IPC Notify 以实现 MCU+内核之间的通信。 虽然 Linux 有一个低级邮箱驱动程序可供其他更高级别的 Linux 驱动程序(如 RPMsg)使用、但 TI 不为将邮箱暴露于 Linux 用户空间之外提供软件支持。

    此致、

    Nick

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢、我理解。

    他说:"我已就刚才提出的问题跟进了很长时间、但仍未收到回应。 我希望您能为此提供帮助。"

    e2e.ti.com/.../5809724