TI中文支持网
TI专业的中文技术问题搜集分享网站

TMS320F28377D: TI的工程师你们好,28377D双核通信存在一个问题,具体问题如下:

Part Number:TMS320F28377D

DSP双核IPC通信,CPU1同样一个数组readData,我把他放在MSGRAM_CPU1_TO_CPU2里面,传输给CPU2,CPU2读取到的readData地址正确,但是我把数组readData放在RAMGS0中,CPU2读取到的readData地址错误,本来地址应该是0x00C000,现在是0x8000C000,这是为什么呢?我CPU1和CPU2的CMD文件都定义了RAMGS0的起始位置和长度,RAMGS0由CPU1控制。

此外我还有一个问题,就是我在CPU1和CPU2都定义了GSRAM0的话,他们是共享这一片GSRAM0还是说CPU1有一块GSRAM0,CPU2有另外的GSRAM0呢?

zhisheng xiong:

CPU1代码如下

//
// Included Files
//
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "F2837xD_device.h"// F2837xD Headerfile Include File
//
// Defines
//
#define IPC_CMD_READ_MEM0x1001
#define IPC_CMD_RESP0x2001#define TEST_PASS0x5555
#define TEST_FAIL0xAAAA#pragma DATA_SECTION(readData, "readDataRAM")
uint32_t readData[10];
uint16_t IPCpass;
uint32_t pass;IPC_MessageQueue_t messageQueue;
IPC_Message_tTxMsg, RxMsg;
//
// Main
//
void main(void){int i;//// Initialize device clock and peripherals//Device_init();//// Initialize PIE and clear PIE registers. Disables CPU interrupts.//Interrupt_initModule();//// Initialize the PIE vector table with pointers to the shell Interrupt// Service Routines (ISR).//Interrupt_initVectorTable();//// Initialize settings from SysConfig//Board_init();//// Give Memory Access to GS0/ GS14 SARAM to CPU02//必须在CPU2启动前分配
//while( !(MemCfgRegs.GSxMSEL.bit.MSEL_GS0 &
//MemCfgRegs.GSxMSEL.bit.MSEL_GS14))while( !(MemCfgRegs.GSxMSEL.bit.MSEL_GS14))//GS14未分配给CPU02则循环{EALLOW;MemCfgRegs.GSxMSEL.bit.MSEL_GS0 = 0;// 将 GS0 分配给 CPU01MemCfgRegs.GSxMSEL.bit.MSEL_GS14 = 1;// 将 GS14 分配给 CPU02EDIS;}//// Give memory access to GS0 and GS14 RAM to CPU2// driverlib库开发写法
//MemCfg_setGSRAMMasterSel((MEMCFG_SECT_GS0 | MEMCFG_SECT_GS14),
//MEMCFG_GSRAMMASTER_CPU2);
//MemCfg_setGSRAMMasterSel((MEMCFG_SECT_GS14),
//MEMCFG_GSRAMMASTER_CPU2);//// Initialize GPIO and configure the GPIO pin as a push-pull output//Device_initGPIO();GPIO_setPadConfig(99, GPIO_PIN_TYPE_STD);GPIO_setDirectionMode(99, GPIO_DIR_MODE_OUT);GPIO_setMasterCore(99, GPIO_CORE_CPU1);GPIO_setPadConfig(133, GPIO_PIN_TYPE_STD);GPIO_setDirectionMode(133, GPIO_DIR_MODE_OUT);GPIO_setMasterCore(133, GPIO_CORE_CPU2);//// Clear any IPC flags if set already//IPC_clearFlagLtoR(IPC_CPU1_L_CPU2_R, IPC_FLAG_ALL);//// Initialize message queue//IPC_initMessageQueue(IPC_CPU1_L_CPU2_R, &messageQueue, IPC_INT1, IPC_INT1);//// Synchronize both the cores//IPC_sync(IPC_CPU1_L_CPU2_R, SYNC_FLAG);//// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)//EINT;ERTM;//// Fill in the data to be sent//for(i=0; i<10; i++){readData[i] = i;}//// Update the message//TxMsg.command = IPC_CMD_READ_MEM;TxMsg.address = (uint32_t)readData;
//TxMsg.address = (uint32_t)readData;TxMsg.dataw1= 10;// Using dataw1 as data lengthTxMsg.dataw2= 1;// Message identifier//// End of example. Loop forever//while(1){DEVICE_DELAY_US(1000000);
//GPIO_togglePin(133);GPIO_togglePin(99);IPC_sendMessageToQueue(IPC_CPU1_L_CPU2_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE,&TxMsg, IPC_BLOCKING_CALL);IPC_readMessageFromQueue(IPC_CPU1_L_CPU2_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;IPCpass++;}elsepass = 0;}
}

