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.

[参考译文] AM62P:AM62P:ipc_notify 如何确定邮箱 FIFO 队列中的消息数

Guru**** 2694635 points

Other Parts Discussed in Thread: AM62P, SYSCONFIG

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1585603/am62p-am62p-ipc_notify-how-to-determine-the-number-of-messages-in-mailbox-fifo-queue

部件号: AM62P
主题: SysConfig 中讨论的其他器件

您好、

我尝试在 WKUP 和 MCU 之间建立 IPC、而我使用的 MCU+SDK 版本为 11.01.08。 当前状态是我可以从 WKUP 向 MCU 发送一条消息、而我想在从 WKUP 向 MCU 发送多条消息时确定邮箱 FIFO 队列中的消息数。

根据 TRM、我发现我需要读取 Mailbox_MSG_STATUS_y、Mailbox cluster0 Mailbox_MSG_STATUS 的地址为 0x290000C0。

20251110-133700.jpg

screenshot-20251110-133826.png

在我的代码中、我使用的 FIFO ID 是 4。 根据我在“ipc_notify_V0_mailbox.h"中“中找到的公式、我在调用“IpcNotify_sendMsg"后“后读取了地址 0x290000D0、但我发现此寄存器的值没有变化(始终=0)。

我的问题是:

  1. Mailbox_cluster 和 Mailbox_fifo 之间的关系是什么? 哪个 mailbox_cluster dose mailbox_fifo_4 属于?
  2.  如果我想读取 fifo_4 的 Mailbox_MSG_STATUS、地址 0x290000D0 是否正确?

我在下面附上了测试代码。

uint32_t gClientId_low = 4u;        // client id for low 16bit address

status = IpcNotify_registerClient(gClientId_low, ipc_notify_msg_handler_wkup_lowAddr, NULL);
IpcNotify_syncAll(SystemP_WAIT_FOREVER);

uint32_t low16bit_addr = 0x1234;
uint32_t high16bit_addr = 0x5678;
uint32_t* MAILBOX_MSG_STATUS_4 = (uint32_t*) 0x290200D0;
uint32_t  msgCnt_mailbox4 = *MAILBOX_MSG_STATUS_4 & 0x0f; 
status = IpcNotify_sendMsg(gRemoteCoreId[0], gClientId_low, low16bit_addr, 1);
uint32_t  msgCnt_mailbox4_1 = *MAILBOX_MSG_STATUS_4 & 0x0f; 
status = IpcNotify_sendMsg(gRemoteCoreId[0], gClientId_low, high16bit_addr, 1);
uint32_t  msgCnt_mailbox4_2 = *MAILBOX_MSG_STATUS_4 & 0x0f; 

BR、

