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_ex2_msgqueue 中、从 CM 到 CPU1的通信仅触发一次

Guru**** 2463330 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1494617/tms320f28388d-communication-from-cm-to-cpu1-triggers-only-once-in-the-adapted-example-ipc_ex2_msgqueue

器件型号:TMS320F28388D
主题:C2000WARE 中讨论的其他器件

工具/软件:

大家好!

我尝试更改 从 CM 到 CPU1内核的通信的 C2000Ware 示例 ipc_ex2_msgqueue。 未添加其他功能。

问题是 CPU1上的中断仅触发一次。 为了进行验证、我从示例中发送了同一条消息  
中间有短延迟的第二次。  CM 内核上的代码卡在第二个 IPC_readMessageFromQueue() IPC_ISR1上
未触发。 有人知道吗、如何 在 CPU1上重新启用 IPC_ISR1 ()中断?

从 CPU1到 CM 的类似双消息通信可以正常工作。

CPU1代码:

#include "driverlib.h"
#include "device.h"

//
//定义
//
#define IPC_CMD_READ_MEM 0x1001
#define IPC_CMD_RESP 0x2001

#define TEST_PASS 0x5555
#define TEST_FAIL 0xAAAA

IPC_MessageQueue_t 消息队列;
int cnt = 0;


//
//标志1的 IPC ISR
// C28x 内核使用标志0发送带有消息队列的数据
//
__interrupt void IPC_ISR1()

int i;
IPC_Message_t TxMsg、RxMsg;
bool 状态= false;

CNT++;
//
//从消息队列中读取消息
//
IPC_readMessageFromQueue (IPC_CPU1_L_CM_R、&messageQueue、IPC_ADDR_CORRECTION_ENABLE、
&RxMsg、ipc_nonblocation_call);

IF (RxMsg.command = IPC_CMD_READ_MEM)

status = true;

//
//读取和比较数据
//
for (I=0;i<RxMsg.dataw1;I++)

if (*((uint32_t *) RxMsg.address + i)!= i)
状态= false;
}
}

//
//发送响应消息
//
TxMsg.command = IPC_CMD_RESP;
TxMsg.address = 0;//未使用
TxMsg.dataw1 =状态? test_pass:test_fail;
TxMsg.dataw2 = RxMsg.dataw2;//使用接收消息中的消息标识符

IPC_sendMessageToQueue (IPC_CPU1_L_CM_R、&messageQueue、IPC_ADDR_CORRECTION_DISABLE、
&TxMsg、ipc_nonblocking_call);

//
//确认标志
//
IPC_ackFlagRtoL (IPC_CPU1_L_CM_R、IPC_Flag1);

//
//确认 PIE 中断。
//
INTERRUPT_CLEARACKGROUP (INTERRUPT_ACK_GROUP1);
}

//
//主要
//
void main (void)

//
//初始化器件时钟和外设
//
设备初始化();

//
//引导 CM 内核
//
#ifdef _flash
DEVICE_BOOTCM (BOOT_BOOT_TO_FLASH_SECTOR0);
#else
DEVICE_BOOTCM (BOOT_BOOT_TO_S0RAM);
#endif

//
//初始化 PIE 并清除 PIE 寄存器。 禁用 CPU 中断。
//
interrupt_initModule();

//
//使用指向 shell 中断的指针初始化 PIE 向量表
//服务例程(ISR)。
//
Interrupt_initVectorTable();
//
//清除所有 IPC 标志(如果已设置)
//
IPC_clearFlagLtoR (IPC_CPU1_L_CM_R、IPC_FLAG_ALL);

//
//启用 IPC 中断
//
IPC_registerInterrupt (IPC_CPU1_L_CM_R、IPC_INT1、IPC_ISR1);

//
//初始化消息队列
//
IPC_initMessageQueue (IPC_CPU1_L_CM_R、&messageQueue、IPC_INT1、IPC_INT1);

//
//同步两个内核。
//
IPC_SYNC (IPC_CPU1_L_CM_R、IPC_FLAG31);

