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.

[参考译文] TMS320F28388D:循环中的 IPC 残桩

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1464349/tms320f28388d-ipc-stucks-in-a-loop

器件型号:TMS320F28388D

工具与软件:

我有一个应用使用修改版本的 LWIP 和 IPC 消息在 DSP 和 CPU1之间进行通信。

当接收到 UDP 数据包时、将执行以下序列:

  1. 转发到 CPU1:

    • 使用将包含 UDP 数据包数据的 IPC 消息发送到 CPU1 IPC_sendCommand(IPC_CM_L_CPU1_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE, IPCTOCPU_PROTO_PCK, (uint32_t)packetData, (uint32_t)pckLength);
    • IPC_waitForAck(IPC_CM_L_CPU1_R, IPC_FLAG0);调用以等待 CPU1的确认。
  2. CPU1处理:

    • CPU1处理接收到的数据包。
  3. 正在发送来自 CPU1的响应:

    • CPU1使用向 CM 发送响应 IPC_sendCommand(IPC_CPU1_L_CM_R, IPC_FLAG1, IPC_ADDR_CORRECTION_ENABLE, IPCTOCM_PROTO_PCK, (uint32_t) packetDataTx, nByte);
    • IPC_waitForAck(IPC_CPU1_L_CM_R, IPC_FLAG1);被调用以等待 CM 的确认。

问题:

代码间歇性进入循环、由汇编指令指示:

F24D0004 movw r0, #0xd004
00001628: F2C4000F movt r0, #0x400f
0000162c: 6800 ldr r0, [r0]
0000162e: 0840 lsrs r0, r0, #1
00001630: D3F8 blo #0x1624 

根据数据表、0x400fd004对应于 IPC 配置寄存器。 此循环似乎与IPC_waitForAck()函数相关联:

static inline void IPC_waitForAck(IPC_Type_t ipcType, uint32_t flag) { 
    while((IPC_Instance[ipcType].IPC_Flag_Ctr_Reg->IPC_FLG & flag) != 0U) { 
        // Wait for flag to be cleared
    } 
}

其中、#define IPC_FLAG0 0x00000001U用于从 CM 到 CPU1的以太网消息的标志是什么。

删除两个IPC_waitForAck()呼叫未解决问题。