,

zhisheng xiong:

CPU2代码如下

#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "F2837xD_device.h"// F2837xD Headerfile Include File//
// Defines
//
#define IPC_CMD_READ_MEM0x1001
#define IPC_CMD_RESP0x2001#define TEST_PASS0x5555
#define TEST_FAIL0xAAAA#define GS0_Start0x00C000
#define ARRAY_LENGTH 10// 假设数组长度为 10IPC_MessageQueue_t messageQueue;
IPC_Message_t TxMsg, RxMsg;
uint16_t IPCCount;
uint32_t command, addr, data;
bool status = false;
uint32_t readData2[10];
#pragma DATA_SECTION(readData2, "readData2")//
// Function prototypes
//
__interrupt void IPC_1_ISR(void);//
// Main
//
void main(void)
{int j=0;//// Initialize device clock and peripherals//Device_init();//// Initialize PIE and clear PIE registers. Disables CPU interrupts.//Interrupt_initModule();//// Initialize the PIE vector table with pointers to the shell Interrupt// Service Routines (ISR).//Interrupt_initVectorTable();Board_init();//// Clear any IPC flags if set already//IPC_clearFlagLtoR(IPC_CPU2_L_CPU1_R, IPC_FLAG_ALL);//// Initialize message queue//IPC_initMessageQueue(IPC_CPU2_L_CPU1_R, &messageQueue, IPC_INT1, IPC_INT1);//// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)//EINT;ERTM;//// Synchronize both the cores.//IPC_sync(IPC_CPU2_L_CPU1_R, SYNC_FLAG);while(1);
}//
// IPC ISR for Flag 1
// C28x core sends data with message queue using Flag 0
//
__interrupt void IPC_1_ISR(void)
{int i,j;
//IPC_Message_t TxMsg, RxMsg;
//bool status = false;IPCCount++;//利用GS0基地址读取for(j=0; j<ARRAY_LENGTH; j++){readData2[j]=*((uint32_t *)GS0_Start+j);}//// Read the message from the message queue//IPC_readMessageFromQueue(IPC_CPU2_L_CPU1_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE,&RxMsg, IPC_NONBLOCKING_CALL);if(RxMsg.command == IPC_CMD_READ_MEM){status = true;//// Read and compare data//for(i=0; i<RxMsg.dataw1; i++){if(*((uint32_t *)RxMsg.address + i) != i)status = false;}}//// Send response message//TxMsg.command = IPC_CMD_RESP;TxMsg.address = 0; // Not usedTxMsg.dataw1= status ? TEST_PASS : TEST_FAIL;TxMsg.dataw2= RxMsg.dataw2; // Use the message identifier from the received messageIPC_sendMessageToQueue(IPC_CPU2_L_CPU1_R, &messageQueue, IPC_ADDR_CORRECTION_DISABLE,&TxMsg, IPC_NONBLOCKING_CALL);DEVICE_DELAY_US(1000000);GPIO_togglePin(133);//uint32_t command, addr, data;
//bool status = false;//// Acknowledge the flag//IPC_ackFlagRtoL(IPC_CPU2_L_CPU1_R, IPC_FLAG1);//// Acknowledge the PIE interrupt.//Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}//
// End of File
//

,

zhisheng xiong:

我不传递数组,仅仅只是传递一个宏定义,定义的是数组的首地址,为什么也是不行呢,地址还是会变为0x8000C000

,

zhisheng xiong:

另外,DSP可以把GSRAM在CMD里面修改分配给MSGRAM_CPU1_TO_CPU2吗,这样的话也能解决问题

,

zhisheng xiong:

又出现了一个问题:数组readData,我把他放 在MSGRAM_CPU1_TO_CPU2里面,传输给CPU2,若是传输的数组大一点例如uint32_t readData[70];,,CPU2的RxMsg都为0了。这是为什么呢??

,

Eirwen:

已经收到了您的案例,调查需要些时间,感谢您的耐心等待。

,

zhisheng xiong:

请尽快

,

Daniel:

您好

CPU1和 CPU2在物理上没有不同的 GSRAM0、它是相同的存储器。 根据 GSxMSEL 寄存器的配置、任一 CPU 拥有该寄存器。 您是否还可以说明将此部分"readData2"映射到了哪个存储器? 在您共享的代码中、在 CPU2中、您对 GS0_Start 进行硬编码并直接读取 readData2[]。 我希望这可以正常工作。 运行代码时、我观察到 CPU1将地址0xC000放入消息队列(不考虑 IPC_sendMessageToQueue 中设置的 addrCorrEnable 参数)、当 CPU2读取队列时、它会转换地址。 既然我们使用的是 GSRAM、您可以尝试使用 IPC_ADDR_CORRECTION_DISABLE 吗?

,

zhisheng xiong:

readData2我放在了RAMGS14,我设置RAMGS14的主核是CPU2,可以对其读写。在CPU1我把数组放在RAMGS0中,我把RAMGS0的起始地址定义为GS0_Start ,在CPU2中直接用GS0_Start 读取数据是没有问题的。意思就是如果我在CPU1中把数组放在GSRAM而不是MSGRAM的话,不用地址校正就可以吗?我去尝试一下。另外这个地址校正是什么意思我还没弄明白,为什么会需要地址校正呢?相关的资料在哪里查呢?

,

zhisheng xiong:

非常感谢,刚刚我尝试了一下使用GSRAM的话采用IPC_ADDR_CORRECTION_DISABLE,现在地址就正确了,为什么用GSRAM就不用地址校正,用MSGRAM就需要呢?麻烦你再给我解释一下。

,

zhisheng xiong:

是的,对于GSRAM来说采用IPC_ADDR_CORRECTION_DISABLE 就可行了,但是为什么利用MSGRAM的时候需要IPC_ADDR_CORRECTION_ENABLE呢?可以为我解答一下吗?

,

Daniel:

您好

感谢您的回复!

如果相关建议已经解决您问题,将关闭本贴,如果您还有问题,请再次发帖,十分感谢。

,

zhisheng xiong:

还有一个疑问呀。为什么数组存放在GSRAM采用IPC_ADDR_CORRECTION_DISABLE,存放在MSGRAM的时候需要IPC_ADDR_CORRECTION_ENABLE呢?只有这一个疑问了。

,

Daniel:

您好

应在 sendMessage 和 readMessage 函数调用中禁用地址校正(IPC_ADDR_CORRECTION_DISABLE)。

,

zhisheng xiong:

这个我知道,请仔细看我的问题,我是询问的为什么GSRAM不需要校正,而MSGRAM需要校正。

,

Daniel:

您好

这是因为 API 实现假定使用 MSGRAM。 如果启用了地址校正、它会将地址发送到 MSGRAM 基址。 当您将其与 GSRAM 一同使用时、地址将损坏。

,

zhisheng xiong:

我的理解是因为GSRAM对于CPU1和CPU2是一个地址,但是MSGRAM具有指向性,若是CPU1TOCPU2RAM,是否可以认为同一块区域在CPU1和CPU2的地址不一样呢?

,

Daniel:

您好

是的、GSRAM 地址同时适用于 CPU1和 CPU2。 CPU1TOCPU2RAM 在 CPU1和 CPU2中也是相同的地址、没有什么不同、只是访问权限不同。 MSGRAM 具有来自其自身 CPU 子系统的 CPU/DMA 读取/写入访问权限、以及来自其他子系统的 CPU/DMA 只读权限。

赞(0)
未经允许不得转载:TI中文支持网 » TMS320F28377D: TI的工程师你们好,28377D双核通信存在一个问题,具体问题如下:
分享到: 更多 (0)