//
//启用全局中断(INTM)和实时中断(DBGM)
//
EINT;
ERTM;

//
//永远循环。 等待 IPC 中断
//
while (1);

}

CM 代码:

#include "cm.h"
#include "ipc.h"
//
//定义
//
#define IPC_CMD_READ_MEM 0x1001
#define IPC_CMD_RESP 0x2001

#define TEST_PASS 0x5555
#define TEST_FAIL 0xAAAA


#pragma DATA_SECTION (ReadData、"MSGRAM_CM_TO_CPU1")
uint32_t ReadData[10];

uint32_t pass;

//
//主要
//
void main (void)

int i;
IPC_MessageQueue_t 消息队列;
IPC_Message_t TxMsg、RxMsg;

//
//初始化器件时钟和外设
//
cm_init();

//
//清除所有 IPC 标志(如果已设置)
//
IPC_clearFlagLtoR (IPC_CM_CPU1_R、IPC_FLAG_ALL);

//
//初始化消息队列
//
IPC_initMessageQueue (IPC_CM_CPU1_R、&messageQueue、IPC_INT1、IPC_INT1);

//
//同步两个内核
//
IPC_SYNC (IPC_CM_L_CPU1_R、IPC_FLAG31);

//启用全局中断
///__enable_irq();
//
//填写要发送的数据
//
对于(I=0;I<10;I++)

ReadData[i]= i;
}

//
//更新消息
//
TxMsg.command = IPC_CMD_READ_MEM;
TxMsg.address =(uint32_t) ReadData;
TxMsg.dataw1 = 10;//使用 dataw1作为数据长度
TxMsg.dataw2 = 1;//消息标识符

//
//将消息发送到队列
//由于 C28x 和 CM 不共享共享 RAM 的相同地址空间、
//已启用 address_correction
//
ipc_sendMessageToQueue (ipc_CM_L_CPU1_R、&messageQueue、ipc_ADDR_CORRECTION_ENABLE、
&TxMsg、ipc_blocking_call);
//
//从队列中读取消息
//从 CM 返回的消息不使用地址字段、因此
//不使用 address_COREECTION 功能
//
IPC_readMessageFromQueue (IPC_CM_L_Cpu1_R、&messageQueue、IPC_ADDR_CORRECTION_DISABLE、
&RxMsg、IPC_BLOCKING_CALL);

if ((RxMsg.command == IPC_CMD_RESP)&&(RxMsg.dataw1 == TEST_PASS)&&(RxMsg.dataw2 == 1))
PASS = 1;
暴露
PASS = 0;

DEVICE_DELAY_US (500000);

ipc_sendMessageToQueue (ipc_CM_L_CPU1_R、&messageQueue、ipc_ADDR_CORRECTION_ENABLE、
&TxMsg、ipc_blocking_call);
//
//从队列中读取消息
//从 CM 返回的消息不使用地址字段、因此
//不使用 address_COREECTION 功能
//
IPC_readMessageFromQueue (IPC_CM_L_Cpu1_R、&messageQueue、IPC_ADDR_CORRECTION_DISABLE、
&RxMsg、IPC_BLOCKING_CALL);