Bomiao

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

    你好,让我看看,明天回来给你

    谢谢你

    Paula

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

    嗨、Bomiao、我认为主要问题是您使用的是 CLIENT_ID 作为硬件 FIFO ID。

    从 source\drivers\ipc_notify\V0\ipx\am62px\ soc ipc_notify_v0_cfg.c 我们有(嗅探代码):

     * --------------------------------
     *  Cluster | FIFO |     IPC
     * --------------------------------
     *   0      |  0   | WKUP R5F -> A53
     *   0      |  1   | A53      -> WKUP R5F
     *   1      |  0   | MCU R5F  -> A53
     *   1      |  1   | A53      -> MCU R5F
     *   2      |  0   | MCU R5F  -> WKUP R5F
     *   2      |  1   | WKUP R5F -> MCU R5F
     *
     * User ID:
     *     MCU R5F Rx : 2
     *     WKUP R5F Rx: 3
     *     A53 Rx     : 0
     */
    IpcNotify_MailboxConfig gIpcNotifyMailboxConfig[CSL_CORE_ID_MAX][CSL_CORE_ID_MAX] =
    {
        /* from MCU R5FSS0-0 */
        {
            { /* to MCU R5FSS0-0 */
                MAILBOX_UNUSED
            },
            { /* to WKUP R5FSS0-0 */
                2U, 0U, 3U
            },
            { /* to A53SS0_0 */
                1U, 0U, 0U
            },
            { /* to A53SS0_1 */
                MAILBOX_UNUSED
            },
            { /* to A53SS1_0 */
                MAILBOX_UNUSED
            },
            { /* to A53SS1_1 */
                MAILBOX_UNUSED
            },
            { /* to HSM_R5FSS0_0 */
                MAILBOX_UNUSED
            },
        },
        /* from WKUP R5FSS0-0 */
        {
            { /* to MCU R5FSS0-0 */
                2U, 1U, 2U
            },
            { /* to WKUP R5FSS0-0 */
                MAILBOX_UNUSED
            },
            { /* to A53SS0_0 */
                0U, 0U, 0U
            },
            { /* to A53SS0_1 */
                MAILBOX_UNUSED
            },
            { /* to A53SS1_0 */
                MAILBOX_UNUSED
            },
            { /* to A53SS1_1 */
                MAILBOX_UNUSED
            },
            { /* to HSM_R5FSS0_0 */
                MAILBOX_UNUSED
            },
        },

    /*来自 WKUP R5FSS0-0 */
      {/*到 MCU R5FSS0-0 */
        2U、1U、2U  //邮箱群集 2、FIFO 1、用户 ID 2
      }、
    因此、 WKUP_>MCU 使用的是  FIFO 1。 然后、如果要读取 WKUP -> MCU R5F 的邮箱消息状态、则应为:
    1) 从 TRM、我们有邮箱基址群集 2 + MSG 状态偏移为 2902 00C0h  
    2) 从 source\drivers\ipc_notify\V0\ ipc_notify_v0_mailbox.h  可以得出:
     
    #define MAILBOX_MSG_STATUS (BASEfifo)      (volatile uint32_t *)(((base)+ 0x0C0u)+(0x04u*((fifo)&(mailbox_MAX_FIFO - 1U)))
    像在嗅探代码中替换一样进行替换: uint32_t* MAILBOX_MSG_STATUS_4 = (uint32_t*) 0x290200C4 //(uint32_t *) 0x29020000 + 0x0C0 +(0x04 * 1)
    另外、最好使用 SDK 的辅助函数 (IpcNotify_mailboxGetNumMsg)、而不是手动读取和计算地址
    请告诉我、如果我们进行了上述更改、您可以读取  WKUP -> MCU R5F 的 FIFO 1 的 MAILBOX_MSG_STATUS
    谢谢您、
    Paula
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Paula、

    我已根据您的建议尝试将地址 0x290200D0 替换为 0x290200C4、但我仍然发现 Mailbox_MSG_STATUS_4 的值没有更改。 我在下面附上了测试代码。

    uint32_t low16bit_addr = 0x1234;
    uint32_t high16bit_addr = 0x5678;
    uint32_t* MAILBOX_MSG_STATUS_4 = (uint32_t*) 0x290200C4;
    uint32_t  msgCnt_mailbox4 = *MAILBOX_MSG_STATUS_4 & 0x0f; 
    status = IpcNotify_sendMsg(gRemoteCoreId[0], gClientId_low, low16bit_addr, 1);
    uint32_t  msgCnt_mailbox4_1 = *MAILBOX_MSG_STATUS_4 & 0x0f; 
    status = IpcNotify_sendMsg(gRemoteCoreId[0], gClientId_low, high16bit_addr, 1);
    uint32_t  msgCnt_mailbox4_2 = *MAILBOX_MSG_STATUS_4 & 0x0f; 

    BR、

    Bomiao

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

    尊敬的 Bomiao:  

    我认为 Mailbox_MSG_STATUS (0x290200C4) 的计算是正确的、但您是否可以使用辅助函数? 确认并避免任何可能的错误。  我将共享一个代码 、如下所示 未经过测试 它是基于我在其他地方所看到的,所以如果你想实施它,请仔细检查和调整它。 下面的代码只是为了提供一个想法。

    主要思路是提取邮箱基址 (mailboxBaseAddr) 和 FIFO ID (hwFifoId)、并使用 IpcNotify_mailboxGetNumMsg() 而不是手动计算和检查邮箱 MSG_STATUS 地址来获取 MSG 计数。
    此外、这还假设代码在 WKUP R5F 中运行。

    顺便说一下、为什么您不会看到消息可能是 MCU R5F ISR 运行得太快并清除消息? 我想这是不可能的事。“

    //Un tested snipped code //
    #include <drivers/ipc_notify/v0/ipc_notify_v0.h>
    #include <drivers/ipc_notify/v0/ipc_notify_v0_mailbox.h>
    
    // Assuming you're running this code on WKUP R5F
    uint16_t remoteCoreId = gRemoteCoreId[0];  // Should be CSL_CORE_ID_MCU_R5FSS0_0
    
    // Query the mailbox configuration
    IpcNotify_MailboxConfig *pMailboxConfig;
    pMailboxConfig = &gIpcNotifyMailboxConfig[IpcNotify_getSelfCoreId()][remoteCoreId];
    
    // Extract configuration
    // For WKUP->MCU it should be: mailboxId=2, hwFifoId=1, userId=2
    uint32_t mailboxBaseAddr = gIpcNotifyMailboxBaseAddr[pMailboxConfig->mailboxId];
    mailboxBaseAddr = (uint32_t)AddrTranslateP_getLocalAddr(mailboxBaseAddr);
    uint32_t hwFifoId = pMailboxConfig->hwFifoId;  // This should be 1, but let's confirm =)
    
    DebugP_log("Using Mailbox Cluster %d, FIFO %d, Address 0x%08X\r\n", 
               pMailboxConfig->mailboxId, hwFifoId, mailboxBaseAddr);
    
    // Check FIFO status before sending
    uint32_t msgCnt_before = IpcNotify_mailboxGetNumMsg(mailboxBaseAddr, hwFifoId);
    uint32_t isFull_before = IpcNotify_mailboxIsFull(mailboxBaseAddr, hwFifoId);
    
    DebugP_log("Before send: msgCnt=%d, isFull=%d\r\n", msgCnt_before, isFull_before);
    
    // Send first message (blocking)
    status = IpcNotify_sendMsg(remoteCoreId, gClientId_low, low16bit_addr, 1);
    
    // Check immediately after (might still be 0 if ISR ran??)
    uint32_t msgCnt_after1 = IpcNotify_mailboxGetNumMsg(mailboxBaseAddr, hwFifoId);
    DebugP_log("After 1st send: msgCnt=%d\r\n", msgCnt_after1);
    
    // Send second message
    status = IpcNotify_sendMsg(remoteCoreId, gClientId_low, high16bit_addr, 1);
    
    uint32_t msgCnt_after2 = IpcNotify_mailboxGetNumMsg(mailboxBaseAddr, hwFifoId);
    DebugP_log("After 2nd send: msgCnt=%d\r\n", msgCnt_after2);

    谢谢您、

    Paula

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

    您好 Paula、

    我遵循了您的建议、使用辅助函数而不是手动计算的地址。 现在测试结果是  PARAMBOL_MSG_STATUS 的值在第一次 IPC_Notify 发送后发生变化、但在第二次 IPC_Notify 发送后不会改变。 换句话说、调试日志如下所示:

    WKUP_R5FSS0_0:使用邮箱集群 2、FIFO 1、地址 0x29020000

    WKUP_R5FSS0_0:发送之前:msgCnt=0、isFull=0

    WKUP_R5FSS0_0:在第 1 次发送之后:msgCnt=1

    WKUP_R5FSS0_0:在第 2 次发送之后:msgCnt=1

    我想知道为什么这种现象会发生?

    我在下面附上了测试代码。

    // query the mailbox configuration
        IpcNotify_MailboxConfig *pMailboxConfig;
        pMailboxConfig = &gIpcNotifyMailboxConfig[CSL_CORE_ID_WKUP_R5FSS0_0][CSL_CORE_ID_MCU_R5FSS0_0];
    
        // extract mailbox config
        uint32_t mailboxBaseAddr = gIpcNotifyMailboxBaseAddr[pMailboxConfig->mailboxId];
        mailboxBaseAddr = (uint32_t)AddrTranslateP_getLocalAddr(mailboxBaseAddr);
        uint32_t hwFifoId = pMailboxConfig->hwFifoId;
        DebugP_log("Using Mailbox Cluster %d, FIFO %d, Address 0x%08X\r\n", pMailboxConfig->mailboxId, hwFifoId, mailboxBaseAddr);
    
        // Check FIFO status before sending
        uint32_t msgCnt_before = IpcNotify_mailboxGetNumMsg(mailboxBaseAddr, hwFifoId);
        uint32_t isFull_before = IpcNotify_mailboxIsFull(mailboxBaseAddr, hwFifoId);
        DebugP_log("Before send: msgCnt=%d, isFull=%d\r\n", msgCnt_before, isFull_before);
    
        status = IpcNotify_sendMsg(gRemoteCoreId[0], gClientId_low, low16bit_addr, 1);
        uint32_t msgCnt_after1 = IpcNotify_mailboxGetNumMsg(mailboxBaseAddr, hwFifoId);
        DebugP_log("After 1st send: msgCnt=%d\r\n", msgCnt_after1);
        
        status = IpcNotify_sendMsg(gRemoteCoreId[0], gClientId_low, high16bit_addr, 1);
        uint32_t msgCnt_after2 = IpcNotify_mailboxGetNumMsg(mailboxBaseAddr, hwFifoId);
        DebugP_log("After 2nd send: msgCnt=%d\r\n", msgCnt_after2);

    我还可以验证您对  MCU R5F ISR 运行速度过快的猜测、并清除消息以使 msgCnt 为 0。 当我在 IPC_Notify 发送后添加 1us 延迟、便发现 Mailbox_MSG_STATUS 的值为 0。 调试日志如下所示:

    WKUP_R5FSS0_0:使用邮箱集群 2、FIFO 1、地址 0x29020000

    WKUP_R5FSS0_0:发送之前:msgCnt=0、isFull=0

    WKUP_R5FSS0_0:在第 1 次发送之后:msgCnt=0

    WKUP_R5FSS0_0:在第 2 次发送之后:msgCnt=1

    相关代码如下所示:

    Status = IpcNotify_sendMsg (gRemoteCoreId[0]、gClientId_low、low16bit_addr、1);
    ClockP_USleep (1);
    uint32_t msgCnt_after1 = IpcNotify_mailboxGetNumMsg (mailboxBaseAddr、hwFifoId);
    DebugP_log(“在第一次发送之后:msgCnt=%d\r\n“、msgCnt_after1);

    BR、

    Bomiao

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

    您好 Paula、

    我还对 ipc_notify 性能有疑问。 参考 MCU+SDK 教程、平均消息延迟约为 1.24us。 我对这些参数的测量方法很好奇、您是否可以分享任何相关代码或教程?

    在我这边、我使用 ipc_notify_send 函数将一条 32 位消息从 WKUP 发送到 MCU、然后在 MCU 内核中立即将该消息发送回 WKUP。 我测量了间隔、得到的时间延迟约为 2ms、与 1.24us 相比有很大差异。

    我在下面附上了测试代码。

    #include <stdio.h>
    #include <inttypes.h>
    #include <kernel/dpl/ClockP.h>
    #include <kernel/dpl/SemaphoreP.h>
    #include <drivers/ipc_notify.h>
    #include "kernel/dpl/DebugP.h"
    #include "kernel/dpl/SystemP.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    
    #include "emmc.h"
    #include "ethData.h"
    
    /* client ID that is used to send and receive messages */
    uint32_t gClientId_low = 4u;        // client id for low 16bit address
    uint32_t gClientId_high = 5u;       // client id for high 16bit address
    
    /* semaphore's used to indicate a main core has finished all message exchanges */
    SemaphoreP_Object gMainDoneSem[CSL_CORE_ID_MAX];
    
    #if defined(SOC_AM62PX)
    /* main core that starts the message exchange */
    uint32_t gMainCoreId = CSL_CORE_ID_WKUP_R5FSS0_0;
    /* remote cores that echo messages from main core, make sure to NOT list main core in this list */
    uint32_t gRemoteCoreId[] = {
        CSL_CORE_ID_MCU_R5FSS0_0,
        CSL_CORE_ID_MAX /* this value indicates the end of the array */
    };
    #endif
    /* semaphore's used to indicate a main core has finished all message exchanges */
    SemaphoreP_Object sLowAddrDone;
    SemaphoreP_Object sHighAddrDone;
    
    uint8_t EmmcRxBuf[3036042]__attribute__((aligned(128U)));
    extern uint8_t SWC_AppEthernRtpDataTwo[3036042] __attribute__((aligned(128U))); 
    
    volatile uint32_t low_addr = 0;
    volatile uint32_t high_addr = 0;
    
    void ipc_notify_msg_handler_wkup_lowAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        low_addr = msgValue;
        DebugP_log("The echoed data is %u.", low_addr);
        SemaphoreP_post(&sLowAddrDone);
    }
    
    void ipc_notify_msg_handler_wkup_highAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        high_addr = msgValue;
        DebugP_log("The echoed data is %u.", high_addr);
        SemaphoreP_post(&sHighAddrDone);
    }
    
    void ipc_notify_echo_main_core_start()
    {
        int32_t status = SystemP_SUCCESS;
        uint64_t curTime;
    
        // /*   start of read eMMC data   */
        // uint32_t blockCnt = MMCSD_getBlockCount(gMmcsdHandle[CONFIG_MMCSD0]);
        // DebugP_log("eMMC blockcount is %u", blockCnt);
        
        // status = emmc_write(SWC_AppEthernRtpDataTwo, 0x1000U, 5930);
        // status = emmc_read(EmmcRxBuf, 0x1000U, 5930);
    
        // MMCSD_close(gMmcsdHandle[CONFIG_MMCSD0]);
        // gMmcsdHandle[CONFIG_MMCSD0] = NULL;
        // MMCSD_deinit();
        // /*  end of read eMMC data   */
    
        SemaphoreP_constructBinary(&sLowAddrDone, 0);
        SemaphoreP_constructBinary(&sHighAddrDone, 0);
        /* register a handler to receive messages */
        status = IpcNotify_registerClient(gClientId_low, ipc_notify_msg_handler_wkup_lowAddr, NULL);
        status = IpcNotify_registerClient(gClientId_high, ipc_notify_msg_handler_wkup_highAddr, NULL);
        /* wait for all cores to be ready */
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
    
        uint32_t* pBuf = EmmcRxBuf; 
        uint32_t  buf_addr = (uint32_t) pBuf;
        uint32_t  low16bit_addr = buf_addr & 0x0000FFFF;
        uint32_t  high16bit_addr = (buf_addr >> 16) & 0x0000FFFF;
    
        uint32_t* MAILBOX_MSG_STATUS_4 = (uint32_t*) 0x290200D0;
        uint32_t  msgCnt_mailbox4 = *MAILBOX_MSG_STATUS_4 & 0x0f; 
        status = IpcNotify_sendMsg(gRemoteCoreId[0], gClientId_low, low16bit_addr, 1);
        uint32_t  msgCnt_mailbox4_1 = *MAILBOX_MSG_STATUS_4 & 0x0f; 
        status = IpcNotify_sendMsg(gRemoteCoreId[0], gClientId_low, high16bit_addr, 1);
        uint32_t  msgCnt_mailbox4_2 = *MAILBOX_MSG_STATUS_4 & 0x0f; 
    
        status = IpcNotify_sendMsg(gRemoteCoreId[0], gClientId_high, high16bit_addr, 1);
        curTime = ClockP_getTimeUsec();
    
        SemaphoreP_pend(&sLowAddrDone, SystemP_WAIT_FOREVER);
        SemaphoreP_pend(&sHighAddrDone, SystemP_WAIT_FOREVER);
        curTime = ClockP_getTimeUsec() - curTime;
        DebugP_log("[IPC Notify] The total echo time is %u.", curTime);
    
        uint32_t full_addr = ( high_addr << 16 ) | ( low_addr & 0x0000FFFF);
        uint8_t* pRecoverData = (uint8_t*) full_addr;
        
        uint8_t rData_0 = pRecoverData[8];
        uint8_t rData_1 = pRecoverData[9];
        uint8_t rData_2 = pRecoverData[10];
        uint8_t rData_3 = pRecoverData[11];
    
    }
    
    void ipc_notify_msg_handler_mcu_lowAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        uint32_t data_l = msgValue;
        DebugP_log("The received data in MCU is %u. \r\n", data_l);
    
        IpcNotify_sendMsg(remoteCoreId, localClientId, data_l, 1);
    }
    
    void ipc_notify_msg_handler_mcu_highAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        uint32_t data_h = msgValue;
        DebugP_log("The received data in MCU is %u. \r\n", data_h);
    
        IpcNotify_sendMsg(remoteCoreId, localClientId, data_h, 1);
    }
    
    void ipc_notify_echo_remote_core_start()
    {
        int32_t status;
    
        /* register a handler to receive messages */
        status = IpcNotify_registerClient(gClientId_low, ipc_notify_msg_handler_mcu_lowAddr, NULL);
        status = IpcNotify_registerClient(gClientId_high, ipc_notify_msg_handler_mcu_highAddr, NULL);
    
        /* wait for all cores to be ready */
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
    
    }
    
    void dloop()
    {
        volatile uint32_t loop = 1;
        while(loop)
            ;
    }
    
    void ipc_notify_echo_main(void *args)
    {
        dloop();
        if(IpcNotify_getSelfCoreId()==gMainCoreId)
        {
            ipc_notify_echo_main_core_start();
        }
        else
        {
            ipc_notify_echo_remote_core_start();
        }
    
    }

    BR、

    Bomiao

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

    谢谢 Bomiao、我认为在您的第一次测试中、从上面 开始、您在第二次发送中只看到一个 msgCnt、因为 MCU R5F ISR 会将其清除。 我们可以尝试进行其他实验来证明/证明这一点、但我想您的主要问题是延迟、因为这是您的最新问题。

    对此、请查看以下 E2E 链接、其中同事回答了类似的问题:

    AM6442:IPC RPMSG 示例代码 — 处理器-内部论坛 — 处理器-内部 — TI E2E 支持论坛

    由此、我们可得出:

    “测试代码未绑定到预编译的 MCU+ SDK 下载中。 但可在 Github 版本的 MCU+ SDK 中找到、此处为:
    https://github.com/TexasInstruments/mcupsdk-core/blob/next/test/drivers/ipc_notify/test_ipc_notify.c#L348

    例如,对于 IPC Notif,请参见函数 test_notifyOneToOneBackToBack ()

    请注意、这些只是通过往返测量计算得出的平均值。 因此、如果您的客户正在寻找最坏情况下的值、他们需要修改代码。“

    谢谢您、

    Paula

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

    您好 Paula、

    根据您提供的 GitHub 链接、现在我可以测试 IPC_Notify 的性能、并参阅 MCU+SDK 教程获得类似的结果。 我真的很感谢您的友好帮助。

    对于读取寄存器  MABOXER_MSG_STATUS 时产生错误结果的问题、我想知道是否有任何措施来控制 MCU 内核中的消息处理速度?  

    BR、

    Bomiao

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

    嗨、Bomia、我想、出于调试目的、我们可以尝试禁用 ISR。 但是、在我们这样做(或任何其他方法)之前、请帮助我再次阐明使用 Mailbox_MSG_STATUS 的目的。 您需要此信息用于什么?

    谢谢您、

    Paula

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

    您好 Paula、

    当前的要求是我需要将四个 3MB 数据阵列从 WKUP 传输到 MCU。 为了确保传输速度、我决定传输该阵列的 32 位地址、而不是数据阵列本身。 由于最大消息值为 0x10000000、因此我无法一次传输整个 32 位地址。 我决定将一个 32 位地址拆分为两部分:low16bit_addr 和 high16bit_addr;并将两部分从 WKUP 发送到 MCU。  

    因此、如果我想在 MCU 中接收数据数组的四个正确地址、则需要监控 FIFO 中的消息计数。  

    BR、

    Bomiao

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

    得到它 Bormiao ,因为你已经在使用共享内存的 3MB 数据数组(对吗?),可能和容易的解决方案是也使用 一个小的 32 位缓冲区在共享内存中的地址,并使用 IpcNotify_sendMsg() 通知 MCU 当地址准备就绪时,用一条消息而不是两条消息。

    谢谢您、

    Paula

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

    您好 Paula、

    我不确定是否使用共享内存来存储 3MB 数据阵列。 当前的情况是这些数据存储在 eMMC 闪存中、我从 eMMC 中读取这些数据、并声明数组以将其存储在 WKUP 中。 然后、我通过 IPC_notify 将数组地址从 WKUP 传输到 MCU。

    我认为 IPC 可以被视为某种“共享存储器“、因为 WKUP 和 MCU 都可以访问 IPC_Mailbox。 AM62p 还有其他某种“共享存储器“。 如果是、您能否分享有关共享存储器的相关链接?   

    BR、

    Bomiao

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

    我在这一周的其余时间里都不在办公室。 让我在下周初回到您的身边。  

    谢谢你  

    Paula

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

    嗨、Bomiao

    我们的 IPC RP 消息示例在共享存储器中使用 VRING (AM62Px MCU+ SDK:IPC RPMessage)、您可以查看该示例以创建类似的方法  

    例如、从 wkup-R5fss0-0 example.sycfg CONFIG_MPU_RTOS_VRING1 中、我们得到:

    从 MCU-r5fss0-0 example.sycfg config_mpu_rtos_VRING1、我们可以得到:

    要点包括:

    -两个内核在 DDR 中与共享存储器具有相同的区域

    -属性为“非高速缓存“(以确保共享内存在内核之间保持一致)

    沿着这些线路的东西可用于创建一个较小的共享缓冲区、两个内核都可以访问该缓冲区。

    谢谢您、

    Paula

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

    嗨、Bomiao、我认为问题与定义为全局变量的“buf_addr1"和“和“buf_addr2"有关“有关、稍后相同的名称被定义为局部变量。 因此、我想 MCU 实际上会获得(读取)未初始化的全局共享变量。

    //Global
    uint32_t buf_addr1 __attribute__((section(".eth_data_addr"),aligned(4)));
    uint32_t buf_addr2 __attribute__((section(".eth_data_addr"),aligned(4)));
    
    void ipc_notify_echo_main_core_start()
    {
        int32_t status = SystemP_SUCCESS;
        uint64_t curTime;
    
        SemaphoreP_constructBinary(&sLowAddrDone, 0);
        /* register a handler to receive messages */
        status = IpcNotify_registerClient(gClientId_low_rx, ipc_notify_msg_handler_wkup_lowAddr, NULL);
        /* wait for all cores to be ready */
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
    
        uint32_t* pBuf1 = EmmcRxBuf1; 
        uint32_t  buf_addr1 = (uint32_t) pBuf1; //Local same name
        
        uint32_t* pBuf2 = EmmcRxBuf2; 
        uint32_t  buf_addr2 = (uint32_t) pBuf2;

    如果我是对的,那么一个简单的解决方法是:

    // Write addresses to GLOBAL shared variables
    buf_addr1 = (uint32_t)EmmcRxBuf1;
    buf_addr2 = (uint32_t)EmmcRxBuf2;

    如果效果很好!如果没有、另一个想法可能是 IPC Notify 仅通知并使用共享存储器缓冲区来共享地址。  

    如下例代码所示:

    ///////////////////////////////////////////////////////////////////////
    //Shared Structure (Both cores)
    typedef struct {
        uint32_t buffer1_addr;
        uint32_t buffer2_addr;
        uint32_t buffer3_addr;
        uint32_t buffer4_addr;
    } SharedBufferAddresses;
    
    SharedBufferAddresses gSharedAddrs __attribute__((section(".eth_data_addr"), aligned(4)));
    
    ///////////////////////////////////////////////////////////////////////
    //WKUP Code
    
    //Four 3MB buffers
    uint8_t gWkupBuffer1[3*1024*1024] __attribute__((aligned(128)));
    uint8_t gWkupBuffer2[3*1024*1024] __attribute__((aligned(128)));
    uint8_t gWkupBuffer3[3*1024*1024] __attribute__((aligned(128)));
    uint8_t gWkupBuffer4[3*1024*1024] __attribute__((aligned(128)));
    
    void wkup_main(void) {
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
        
        // Write addresses to shared memory
        gSharedAddrs.buffer1_addr = (uint32_t)gWkupBuffer1;
        gSharedAddrs.buffer2_addr = (uint32_t)gWkupBuffer2;
        gSharedAddrs.buffer3_addr = (uint32_t)gWkupBuffer3;
        gSharedAddrs.buffer4_addr = (uint32_t)gWkupBuffer4;
        
        // Notify MCU addresses are ready
        IpcNotify_sendMsg(CSL_CORE_ID_MCU_R5FSS0_0, 5, 0x1, 1);
    }
    
    
    ///////////////////////////////////////////////////////////////////////
    //MCU Code
    
    SemaphoreP_Object gSem;
    
    void mcu_main(void) {
        SemaphoreP_constructBinary(&gSem, 0);
        IpcNotify_registerClient(5, mcu_handler, NULL);  // Ready handler
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
        
        // Wait for WKUP to signal addresses ready
        SemaphoreP_pend(&gSem, SystemP_WAIT_FOREVER);
    
        uint32_t addr1 = gSharedAddrs.buffer1_addr;
        uint32_t addr2 = gSharedAddrs.buffer2_addr;
        uint32_t addr3 = gSharedAddrs.buffer3_addr;
        uint32_t addr4 = gSharedAddrs.buffer4_addr;
        
        // Use WKUP's buffers to do something..
        uint8_t* pBuf1 = (uint8_t*)addr1;
    }
    
    void mcu_handler(uint16_t remoteCoreId, uint16_t localClientId, 
                     uint32_t msgValue, void *args) {
        SemaphoreP_post(&gSem);  // WKUP signaled addresses ready
    }

    谢谢您、

    Paula

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

    您好 Paula、

    我遵循了您的建议并测试了修改后的代码、但它不起作用。 我都尝试了对 uint32_t 变量使用共享存储器、对结构使用共享存储器及其结果是相同的。 我认为上述两种方法之间没有本质区别、因为它们只是以不同的格式将数据放在特定地址中。 在 WKUP 中进行调试时、我发现缓冲区的地址已经存储在 0xA0000000 中。 我可以附上下面相应的屏幕截图。

       

    我还可以附上下面的相关代码。

    #include <stdio.h>
    #include <inttypes.h>
    #include <kernel/dpl/ClockP.h>
    #include <kernel/dpl/SemaphoreP.h>
    #include <drivers/ipc_notify.h>
    #include "kernel/dpl/DebugP.h"
    #include "kernel/dpl/SystemP.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include <drivers/ipc_notify/v0/ipc_notify_v0.h>
    #include <drivers/ipc_notify/v0/ipc_notify_v0_mailbox.h>
    
    #include "emmc.h"
    #include "ethData.h"
    
    /* client ID that is used to send and receive messages */
    uint32_t gClientId_low_tx = 4u;        // mailbox WKUP to MCU
    uint32_t gClientId_low_rx = 5u;       // mailbox MCU to WKUP
    
    #if defined(SOC_AM62PX)
    /* main core that starts the message exchange */
    uint32_t gMainCoreId = CSL_CORE_ID_WKUP_R5FSS0_0;
    /* remote cores that echo messages from main core, make sure to NOT list main core in this list */
    uint32_t gRemoteCoreId[] = {
        CSL_CORE_ID_MCU_R5FSS0_0,
        CSL_CORE_ID_MAX /* this value indicates the end of the array */
    };
    #endif
    
    /* semaphore's used to indicate a main core has finished all message exchanges */
    SemaphoreP_Object sLowAddrDone;
    SemaphoreP_Object sHighAddrDone;
    
    uint8_t EmmcRxBuf1[4]__attribute__((aligned(128U))) = {0x1B, 0x2C, 0x2A, 0x3B};
    uint8_t EmmcRxBuf2[4]__attribute__((aligned(128U))) = {0x0A, 0x0C, 0x0A, 0x0B};
    
    // uint32_t buf_addr1 __attribute__((section(".eth_data_addr"),aligned(4)));
    // uint32_t buf_addr2 __attribute__((section(".eth_data_addr"),aligned(4)));
    
    typedef struct {
        uint32_t buf1_addr;
        uint32_t buf2_addr;
    }SharedBuffAddr;
    
    SharedBuffAddr gSharedAddrs __attribute__((section(".eth_data_addr"),aligned(4)));
    
    uint32_t rx_arr_mcu[2];
    uint32_t rx_cnt_mcu = 0;
    
    void ipc_notify_msg_handler_wkup_lowAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        rx_arr_mcu[rx_cnt_mcu] = msgValue;
        rx_cnt_mcu ++;
        if (rx_cnt_mcu == 2)
        {
            SemaphoreP_post(&sLowAddrDone);
        
        }
    
    }
    
    void ipc_notify_echo_main_core_start()
    {
        int32_t status = SystemP_SUCCESS;
        uint64_t curTime;
    
        SemaphoreP_constructBinary(&sLowAddrDone, 0);
        /* register a handler to receive messages */
        status = IpcNotify_registerClient(gClientId_low_rx, ipc_notify_msg_handler_wkup_lowAddr, NULL);
        /* wait for all cores to be ready */
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
    
        // uint32_t* pBuf1 = EmmcRxBuf1; 
        // buf_addr1 = (uint32_t) pBuf1;
        
        // uint32_t* pBuf2 = EmmcRxBuf2; 
        // buf_addr2 = (uint32_t) pBuf2;
    
        gSharedAddrs.buf1_addr = (uint32_t) EmmcRxBuf1;
        gSharedAddrs.buf2_addr = (uint32_t) EmmcRxBuf2;
    
        uint32_t eth_flag = 0x01;
        status = IpcNotify_sendMsg(gRemoteCoreId[0], gClientId_low_tx, eth_flag, 1);
        
        curTime = ClockP_getTimeUsec();
        SemaphoreP_pend(&sLowAddrDone, SystemP_WAIT_FOREVER);
        curTime = ClockP_getTimeUsec() - curTime;
        DebugP_log("[IPC Notify] The total echo time is %u. \r\n", curTime);
    
    }
    
    void ipc_notify_msg_handler_mcu_lowAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        if (msgValue == 0x01)
        {
            uint32_t eth_data_addr_recov1 = gSharedAddrs.buf1_addr;
            uint32_t eth_data_addr_recov2 = gSharedAddrs.buf2_addr;
            IpcNotify_sendMsg(remoteCoreId, gClientId_low_rx, eth_data_addr_recov1, 1);
            IpcNotify_sendMsg(remoteCoreId, gClientId_low_rx, eth_data_addr_recov2, 1);
        
        }
            
    }
    
    void ipc_notify_msg_handler_mcu_highAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        uint32_t data_h = msgValue;
        DebugP_log("The received data in MCU is %u. \r\n", data_h);
    
        IpcNotify_sendMsg(remoteCoreId, localClientId, data_h, 1);
    }
    
    void ipc_notify_echo_remote_core_start()
    {
        int32_t status;
        /* register a handler to receive messages */
        status = IpcNotify_registerClient(gClientId_low_tx, ipc_notify_msg_handler_mcu_lowAddr, NULL);
    
        /* wait for all cores to be ready */
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
    
    }
    
    void dloop()
    {
        volatile uint32_t loop = 1;
        while(loop)
            ;
    }
    
    void ipc_notify_echo_main(void *args)
    {
        dloop();
        if(IpcNotify_getSelfCoreId()==gMainCoreId)
        {
            ipc_notify_echo_main_core_start();
        }
        else
        {
            ipc_notify_echo_remote_core_start();
        }
    
    }

    此致、

    Bomiao

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

    嗨、Bomiao、问题是否与之前相同、这意味着您 无法进入回调函数“ipc_notify_msg_handler_wkup_lowAddr"?“? 还是 有所不同?

    谢谢您、

    Paula

     

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

    您好 Paula、

    问题与之前相同、即我无法  在 WKUP 中进入回调函数“ipc_notify_msg_handler_wkup_lowAddr"。“。

    此致、

    Bomiao

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

    嗨、Bomiao、我不确定可能是什么问题。 从您的帖子和最新的共享代码中,我看到您添加了 dloop () 来连接 JTAG。 您可能可以通过单步执行代码来调查此问题、但无论如何、让我与一组打印语句共享您的代码、看看我们是否能找出问题所在。 我知道我们不应该在 IPC Notify 回调函数中添加 DebugP_log ()(因为它们在 ISR 上下文中运行),但我们要为调试目的这样做。

    我已经添加了一组 DebugP_log() 调用和一些 DebugP_logError 调用、因为我不确定您如何配置 SysConfig 日志。 如果我在打印地址时出现错误、请随时更正我、并删除多余的打印声明。

    主要思路是看看事情到底在哪里发生了故障

    #include <stdio.h>
    #include <inttypes.h>
    #include <kernel/dpl/ClockP.h>
    #include <kernel/dpl/SemaphoreP.h>
    #include <drivers/ipc_notify.h>
    #include "kernel/dpl/DebugP.h"
    #include "kernel/dpl/SystemP.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include <drivers/ipc_notify/v0/ipc_notify_v0.h>
    #include <drivers/ipc_notify/v0/ipc_notify_v0_mailbox.h>
    
    #include "emmc.h"
    #include "ethData.h"
    
    /* client ID that is used to send and receive messages */
    uint32_t gClientId_low_tx = 4u;        // mailbox WKUP to MCU
    uint32_t gClientId_low_rx = 5u;       // mailbox MCU to WKUP
    
    #if defined(SOC_AM62PX)
    /* main core that starts the message exchange */
    uint32_t gMainCoreId = CSL_CORE_ID_WKUP_R5FSS0_0;
    /* remote cores that echo messages from main core, make sure to NOT list main core in this list */
    uint32_t gRemoteCoreId[] = {
        CSL_CORE_ID_MCU_R5FSS0_0,
        CSL_CORE_ID_MAX /* this value indicates the end of the array */
    };
    #endif
    
    /* semaphore's used to indicate a main core has finished all message exchanges */
    SemaphoreP_Object sLowAddrDone;
    SemaphoreP_Object sHighAddrDone;
    
    uint8_t EmmcRxBuf1[4]__attribute__((aligned(128U))) = {0x1B, 0x2C, 0x2A, 0x3B};
    uint8_t EmmcRxBuf2[4]__attribute__((aligned(128U))) = {0x0A, 0x0C, 0x0A, 0x0B};
    
    // uint32_t buf_addr1 __attribute__((section(".eth_data_addr"),aligned(4)));
    // uint32_t buf_addr2 __attribute__((section(".eth_data_addr"),aligned(4)));
    
    typedef struct {
        uint32_t buf1_addr;
        uint32_t buf2_addr;
    }SharedBuffAddr;
    
    SharedBuffAddr gSharedAddrs __attribute__((section(".eth_data_addr"),aligned(4)));
    
    uint32_t rx_arr_mcu[2];
    uint32_t rx_cnt_mcu = 0;
    
    void ipc_notify_msg_handler_wkup_lowAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        //PC-- let see if we reach here.. to see if we receive the message from MCU and ISR is fired and callback invoked. If so is core id correct?, client id correct?, msg correct?
        DebugP_log("[WKUP HANDLER] inside handler core=%d, client=%d, msg=0x%08X, count=%d\r\n",
                   remoteCoreId, localClientId, msgValue, rx_cnt_mcu);
        
        rx_arr_mcu[rx_cnt_mcu] = msgValue;
        rx_cnt_mcu ++;
        if (rx_cnt_mcu == 2)
        {
            DebugP_log("[WKUP] Received both addresses: 0x%08X, 0x%08X\r\n",
                       rx_arr_mcu[0], rx_arr_mcu[1]);
            SemaphoreP_post(&sLowAddrDone);
        
        }
    
    }
    
    void ipc_notify_echo_main_core_start()
    {
        int32_t status = SystemP_SUCCESS;
        uint64_t curTime;
    
        DebugP_log("[WKUP] WKUP core ID (main): %d\r\n", IpcNotify_getSelfCoreId());
        DebugP_log("[WKUP] MCU core ID (remote): %d\r\n", gRemoteCoreId[0]);
        DebugP_log("[WKUP] gSharedAddrs at 0x%X\r\n", (uint32_t)&gSharedAddrs);
        
        SemaphoreP_constructBinary(&sLowAddrDone, 0);
        /* register a handler to receive messages */
        DebugP_log("[WKUP] Registering handler for client ID %d\r\n", gClientId_low_rx);
        status = IpcNotify_registerClient(gClientId_low_rx, ipc_notify_msg_handler_wkup_lowAddr, NULL);
        DebugP_log("[WKUP] Register status: %d\r\n", status);
        if (status != SystemP_SUCCESS) {
            DebugP_logError("[WKUP] ERROR: Handler registration FAILED. Status=%d\r\n", status);
        }
        
        /* wait for all cores to be ready */
        DebugP_log("[WKUP] Waiting for sync\r\n");
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
        DebugP_log("[WKUP] Sync completed\r\n");
    
        // uint32_t* pBuf1 = EmmcRxBuf1; 
        // buf_addr1 = (uint32_t) pBuf1;
        
        // uint32_t* pBuf2 = EmmcRxBuf2; 
        // buf_addr2 = (uint32_t) pBuf2;
    
        gSharedAddrs.buf1_addr = (uint32_t) EmmcRxBuf1;
        gSharedAddrs.buf2_addr = (uint32_t) EmmcRxBuf2;
        
        DebugP_log("[WKUP] gSharedAddrs=0x%X: buf1_addr=0x%08X, buf2_addr=0x%08X\r\n", 
                   (uint32_t)&gSharedAddrs, gSharedAddrs.buf1_addr, gSharedAddrs.buf2_addr); //PC-- WKUP writing to shared memory
    
        uint32_t eth_flag = 0x01;
        DebugP_log("[WKUP] Before IpcNotify_sendMsg() to MCU (core %d, client %d, msg=0x%X)\r\n",
                   gRemoteCoreId[0], gClientId_low_tx, eth_flag);
        status = IpcNotify_sendMsg(gRemoteCoreId[0], gClientId_low_tx, eth_flag, 1);
        DebugP_log("[WKUP] Send status: %d\r\n", status); //PC-- let's double check if we reach here if status is 0 (success) or something else
        if (status != SystemP_SUCCESS) {
            DebugP_logError("[WKUP] ERROR: Send FAILED. Status=%d\r\n", status);
        }
        
        DebugP_log("[WKUP] Waiting for MCU responses (will block here if MCU doesn't respond)...\r\n");
        curTime = ClockP_getTimeUsec();
        SemaphoreP_pend(&sLowAddrDone, SystemP_WAIT_FOREVER);
        curTime = ClockP_getTimeUsec() - curTime;
        DebugP_log("[IPC Notify] The total echo time is %u. \r\n", curTime);
    
    }
    
    void ipc_notify_msg_handler_mcu_lowAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        //PC-- let see if we reach here.. to see if we receive the message from WKUP and ISR is fired and callback invoked. If so is core id correct?, client id correct?, msg correct?
        DebugP_log("[MCU HANDLER] inside handler core=%d, client=%d, msg=0x%X\r\n",
                   remoteCoreId, localClientId, msgValue);
        
        if (msgValue == 0x01)
        {
            uint32_t eth_data_addr_recov1 = gSharedAddrs.buf1_addr;
            uint32_t eth_data_addr_recov2 = gSharedAddrs.buf2_addr;
            
            if (eth_data_addr_recov1 == 0 && eth_data_addr_recov2 == 0) {
                DebugP_logError("[MCU] WARNING: Read all-zero addresses from shared memory!\r\n");
            }
            
            DebugP_log("[MCU] gSharedAddrs 0x%X: buf1_addr=0x%08X, buf2_addr=0x%08X\r\n",
                       (uint32_t)&gSharedAddrs, eth_data_addr_recov1, eth_data_addr_recov2);
            
            int32_t s1 = IpcNotify_sendMsg(remoteCoreId, gClientId_low_rx, eth_data_addr_recov1, 1);
            int32_t s2 = IpcNotify_sendMsg(remoteCoreId, gClientId_low_rx, eth_data_addr_recov2, 1);
            
            DebugP_log("[MCU] Send status: addr1=%d, addr2=%d\r\n", s1, s2); //PC-- let's double check if we reach here and if send status is OK
            if (s1 != SystemP_SUCCESS || s2 != SystemP_SUCCESS) {
                DebugP_logError("[MCU] ERROR: Send FAILED. s1=%d, s2=%d\r\n", s1, s2); //PC-- if send fails, we won't reach WKUP side handler. 
            }
        
        }
            
    }
    
    void ipc_notify_msg_handler_mcu_highAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        uint32_t data_h = msgValue;
        IpcNotify_sendMsg(remoteCoreId, localClientId, data_h, 1);
    }
    
    void ipc_notify_echo_remote_core_start()
    {
        DebugP_log("[MCU] MCU Core ID: %d\r\n", IpcNotify_getSelfCoreId());
        DebugP_log("[MCU] gSharedAddrs at 0x%X\r\n", (uint32_t)&gSharedAddrs);
        
        int32_t status;
        /* register a handler to receive messages */
        DebugP_log("[MCU] Registering handler for client ID %d\r\n", gClientId_low_tx);
        status = IpcNotify_registerClient(gClientId_low_tx, ipc_notify_msg_handler_mcu_lowAddr, NULL);
        DebugP_log("[MCU] Register status: %d\r\n", status);
        if (status != SystemP_SUCCESS) {
            DebugP_logError("[MCU] ERROR: Handler registration FAILED. Status=%d\r\n", status);
        }
    
        /* wait for all cores to be ready */
        DebugP_log("[MCU] Waiting for sync\r\n");
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
        DebugP_log("[MCU] Sync completed, and waiting for messages\r\n");
    
    }
    
    void dloop()
    {
        volatile uint32_t loop = 1;
        while(loop)
            ;
    }
    
    void ipc_notify_echo_main(void *args)
    {
        dloop();
        if(IpcNotify_getSelfCoreId()==gMainCoreId)
        {
            ipc_notify_echo_main_core_start();
        }
        else
        {
            ipc_notify_echo_remote_core_start();
        }
    
    }

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

    您好 Paula、

    首先,我非常感谢你的代码,好的评论,以及你的耐心。 我 在代码中添加了 DebugP_log (),并尝试查找失败的位置。 正如您提到的“我们不应该在 IPC Notify 回调函数中添加 DebugP_log ()“,我 可以 确认,即使代码输入可以通过 调用 DebugP_log () 成功进入回调函数,也不能在控制台上打印日志。 我已经根据一个 WKUP 工程验证了我的结论、该工程可以 成功将 msg 发送回 MCU。 因此、我认为我们不能依赖打印的日志来确定 MCU 代码是否进入 IPC Notify 回调函数。

    我在进入 MCU 内核开始时尝试读取共享存储器中的元素、发现这些元素并未保留。 我已将日志屏幕截图保存在 WKUP 和 MCU 中。  

      

    我想知道我是否需要采取额外措施来保护这些共享内存区域。 我附上下面的测试代码和相关项目。

    #include <stdio.h>
    #include <inttypes.h>
    #include <kernel/dpl/ClockP.h>
    #include <kernel/dpl/SemaphoreP.h>
    #include <drivers/ipc_notify.h>
    #include "kernel/dpl/DebugP.h"
    #include "kernel/dpl/SystemP.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include <drivers/ipc_notify/v0/ipc_notify_v0.h>
    #include <drivers/ipc_notify/v0/ipc_notify_v0_mailbox.h>
    
    // #include "emmc.h"
    // #include "ethData.h"
    
    /* client ID that is used to send and receive messages */
    uint32_t gClientId_low_tx = 4u;        // mailbox WKUP to MCU
    uint32_t gClientId_low_rx = 5u;       // mailbox MCU to WKUP
    
    #if defined(SOC_AM62PX)
    /* main core that starts the message exchange */
    uint32_t gMainCoreId = CSL_CORE_ID_WKUP_R5FSS0_0;
    /* remote cores that echo messages from main core, make sure to NOT list main core in this list */
    uint32_t gRemoteCoreId[] = {
        CSL_CORE_ID_MCU_R5FSS0_0,
        CSL_CORE_ID_MAX /* this value indicates the end of the array */
    };
    #endif
    
    /* semaphore's used to indicate a main core has finished all message exchanges */
    SemaphoreP_Object sLowAddrDone;
    SemaphoreP_Object sHighAddrDone;
    
    uint8_t EmmcRxBuf1[4]__attribute__((aligned(128U))) = {0x1B, 0x2C, 0x2A, 0x3B};
    uint8_t EmmcRxBuf2[4]__attribute__((aligned(128U))) = {0x0A, 0x0C, 0x0A, 0x0B};
    
    // uint32_t buf_addr1 __attribute__((section(".eth_data_addr"),aligned(4)));
    // uint32_t buf_addr2 __attribute__((section(".eth_data_addr"),aligned(4)));
    
    typedef struct {
        uint32_t buf1_addr;
        uint32_t buf2_addr;
    }SharedBuffAddr;
    
    SharedBuffAddr gSharedAddrs __attribute__((section(".eth_data_addr"),aligned(4)));
    
    uint32_t rx_arr_mcu[2];
    uint32_t rx_cnt_mcu = 0;
    
    void ipc_notify_msg_handler_wkup_lowAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        rx_arr_mcu[rx_cnt_mcu] = msgValue;
        rx_cnt_mcu ++;
        if (rx_cnt_mcu == 2)
        {
            SemaphoreP_post(&sLowAddrDone);
        
        }
    
    }
    
    void ipc_notify_echo_main_core_start()
    {
        int32_t status = SystemP_SUCCESS;
        uint64_t curTime;
    
        SemaphoreP_constructBinary(&sLowAddrDone, 0);
        /* register a handler to receive messages */
        DebugP_log("[WKUP] Registering handler for client ID %d\r\n", gClientId_low_rx);
        status = IpcNotify_registerClient(gClientId_low_rx, ipc_notify_msg_handler_wkup_lowAddr, NULL);
        DebugP_log("[WKUP] Register status: %d\r\n", status);
        /* wait for all cores to be ready */
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
    
        // uint32_t* pBuf1 = EmmcRxBuf1; 
        // buf_addr1 = (uint32_t) pBuf1;
        
        // uint32_t* pBuf2 = EmmcRxBuf2; 
        // buf_addr2 = (uint32_t) pBuf2;
    
        gSharedAddrs.buf1_addr = (uint32_t) EmmcRxBuf1;
        gSharedAddrs.buf2_addr = (uint32_t) EmmcRxBuf2;
        DebugP_log("[WKUP] gSharedAddrs=0x%X: buf1_addr=0x%08X, buf2_addr=0x%08X\r\n", 
                   (uint32_t)&gSharedAddrs, gSharedAddrs.buf1_addr, gSharedAddrs.buf2_addr); //PC-- WKUP writing to shared memory
    
        uint32_t eth_flag = 0x01;
        status = IpcNotify_sendMsg(gRemoteCoreId[0], gClientId_low_tx, eth_flag, 1);
        DebugP_log("[WKUP] Send status: %d\r\n", status);
        
        curTime = ClockP_getTimeUsec();
        SemaphoreP_pend(&sLowAddrDone, SystemP_WAIT_FOREVER);
        curTime = ClockP_getTimeUsec() - curTime;
        DebugP_log("[IPC Notify] The total echo time is %u. \r\n", curTime);
    
    }
    
    void ipc_notify_msg_handler_mcu_lowAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        DebugP_log("[MCU HANDLER] inside handler core=%d, client=%d, msg=0x%X\r\n",
                   remoteCoreId, localClientId, msgValue);
        if (msgValue == 0x01)
        {
            uint32_t eth_data_addr_recov1 = gSharedAddrs.buf1_addr;
            uint32_t eth_data_addr_recov2 = gSharedAddrs.buf2_addr;
            
            if (eth_data_addr_recov1 == 0 && eth_data_addr_recov2 == 0) {
                DebugP_logError("[MCU] WARNING: Read all-zero addresses from shared memory!\r\n");
            }
            
            DebugP_log("[MCU] gSharedAddrs 0x%X: buf1_addr=0x%08X, buf2_addr=0x%08X\r\n",
                       (uint32_t)&gSharedAddrs, eth_data_addr_recov1, eth_data_addr_recov2);
            
            IpcNotify_sendMsg(remoteCoreId, gClientId_low_rx, eth_data_addr_recov1, 1);
            IpcNotify_sendMsg(remoteCoreId, gClientId_low_rx, eth_data_addr_recov2, 1);
        
        }
            
    }
    
    void ipc_notify_msg_handler_mcu_highAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        uint32_t data_h = msgValue;
        DebugP_log("The received data in MCU is %u. \r\n", data_h);
    
        IpcNotify_sendMsg(remoteCoreId, localClientId, data_h, 1);
    }
    
    void ipc_notify_echo_remote_core_start()
    {
        DebugP_log("[MCU] MCU Core ID: %d\r\n", IpcNotify_getSelfCoreId());
        DebugP_log("[MCU] gSharedAddrs at 0x%X\r\n", (uint32_t)&gSharedAddrs);
        uint32_t eth_data_addr_recov1 = gSharedAddrs.buf1_addr;
        uint32_t eth_data_addr_recov2 = gSharedAddrs.buf2_addr;
        DebugP_log("[MCU] gSharedAddrs 0x%X: buf1_addr=0x%08X, buf2_addr=0x%08X\r\n",
                       (uint32_t)&gSharedAddrs, eth_data_addr_recov1, eth_data_addr_recov2);
    
        int32_t status;
        /* register a handler to receive messages */
        DebugP_log("[MCU] Registering handler for client ID %d\r\n", gClientId_low_tx);
        status = IpcNotify_registerClient(gClientId_low_tx, ipc_notify_msg_handler_mcu_lowAddr, NULL);
        DebugP_log("[MCU] Register status: %d\r\n", status);
    
        /* wait for all cores to be ready */
        DebugP_log("[MCU] Waiting for sync\r\n");
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
        DebugP_log("[MCU] Sync completed, and waiting for messages\r\n");
    
        
                       
    }
    
    void dloop()
    {
        volatile uint32_t loop = 1;
        while(loop)
            ;
    }
    
    void ipc_notify_echo_main(void *args)
    {
        // dloop();
        if(IpcNotify_getSelfCoreId()==gMainCoreId)
        {
            ipc_notify_echo_main_core_start();
        }
        else
        {
            ipc_notify_echo_remote_core_start();
        }
    
    }
     

    e2e.ti.com/.../ipc_5F00_notify_5F00_mcu01.zipe2e.ti.com/.../ipc_5F00_notify_5F00_wkup01.zip

    此致、

    Bomiao

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

    嗨 Bomiao ,你的观察似乎是一个好的。 我没有机会检查您的新共享代码、这可能需要一些时间、因此在此期间、请允许我分享一些您可以并行调查的指针。

    如您所知、对于 IPC RP 消息、我们使用 共享存储器 (VRING) 来缓冲消息。 要保证数据在临界点准备就绪、需要使用一个功能 UTILS_dataAndInstructionBarrier () 数据障碍的示例。 您可以查看“source\drivers\ipc_rpmsg\ipc_rpmsg_vring.c"和“和“source\kernel\nortos\DPL\R5\HwiP_armv7r_vim.c"以“以了解更多参考。

    此外、下面的 MCU+SDK 用户指南页面也可供您参考:

    AM62Px MCU+ SDK:IPC RP 消息回显

    AM62Px MCU+ SDK:IPC RPMessage

    回到您的应用。 可能您可以使用相同的函数,甚至可以尝试在读取地址和将地址写入共享存储器之前添加“__ASM__ volatile(“ DSB sy “:::“内存“);“。 下面是示例代码

    //Example snipped code - untested
    
    //In WKUP after writting
    buf_addr1 = (uint32_t)EmmcRxBuf1;
    buf_addr2 = (uint32_t)EmmcRxBuf2;
    
    __asm__ volatile("dsb sy" ::: "memory");
    
    //In MCU before reading
    if (msgValue == 0x01) {
        __asm__ volatile("dsb sy" ::: "memory");
        
        uint32_t wkup_buf_addr1 = buf_addr1;
        uint32_t wkup_buf_addr2 = buf_addr2;
    }

    谢谢您、

    Paula

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

    您好 Paula、

    我已根据您的建议修改了我的代码。 遗憾的是、我仍然无法从 MCU 内核中的 sharedMem 中获得元素的正确值。 我附上下面 MCU 侧的代码和日志。

    #include <stdio.h>
    #include <inttypes.h>
    #include <kernel/dpl/ClockP.h>
    #include <kernel/dpl/SemaphoreP.h>
    #include <drivers/ipc_notify.h>
    #include "kernel/dpl/DebugP.h"
    #include "kernel/dpl/SystemP.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include <drivers/ipc_notify/v0/ipc_notify_v0.h>
    #include <drivers/ipc_notify/v0/ipc_notify_v0_mailbox.h>
    
    // #include "emmc.h"
    // #include "ethData.h"
    
    /* client ID that is used to send and receive messages */
    uint32_t gClientId_low_tx = 4u;        // mailbox WKUP to MCU
    uint32_t gClientId_low_rx = 5u;       // mailbox MCU to WKUP
    
    #if defined(SOC_AM62PX)
    /* main core that starts the message exchange */
    uint32_t gMainCoreId = CSL_CORE_ID_WKUP_R5FSS0_0;
    /* remote cores that echo messages from main core, make sure to NOT list main core in this list */
    uint32_t gRemoteCoreId[] = {
        CSL_CORE_ID_MCU_R5FSS0_0,
        CSL_CORE_ID_MAX /* this value indicates the end of the array */
    };
    #endif
    
    /* semaphore's used to indicate a main core has finished all message exchanges */
    SemaphoreP_Object sLowAddrDone;
    SemaphoreP_Object sHighAddrDone;
    
    uint8_t EmmcRxBuf1[4]__attribute__((aligned(128U))) = {0x1B, 0x2C, 0x2A, 0x3B};
    uint8_t EmmcRxBuf2[4]__attribute__((aligned(128U))) = {0x0A, 0x0C, 0x0A, 0x0B};
    
    // uint32_t buf_addr1 __attribute__((section(".eth_data_addr"),aligned(4)));
    // uint32_t buf_addr2 __attribute__((section(".eth_data_addr"),aligned(4)));
    
    typedef struct {
        uint32_t buf1_addr;
        uint32_t buf2_addr;
    }SharedBuffAddr;
    
    SharedBuffAddr gSharedAddrs __attribute__((section(".eth_data_addr"),aligned(4)));
    
    uint32_t rx_arr_mcu[2];
    uint32_t rx_cnt_mcu = 0;
    
    void ipc_notify_msg_handler_wkup_lowAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        rx_arr_mcu[rx_cnt_mcu] = msgValue;
        rx_cnt_mcu ++;
        if (rx_cnt_mcu == 2)
        {
            SemaphoreP_post(&sLowAddrDone);
        
        }
    
    }
    
    void ipc_notify_echo_main_core_start()
    {
        int32_t status = SystemP_SUCCESS;
        uint64_t curTime;
    
        SemaphoreP_constructBinary(&sLowAddrDone, 0);
        /* register a handler to receive messages */
        DebugP_log("[WKUP] Registering handler for client ID %d\r\n", gClientId_low_rx);
        status = IpcNotify_registerClient(gClientId_low_rx, ipc_notify_msg_handler_wkup_lowAddr, NULL);
        DebugP_log("[WKUP] Register status: %d\r\n", status);
        /* wait for all cores to be ready */
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
    
        // uint32_t* pBuf1 = EmmcRxBuf1; 
        // buf_addr1 = (uint32_t) pBuf1;
        
        // uint32_t* pBuf2 = EmmcRxBuf2; 
        // buf_addr2 = (uint32_t) pBuf2;
    
        gSharedAddrs.buf1_addr = (uint32_t) EmmcRxBuf1;
        gSharedAddrs.buf2_addr = (uint32_t) EmmcRxBuf2;
        DebugP_log("[WKUP] gSharedAddrs=0x%X: buf1_addr=0x%08X, buf2_addr=0x%08X\r\n", 
                   (uint32_t)&gSharedAddrs, gSharedAddrs.buf1_addr, gSharedAddrs.buf2_addr); //PC-- WKUP writing to shared memory
    
        __asm__ __volatile__ ( "dsb sy"  "\n\t": : : "memory");
        
        uint32_t eth_flag = 0x01;
        status = IpcNotify_sendMsg(gRemoteCoreId[0], gClientId_low_tx, eth_flag, 1);
        DebugP_log("[WKUP] Send status: %d\r\n", status);
        
        curTime = ClockP_getTimeUsec();
        SemaphoreP_pend(&sLowAddrDone, SystemP_WAIT_FOREVER);
        curTime = ClockP_getTimeUsec() - curTime;
        DebugP_log("[IPC Notify] The total echo time is %u. \r\n", curTime);
    
    }
    
    void ipc_notify_msg_handler_mcu_lowAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        DebugP_log("[MCU HANDLER] inside handler core=%d, client=%d, msg=0x%X\r\n",
                   remoteCoreId, localClientId, msgValue);
        if (msgValue == 0x01)
        {
            uint32_t eth_data_addr_recov1 = gSharedAddrs.buf1_addr;
            uint32_t eth_data_addr_recov2 = gSharedAddrs.buf2_addr;
            
            if (eth_data_addr_recov1 == 0 && eth_data_addr_recov2 == 0) {
                DebugP_logError("[MCU] WARNING: Read all-zero addresses from shared memory!\r\n");
            }
            
            DebugP_log("[MCU] gSharedAddrs 0x%X: buf1_addr=0x%08X, buf2_addr=0x%08X\r\n",
                       (uint32_t)&gSharedAddrs, eth_data_addr_recov1, eth_data_addr_recov2);
            
            IpcNotify_sendMsg(remoteCoreId, gClientId_low_rx, eth_data_addr_recov1, 1);
            IpcNotify_sendMsg(remoteCoreId, gClientId_low_rx, eth_data_addr_recov2, 1);
        
        }
            
    }
    
    void ipc_notify_msg_handler_mcu_highAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        uint32_t data_h = msgValue;
        DebugP_log("The received data in MCU is %u. \r\n", data_h);
    
        IpcNotify_sendMsg(remoteCoreId, localClientId, data_h, 1);
    }
    
    void ipc_notify_echo_remote_core_start()
    {
        __asm__ __volatile__ ( "dsb sy"  "\n\t": : : "memory");
        
        DebugP_log("[MCU] MCU Core ID: %d\r\n", IpcNotify_getSelfCoreId());
        DebugP_log("[MCU] gSharedAddrs at 0x%X\r\n", (uint32_t)&gSharedAddrs);
        uint32_t eth_data_addr_recov1 = gSharedAddrs.buf1_addr;
        uint32_t eth_data_addr_recov2 = gSharedAddrs.buf2_addr;
        DebugP_log("[MCU] gSharedAddrs 0x%X: buf1_addr=0x%08X, buf2_addr=0x%08X\r\n",
                       (uint32_t)&gSharedAddrs, eth_data_addr_recov1, eth_data_addr_recov2);
    
        int32_t status;
        /* register a handler to receive messages */
        DebugP_log("[MCU] Registering handler for client ID %d\r\n", gClientId_low_tx);
        status = IpcNotify_registerClient(gClientId_low_tx, ipc_notify_msg_handler_mcu_lowAddr, NULL);
        DebugP_log("[MCU] Register status: %d\r\n", status);
    
        /* wait for all cores to be ready */
        DebugP_log("[MCU] Waiting for sync\r\n");
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
        DebugP_log("[MCU] Sync completed, and waiting for messages\r\n");
    
        
                       
    }
    
    void dloop()
    {
        volatile uint32_t loop = 1;
        while(loop)
            ;
    }
    
    void ipc_notify_echo_main(void *args)
    {
        // dloop();
        if(IpcNotify_getSelfCoreId()==gMainCoreId)
        {
            ipc_notify_echo_main_core_start();
        }
        else
        {
            ipc_notify_echo_remote_core_start();
        }
    
    }

    此致、

    Bomiao

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

    你好  Bomiao ,允许我检查一下,回来给你

    谢谢你

    Paula

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

    尊敬的 Bomiao:

    我认为 MCU 打印的问题是、它们是在调用 MCU 的 IpcNotify_syncall() 之前执行的、因此 WKUP 尚未将地址写入 gSharedAddrs。 换句话说、WKUP 在调用 IpcNotify_syncall() 后写入共享内存、但 MCU 打印发生在 IpcNotify_syncall() 之前。 我的坏、我之前没有意识到这一点。

    此外、查看您最新的 ipc_notify_echo.c 代码(位于共享代码上方)、我认为 DSB 屏障应置于回调函数中、而不是放在 ipc_notify_echo_remote_core_start () 中:

    //Snipped code - untested - just as a reference
        void ipc_notify_msg_handler_mcu_lowAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        DebugP_log("[MCU HANDLER] inside handler core=%d, client=%d, msg=0x%X\r\n",
        
        if (msgValue == 0x01)
        {
            /* Here should be a good place to try to ensure WKUP's writes to shared memory are visible before reading them*/
            __asm__ volatile("dsb sy" ::: "memory");
            
            uint32_t eth_data_addr_recov1 = gSharedAddrs.buf1_addr;
            uint32_t eth_data_addr_recov2 = gSharedAddrs.buf2_addr;
    我的理解是、在读取处理程序中的共享内存值之前、必须立即放置 DSB 屏障。 将 DSB 放在 ipc_notify_echo_remote_core_start () 中会太早,因为此时 WKUP 尚未写入数据。

    如果上述更改仍然不起作用、请将您的最新项目发送给我、我将尝试在我的电路板上重现问题。
    谢谢您、
    Paula
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Paula、

    按照您的建议,我尝试在  MCU 内核中的 IpcNotify_syncall () 之后读取共享内存。 下面附加了两个内核的日志。

    我认为 MCU 内核现在可以正确读取共享存储器、但我不确定 MCU 是否可以访问 IPC_ISR 中的共享存储器。 如前所述、DebugP_LOG 无法在 ISR 中工作、因此我尝试将共享存储器中的变量发送回 WKUP。 但是、 仍然出现了“无法进入回调函数 ipc_notify_msg_handler_wkup_lowAddr“的类似结果。 我可以在下面附上我的测试代码。

    #include <stdio.h>
    #include <inttypes.h>
    #include <kernel/dpl/ClockP.h>
    #include <kernel/dpl/SemaphoreP.h>
    #include <drivers/ipc_notify.h>
    #include "kernel/dpl/DebugP.h"
    #include "kernel/dpl/SystemP.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include <drivers/ipc_notify/v0/ipc_notify_v0.h>
    #include <drivers/ipc_notify/v0/ipc_notify_v0_mailbox.h>
    
    // #include "emmc.h"
    // #include "ethData.h"
    
    /* client ID that is used to send and receive messages */
    uint32_t gClientId_low_tx = 4u;        // mailbox WKUP to MCU
    uint32_t gClientId_low_rx = 5u;       // mailbox MCU to WKUP
    
    #if defined(SOC_AM62PX)
    /* main core that starts the message exchange */
    uint32_t gMainCoreId = CSL_CORE_ID_WKUP_R5FSS0_0;
    /* remote cores that echo messages from main core, make sure to NOT list main core in this list */
    uint32_t gRemoteCoreId[] = {
        CSL_CORE_ID_MCU_R5FSS0_0,
        CSL_CORE_ID_MAX /* this value indicates the end of the array */
    };
    #endif
    
    /* semaphore's used to indicate a main core has finished all message exchanges */
    SemaphoreP_Object sLowAddrDone;
    SemaphoreP_Object sHighAddrDone;
    
    uint8_t EmmcRxBuf1[4]__attribute__((aligned(128U))) = {0x1B, 0x2C, 0x2A, 0x3B};
    uint8_t EmmcRxBuf2[4]__attribute__((aligned(128U))) = {0x0A, 0x0C, 0x0A, 0x0B};
    
    // uint32_t buf_addr1 __attribute__((section(".eth_data_addr"),aligned(4)));
    // uint32_t buf_addr2 __attribute__((section(".eth_data_addr"),aligned(4)));
    
    typedef struct {
        uint32_t buf1_addr;
        uint32_t buf2_addr;
    }SharedBuffAddr;
    
    SharedBuffAddr gSharedAddrs __attribute__((section(".eth_data_addr"),aligned(4)));
    
    uint32_t rx_arr_mcu[2];
    uint32_t rx_cnt_mcu = 0;
    
    void ipc_notify_msg_handler_wkup_lowAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        rx_arr_mcu[rx_cnt_mcu] = msgValue;
        rx_cnt_mcu ++;
        if (rx_cnt_mcu == 2)
        {
            SemaphoreP_post(&sLowAddrDone);
        
        }
    
    }
    
    void ipc_notify_echo_main_core_start()
    {
        int32_t status = SystemP_SUCCESS;
        uint64_t curTime;
    
        SemaphoreP_constructBinary(&sLowAddrDone, 0);
        /* register a handler to receive messages */
        DebugP_log("[WKUP] Registering handler for client ID %d\r\n", gClientId_low_rx);
        status = IpcNotify_registerClient(gClientId_low_rx, ipc_notify_msg_handler_wkup_lowAddr, NULL);
        DebugP_log("[WKUP] Register status: %d\r\n", status);
        /* wait for all cores to be ready */
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
    
        // uint32_t* pBuf1 = EmmcRxBuf1; 
        // buf_addr1 = (uint32_t) pBuf1;
        
        // uint32_t* pBuf2 = EmmcRxBuf2; 
        // buf_addr2 = (uint32_t) pBuf2;
    
        gSharedAddrs.buf1_addr = (uint32_t) EmmcRxBuf1;
        gSharedAddrs.buf2_addr = (uint32_t) EmmcRxBuf2;
        DebugP_log("[WKUP] gSharedAddrs=0x%X: buf1_addr=0x%08X, buf2_addr=0x%08X\r\n", 
                   (uint32_t)&gSharedAddrs, gSharedAddrs.buf1_addr, gSharedAddrs.buf2_addr); //PC-- WKUP writing to shared memory
    
        __asm__ __volatile__ ( "dsb sy"  "\n\t": : : "memory");
        
        uint32_t eth_flag = 0x01;
        status = IpcNotify_sendMsg(gRemoteCoreId[0], gClientId_low_tx, eth_flag, 1);
        DebugP_log("[WKUP] Send status: %d\r\n", status);
        
        curTime = ClockP_getTimeUsec();
        SemaphoreP_pend(&sLowAddrDone, SystemP_WAIT_FOREVER);
        curTime = ClockP_getTimeUsec() - curTime;
        DebugP_log("[IPC Notify] The total echo time is %u. \r\n", curTime);
    
        DebugP_log("[WKUP] buf1_addr=0x%08X, buf2_addr=0x%08X\r\n", rx_arr_mcu[0], rx_arr_mcu[1]);
    
    }
    
    void ipc_notify_msg_handler_mcu_lowAddr(uint16_t remoteCoreId, uint16_t localClientId, uint32_t msgValue, void *args)
    {
        DebugP_log("[MCU HANDLER] inside handler core=%d, client=%d, msg=0x%X\r\n",
                   remoteCoreId, localClientId, msgValue);
        if (msgValue == 0x01)
        {
            __asm__ volatile("dsb sy" ::: "memory");
            
            uint32_t eth_data_addr_recov1 = gSharedAddrs.buf1_addr;
            uint32_t eth_data_addr_recov2 = gSharedAddrs.buf2_addr;
            
            DebugP_log("[MCU] gSharedAddrs 0x%X: buf1_addr=0x%08X, buf2_addr=0x%08X\r\n",
                       (uint32_t)&gSharedAddrs, eth_data_addr_recov1, eth_data_addr_recov2);
            
            IpcNotify_sendMsg(remoteCoreId, gClientId_low_rx, eth_data_addr_recov1, 1);
            IpcNotify_sendMsg(remoteCoreId, gClientId_low_rx, eth_data_addr_recov2, 1);
        
        }
            
    }
    
    void ipc_notify_echo_remote_core_start()
    {
        
        int32_t status;
        /* register a handler to receive messages */
        DebugP_log("[MCU] Registering handler for client ID %d\r\n", gClientId_low_tx);
        status = IpcNotify_registerClient(gClientId_low_tx, ipc_notify_msg_handler_mcu_lowAddr, NULL);
        DebugP_log("[MCU] Register status: %d\r\n", status);
    
        /* wait for all cores to be ready */
        DebugP_log("[MCU] Waiting for sync\r\n");
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
        DebugP_log("[MCU] Sync completed, and waiting for messages\r\n");
    
        __asm__ volatile("dsb sy" ::: "memory");
        
        DebugP_log("[MCU] MCU Core ID: %d\r\n", IpcNotify_getSelfCoreId());
        DebugP_log("[MCU] gSharedAddrs at 0x%X\r\n", (uint32_t)&gSharedAddrs);
        uint32_t eth_data_addr_recov1 = gSharedAddrs.buf1_addr;
        uint32_t eth_data_addr_recov2 = gSharedAddrs.buf2_addr;
        DebugP_log("[MCU] gSharedAddrs 0x%X: buf1_addr=0x%08X, buf2_addr=0x%08X\r\n",
                       (uint32_t)&gSharedAddrs, eth_data_addr_recov1, eth_data_addr_recov2);
                       
    }
    
    void dloop()
    {
        volatile uint32_t loop = 1;
        while(loop)
            ;
    }
    
    void ipc_notify_echo_main(void *args)
    {
        // dloop();
        if(IpcNotify_getSelfCoreId()==gMainCoreId)
        {
            ipc_notify_echo_main_core_start();
        }
        else
        {
            ipc_notify_echo_remote_core_start();
        }
    
    }

    此致、

    Bomiao