您能否提供有关对此问题进行故障排除的指导? 如果需要、我可以通过私人消息共享相关的代码片段。

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

    您好!

    您是否曾有机会先 了解 C 2000Ware 中提供的 IPC 示例?  
    https://dev.ti.com/tirex/explore/node?node=A__ANwwURrRiqh4Fp5sl6q1qQ__C2000WARE__1kRFgrO__LATEST

    提供了基于 C 28和 CM 的示例、您可以将其用作起点。

    此致、

    Ozino

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

    我已经在 TI 提供的代码中实现了一些示例。

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

    看起来、如果我再添加一个 IPC 标志并提高消息频率、那么该错误发生的频率会更高。

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

    您好、Yaro、

    您知道如何添加这些 IPC 标志吗?  只想指出、必须对中断1使用标志1、对中断2使用标志2、对中断3使用标志3、对中断4使用标志4。

    另请参见 上的 ipc_ex2_msgqueue_c28x1、ipc_ex2_msgqueue_cm 示例、在两个内核之间建立正确的通信。

    有关 IPC 标志的更多信息、请参阅 IPC 指南中的这一节。

    https://software-dl.ti.com/C2000/docs/C2000_Multicore_Development_User_Guide ipc/ipc_communication.html#ipc-flags-and-command-registers 

    此致、

    Ozino

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

    以下是其他一些:

    我分配内存的方式如下:

    在 CM 上:

    Fullscreen
    1
    2
    3
    4
    5
    #define PACKET_LENGTH 1500
    uint8_t packetData[PACKET_LENGTH];
    #pragma DATA_SECTION(packetData, "MSGRAM_CM_TO_CPU1")
    uint8_t ipcTransBuff[250];
    #pragma DATA_SECTION(ipcTransBuff, "MSGRAM_CM_TO_CPU1")
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    在 CM .cmd 文件上:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    MEMORY {
    CPU1TOCMMSGRAM0 : origin = 0x20080000, length = 0x00000800
    CPU1TOCMMSGRAM1 : origin = 0x20080800, length = 0x00000800
    CMTOCPU1MSGRAM0 : origin = 0x20082000, length = 0x00000800
    CMTOCPU1MSGRAM1 : origin = 0x20082800, length = 0x00000800
    SECTIONS {
    MSGRAM_CM_TO_CPU1 : > CMTOCPU1MSGRAM0, type=NOINIT
    MSGRAM_CPU1_TO_CM : > CPU1TOCMMSGRAM0, type=NOINIT
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    在 CPU1上:

    Fullscreen
    1
    2
    3
    4
    5
    #define PACKET_LENGTH 1500
    uint8_t packetDataTx[PACKET_LENGTH];
    #pragma DATA_SECTION(packetDataTx, "MSGRAM_CPU_TO_CM")
    uint8_t ipcTransBuff[250];
    #pragma DATA_SECTION(ipcTransBuff, "MSGRAM_CPU_TO_CM")
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    在 CPU1 .cmd 文件上:

    Fullscreen
    1
    2
    3
    4
    5
    6
    PAGE 1:
    CPUTOCMRAM : origin = 0x039000, length = 0x000800
    CMTOCPURAM : origin = 0x038000, length = 0x000800
    SECTIONS {
    MSGRAM_CPU_TO_CM : > CPUTOCMRAM, type=NOINIT, PAGE = 1
    MSGRAM_CM_TO_CPU : > CMTOCPURAM, type=NOINIT, PAGE = 1
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    CM 侧:

    首先、CM 和 CPU1在不同的时刻进行同步、以允许初始化外设和存储器。

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    IPC_clearFlagLtoR(IPC_CM_L_CPU1_R, IPC_FLAG_ALL);
    IPC_registerInterrupt(IPC_CM_L_CPU1_R, IPC_INT1, IPC_ISR1);·
    IPC_registerInterrupt(IPC_CM_L_CPU1_R, IPC_INT3, IPC_ISR3);·
    IPC_sync(IPC_CM_L_CPU1_R, IPC_FLAG31); // Synchronize both the cores.
    struct cmFwInfo_s {
    uint16_t major;
    uint16_t minor;
    uint16_t rev;
    } cmFwInfo;
    cmFwInfo.major = VER_MAJOR;
    cmFwInfo.minor = VER_MINOR;
    cmFwInfo.rev = VER_REV;
    memcpy(&ipcTransBuff, &cmFwInfo, sizeof(struct cmFwInfo_s));
    if(!IPC_isFlagBusyLtoR(IPC_CM_L_CPU1_R, IPC_FLAG2))
    IPC_sendCommand(IPC_CM_L_CPU1_R, IPC_FLAG2, IPC_ADDR_CORRECTION_ENABLE,
    IPCTOCPU_CMD_SEND_INFO, (uint32_t) ipcTransBuff, (uint32_t) sizeof(struct cmFwInfo_s));
    IPC_waitForAck(IPC_CM_L_CPU1_R, IPC_FLAG2); // Wait for acknowledgment
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    现在、CPU1和 CM 使用以下顺序进行通信:

    生成


     

    Fullscreen
    1
    2
    3
    if(!IPC_isFlagBusyLtoR(IPC_CM_L_CPU1_R, IPC_FLAG0))
    IPC_sendCommand(IPC_CM_L_CPU1_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
    IPCTOCPU_PROTO_PCK, (uint32_t)packetData, (uint32_t)pckLength);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    从 CPU1获取

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    IPC_readCommand(IPC_CPU1_L_CM_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
    &command, &addr, &data);
    newRxProtoPck((uint8_t *) addr, data);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP11); // Acknowledge this interrupt
    IPC_ackFlagRtoL(IPC_CPU1_L_CM_R, IPC_FLAG0); // Acknowledge the flag
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    均可通过 CPU1传输
    Fullscreen
    1
    2
    3
    if(!IPC_isFlagBusyLtoR(IPC_CPU1_L_CM_R, IPC_FLAG1))
    IPC_sendCommand(IPC_CPU1_L_CM_R, IPC_FLAG1, IPC_ADDR_CORRECTION_ENABLE,
    IPCTOCM_PROTO_PCK, (uint32_t) packetDataTx, nByte);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    获取的代码

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    IPC_readCommand(IPC_CM_L_CPU1_R, IPC_FLAG1, IPC_ADDR_CORRECTION_ENABLE,
    &command, &addr, &data);
    if(command == IPCTOCM_PROTO_PCK)
    udpSendTxProtoPck((uint8_t *) addr, data);
    IPC_ackFlagRtoL(IPC_CM_L_CPU1_R, IPC_FLAG1);
    Interrupt on CM is registred by·IPC_registerInterrupt while on CPU1 by sysBios interrupt configuration:
    Hwi_create(208, (Hwi_FuncPtr)IPC_ISR0,· &hwiParams, &eb);
    Hwi_create(210, (Hwi_FuncPtr)IPC_ISR2, &hwiParams, &eb);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    标记为
    从 CM 到 CPU1的 IPC_FLAG0
    从 CPU1到 CM 的 IPC_FLAG1
     从 CM 到 CPU1的 IPC_FLAG2
     从 CPU1到 CM 的 IPC_FLAG3

    如前所述、IPC 在 频率为5ms 至10ms 时能够正常处理恒定消息。 从和到 CM (实际上仅适用于 CPU1)。

    很多消息在封锁发生之前被交换,大约 15 到2小时的消息。 它是随机的,与分词事件无关(或者我们无法将此错误与特定的错误关联)。
    此外、从和到 CM 的缓冲区在发送 ipcCommand 之前填充、仅在这种情况下填充。

    遗憾的是、您的手册和 TMS320F28388的应用手册未能为我提供更多有用的信息。

    希望得到您的支持。 可以按 PM 共享代码。

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

    您好!

    我发送了朋友请求。 请继续分享您的代码、并描述最能复制上述错误的确切用例。

    在有机会联系 IPC 专家后、我会向您提供更多信息。

    此致、

    Ozino

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

    您好!

    我遇到过在 IPC_messageRam 示例中提到错误的情形。 您能否应用此处所述的以下更改:

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1292430/tms320f28388d-cpu1-to-cm-ipc-message-queue-problem 

    您是否能够使用多个消息队列而不是多次调用 IPC send 命令? 本线程解释了这些实现的优缺点。https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1288693/tms320f28388d-ipc-message-queue-communication-between-cpu1-and-cm-and-ipc-communication-issues 

    此致、

    Ozino

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

    我在您的邮件中 错误地确认了(按下了"这解决了我的问题")。 很遗憾、我无法删除这个。

    关于您的第一个链接、我已经检查了内存分配、回答正确。 我也不能多次调用相同的 IPC ,如果它以前不是 akn .  

    我可以尝试您的提议、但我有一些疑问、而 C2000手册中没有解释这些疑问:

    实际上、一种消息有一个1500字节的缓冲区、另一种消息有250字节的缓冲区。 共有1750字节被占用在共享内存 CM 到 CPU1的2048个可用字节上。 从 CPU1到 CM 都相同。

    我已经了解到、IPC 消息每个 IPC 标志有4个缓冲区。 如果队列中有1条以上的消息、我无法在共享存储器上分配1500 x 4 = 6000字节(甚至不能分配2个、3000字节)。

    我缺少什么? 在中止或溢出的情况下会发生什么情况?

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

    您好!

    我将联系其他专家、讨论您观察到的这个问题。 我将回答最后两个问题。 您能否提供有关建议的权变措施的任何更新?

    此致、

    Ozino

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

    经过一些研究、我发现这是一个循环缓冲区、将覆盖最后的消息。 很遗憾、我无法使 IPC 消息正常工作。 我仔细检查了您的帖子、并描述了在最后几个示例中已实现的权变措施。 IPC 中断正在工作、但仅发生一次。 在 IPC 标志被清除后(以及 CPU1的中断 akn ), CPU1和 CM 之间不再有中断调用。 另外、 IPC_Message_t 内部还有垃圾、似乎它指向传递的数据、而不是内部具有数据地址的结构。

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

    找到数据损坏的原因。 分配的 MessageQueue 缓冲区的位置在 CM 端也是错误的、因此、先前所示帖子中所述的相同更正也必须应用于 CM。 现在数据是正确的。

    仍然保留仅触发一次的中断问题。 两个内核上的实际 IPC_Flag 与 akn 标志相同。 另一个是 ack group11。

    您对为什么工作不正常有想法吗?

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

    您好!

    感谢您的耐心。 我们的专家现在可以离线进一步了解该主题。 您能否在此 E2E 帖子上或通过 FAE 联系人分享您的邮政编码。 一旦我们收到代码,我们将返回给您更多的信息。

    此致、

    Ozino