if ((RxMsg.command == IPC_CMD_RESP)&&(RxMsg.dataw1 == TEST_PASS)&&(RxMsg.dataw2 == 1))
PASS = 1;
暴露
PASS = 0;
//
//示例末尾。 一直循环
//
while (1);
}

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

    您好、

    通常、我们无法调试客户代码、但我来尝试回答这个问题:  

    Unknown 说:
    问题是 CPU1上的中断仅触发一次。 为了进行验证、我从示例中发送了同一条消息  
    第二次、中间有短暂的延迟。

    查看 IPC 的 CPU1和 CPU2示例、您将在 ISR 中看到、有一些中断闪存必须被确认和清除。  

    如果未执行此操作、则 ISR 只会发生一次。  

    此致、

    Ben Collier

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

    嗨、Benjamin、

    感谢您的回答。 实际上、我检查了 c28x_dual 示例、并从该示例中添加了以下代码(见上文):
    //
    //确认 PIE 中断。
    //
    INTERRUPT_CLEARACKGROUP (INTERRUPT_ACK_GROUP1);

    我也不会将其称为"客户代码"、因为它与 C2000Ware 示例中的代码相同。
    我只是颠倒了沟通的方向,并执行了两次相同的代码。

    此致、

    Stanislav

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

    尊敬的 Stanislav:

    当您说您颠倒了通信方向时、您最终会改变应用程序代码以实现这一点吗? 能否总结一下步骤。 谢谢。

    此致、

    Ozino

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

    尊敬的 Ozino:

    感谢您的回答。

    没有从 CM 到 CPU1的 IPC 通信示例、因此我查看了 IPC 模块—F2838x CM API 指南 文档、其中指出"除了极少数例外情况、所有3款处理器都使用了相同的 IPC API。"

    因此、 在示例 ipc_ex2_msgqueueand i 中:

    1. 从 CM 代码中切断__interrupt void IPC_ISR1 ()、并通过更正 IPC_CM_L_CPU1_R -> IPC_CPU1_L_CM_R 将其粘贴到 CPU1代码中  

    2.从 CPU1剪切 main ()中的通信代码并将其粘贴到 CM 代码中、同时更正 IPC_CPU1_L_CM_R -> IPC_CM_L_CPU1_R

    2.1通过简单的复制粘贴示例中的相关代码发送和读取消息两次(双消息)

    2.2为了确保不存在同步问题、我在消息之间设置了短暂的延迟

    3. 将#pragma DATA_SECTION (ReadData、"MSGRAM_CM_TO_CPU1")移至带有相应更正的 CM 代码。

    4.我检查了 CPU1和 CPU2之间通信的示例、并添加了"Interrupt_clearACKGroup (INTERRUPT_ACK_GROUP1);"、该代码在 CM 代码中不可用

    这几乎是所有的,我把更新的代码粘贴在我的第一条消息。

    此更新的 CM->CPU1通信正常工作、但仅适用于第一条消息。 第二条消息滞留在 CM 代码中、CPU1上的中断仅由第一条消息触发。 我还尝试了从 CPU1到 CM 的类似"双消息通信"、这样可以顺利工作、每次消息排队时都会触发中断。

    由于我没有添加我自己的单行代码、而只是修改原始代码、因此我将其称为反向通信。

    BTW、  ipc_ex1_basic 示例中也会出现从 CM 到 CPU1的类似双消息问题。

    我希望,我的解释已经足够清楚了。

    此致、

    Stanislav

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

    尊敬的 Stanislav:

    您是否有机会查看 CM 方面的示例? CPU1和 CM 之间有一个 IPC 示例、位于此处:

    https://dev.ti.com/tirex/explore/node?node=A__ANwwURrRiqh4Fp5sl6q1qQ__C2000WARE__1kRFgrO__LATEST&placeholder=true 

    这里应该显示在 CPU1和 CM 之间建立通信的步骤。您能否交叉检查该示例并查看您的设置是否类似匹配。

    对于双消息问题、您能否提供更多详细信息、因为不清楚根本原因是什么。

    此致、

    Ozino

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

    尊敬的 Ozino:

    我准确地使用了这些示例(旨在实现从 CPU1 -> CM 到反向通信(CM -> CPU1)的通信。 此外、我对从 CPU1到 CPU2的通信使用了类似的示例以清除 CPU1上的中断(Interrupt_clearACKGroup (interrupt_ACK_Group1);)。

    在这两个调整的示例中:IPC Ex1 BASIC 和 IPC Ex2 MSGQUEUE、从 CM 到 CPU1的通信仅触发一次。

    此致、

    Stanislav

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

    尊敬的 Stanislav:

    让我在内部与团队核实您所描述的内容是否可行。 请短暂延迟。

    此致、

    Ozino

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

    您好、
    你必须要做  

      interrupt_clearACKGroup( INTERRUPT_ACK_group11 );

    由于  CM 至 CPU、IPC 中断1是 PIE 组11的一部分 (INT_CMTOCPUXIPC1 11.10)

    此致
    Samritha