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

TMS320F28388D: C28XCPU1与CM4 IPC通讯不能进入中断

Part Number:TMS320F28388DOther Parts Discussed in Thread:C2000WARE

在例程的基础上,我改了C28X1的程序,接收也采用中断的形式。代码如下:

//
// Included Files
//
#include "driverlib.h"
#include "device.h"

//
// Defines
//
#define IPC_CMD_READ_MEM 0x1001
#define IPC_CMD_RESP 0x2001

#define TEST_PASS 0x5555
#define TEST_FAIL 0xAAAA


#pragma DATA_SECTION(readData, "MSGRAM_CPU_TO_CM")
uint32_t readData[10];

uint32_t pass;

//
// Main
//
void main(void)
{
int i;
IPC_MessageQueue_t messageQueue;
IPC_Message_t TxMsg, RxMsg;

//
// Initialize device clock and peripherals
//
Device_init();

//
// Boot CM core
//
#ifdef _FLASH
Device_bootCM(BOOTMODE_BOOT_TO_FLASH_SECTOR0);
#else
Device_bootCM(BOOTMODE_BOOT_TO_S0RAM);
#endif

//
// 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();

//
// Clear any IPC flags if set already
//
IPC_clearFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG_ALL);

//
// Initialize message queue
//
IPC_initMessageQueue(IPC_CPU1_L_CM_R, &messageQueue, IPC_INT1, IPC_INT1);

//
// Synchronize both the cores
//
IPC_sync(IPC_CPU1_L_CM_R, IPC_FLAG31);

//
// 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.dataw1 = 10; // Using dataw1 as data length
TxMsg.dataw2 = 1; // Message identifier

//
// Send message to the queue
// Since C28x and CM does not share the same address space for shared RAM,
// ADDRESS_CORRECTION is enabled
//
IPC_sendMessageToQueue(IPC_CPU1_L_CM_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE,
&TxMsg, IPC_BLOCKING_CALL);

//
// Read message from the queue
// Return message from CM does not use the address field, hence
// ADDRESS_COREECTION feature is not used
//
IPC_readMessageFromQueue(IPC_CPU1_L_CM_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;
else
pass = 0;


//
// End of example. Loop forever
//
while(1);
}


//
// End of File
//



但是,CPU1不能进入接收中断,CM4则运行正常。请问这是什么原因呢?

在另外一个例程中,CPU1与CPU2 IPC通讯,我改了CPU1的代码则可以正常进入接收中断,代码如下:

//
// Included Files
//
#include "driverlib.h"
#include "device.h"

//
// Defines
//
#define IPC_CMD_READ_MEM 0x1001
#define IPC_CMD_RESP 0x2001

#define TEST_PASS 0x5555
#define TEST_FAIL 0xAAAA


#pragma DATA_SECTION(readData, "MSGRAM_CPU1_TO_CPU2")
uint32_t readData[10];

uint32_t pass;

IPC_MessageQueue_t messageQueue;
IPC_Message_t TxMsg, RxMsg;

//
// IPC ISR for Flag 1
// C28x core sends data with message queue using Flag 0
//
__interrupt void IPC_ISR1()
{
int i;
// IPC_Message_t TxMsg, RxMsg;
bool status = false;

//
// Read the message from the message queue
//
IPC_readMessageFromQueue(IPC_CPU1_L_CPU2_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;
}
}

//
// Acknowledge the flag
//
IPC_ackFlagRtoL(IPC_CPU1_L_CPU2_R, IPC_FLAG1);

//
// Acknowledge the PIE interrupt.
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}













//
// Main
//
void main(void)
{
int i;


//
// Initialize device clock and peripherals
//
Device_init();

//
// Boot CPU2 core
//
#ifdef _FLASH
Device_bootCPU2(BOOTMODE_BOOT_TO_FLASH_SECTOR0);
#else
Device_bootCPU2(BOOTMODE_BOOT_TO_M0RAM);
#endif

//
// 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();

// //
// // 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);


// Clear any IPC flags if set already
//
IPC_clearFlagLtoR(IPC_CPU1_L_CPU2_R, IPC_FLAG_ALL);

//
// Enable IPC interrupts
//
IPC_registerInterrupt(IPC_CPU1_L_CPU2_R, IPC_INT1, IPC_ISR1);

//
// Initialize message queue
//
IPC_initMessageQueue(IPC_CPU1_L_CPU2_R, &messageQueue, IPC_INT1, IPC_INT1);

//
// Synchronize both the cores
//


//
// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
//
EINT;
ERTM;

IPC_sync(IPC_CPU1_L_CPU2_R, IPC_FLAG31);
//
// 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.dataw1 = 10; // Using dataw1 as data length
TxMsg.dataw2 = 1; // Message identifier

//
// Send message to the queue
//
// IPC_sendMessageToQueue(IPC_CPU1_L_CPU2_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE,
// &TxMsg, IPC_BLOCKING_CALL);

//
// Read message from the queue
//
// 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;
// else
// pass = 0;


//
// End of example. Loop forever
//
while(1)
{

DEVICE_DELAY_US(100000);
IPC_sendMessageToQueue(IPC_CPU1_L_CPU2_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE,
&TxMsg, IPC_NONBLOCKING_CALL);
DEVICE_DELAY_US(100000);

}
}


//
// End of File
//

user6328081:

更正一下CPU1与CM4通讯的代码:

//#############################################################################
//
// FILE: ipc_ex2_msgqueue_c28x1.c
//
// TITLE: IPC example with interrupt and message queue
//
//! \addtogroup driver_dual_example_list
//! <h1> IPC message passing example with interrupt and message queue </h1>
//!
//! This example demonstrates how to configure IPC and pass information from
//! C28x1 to C28x2 core with message queues.
//! It is recommended to run the C28x1 core first, followed by the C28x2 core.
//!
//! \b External \b Connections \n
//! - None.
//!
//! \b Watch \b Variables \n
//! - pass
//!
//
//#############################################################################
// $TI Release: F2838x Support Library v3.04.00.00 $
// $Release Date: Fri Feb 12 19:08:49 IST 2021 $
// $Copyright:
// Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti2k.com/wp-content/uploads/ti2k/DeyiSupport_C2000_
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################//
// Included Files
//
#include "driverlib.h"
#include "device.h"//
// Defines
//
#define IPC_CMD_READ_MEM 0x1001
#define IPC_CMD_RESP 0x2001#define TEST_PASS 0x5555
#define TEST_FAIL 0xAAAA#pragma DATA_SECTION(readData, "MSGRAM_CPU_TO_CM")
uint32_t readData[10];uint32_t pass;IPC_MessageQueue_t messageQueue;
IPC_Message_t TxMsg, RxMsg;//
// IPC ISR for Flag 1
// C28x core sends data with message queue using Flag 0
//
__interrupt void IPC_ISR1()
{
int i;
//IPC_Message_t TxMsg, RxMsg;
bool status = false;//
// Read the message from the message queue
//
IPC_readMessageFromQueue(IPC_CPU1_L_CM_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;
}
}//
// Acknowledge the flag
//
IPC_ackFlagRtoL(IPC_CPU1_L_CM_R, IPC_FLAG1);//
// Acknowledge the PIE interrupt.
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}//
// Main
//
void main(void)
{
int i;//
// Initialize device clock and peripherals
//
Device_init();//
// Boot CPU2 core
//
//#ifdef _FLASH
// Device_bootCPU2(BOOTMODE_BOOT_TO_FLASH_SECTOR0);
//#else
// Device_bootCPU2(BOOTMODE_BOOT_TO_M0RAM);
//#endif
//
// Boot CM core
//
#ifdef _FLASH
Device_bootCM(BOOTMODE_BOOT_TO_FLASH_SECTOR0);
#else
Device_bootCM(BOOTMODE_BOOT_TO_S0RAM);
#endif
//
// 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();// //
// // 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);// Clear any IPC flags if set already
//
IPC_clearFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG_ALL);//
// Enable IPC interrupts
//
IPC_registerInterrupt(IPC_CPU1_L_CM_R, IPC_INT1, IPC_ISR1);//
// Initialize message queue
//
IPC_initMessageQueue(IPC_CPU1_L_CM_R, &messageQueue, IPC_INT1, IPC_INT1);//
// Synchronize both the cores
////
// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
//
EINT;
ERTM;IPC_sync(IPC_CPU1_L_CM_R, IPC_FLAG31);
//
// 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.dataw1 = 10; // Using dataw1 as data length
TxMsg.dataw2 = 1; // Message identifier//
// Send message to the queue
//
// IPC_sendMessageToQueue(IPC_CPU1_L_CPU2_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE,
// &TxMsg, IPC_BLOCKING_CALL);//
// Read message from the queue
//
// 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;
// else
// pass = 0;//
// End of example. Loop forever
//
while(1)
{DEVICE_DELAY_US(100000);
IPC_sendMessageToQueue(IPC_CPU1_L_CM_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE,
&TxMsg, IPC_NONBLOCKING_CALL);
DEVICE_DELAY_US(100000);}
}//
// End of File
//

,

Green Deng:

额,不好意思能否标注一下具体是在例程的基础上改了哪些位置?否则我去跟例程比对太耗时了。

,

user6328081:

更改的地方详见以下代码中文注释。(源代码为ipc_ex2_msgqueue_c28x1.c)

//
// Included Files
//
#include "driverlib.h"
#include "device.h"//
// Defines
//
#define IPC_CMD_READ_MEM 0x1001
#define IPC_CMD_RESP 0x2001#define TEST_PASS 0x5555
#define TEST_FAIL 0xAAAA#pragma DATA_SECTION(readData, "MSGRAM_CPU_TO_CM")
uint32_t readData[10];uint32_t pass;IPC_MessageQueue_t messageQueue;
IPC_Message_t TxMsg, RxMsg;//
// IPC ISR for Flag 1
// C28x core sends data with message queue using Flag 0
//
__interrupt void IPC_ISR1()          //增加了中断接收函数
{
int i;
//IPC_Message_t TxMsg, RxMsg;
bool status = false;//
// Read the message from the message queue
//
IPC_readMessageFromQueue(IPC_CPU1_L_CM_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;
}
}//
// Acknowledge the flag
//
IPC_ackFlagRtoL(IPC_CPU1_L_CM_R, IPC_FLAG1);//
// Acknowledge the PIE interrupt.
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}//
// Main
//
void main(void)
{
int i;//
// Initialize device clock and peripherals
//
Device_init();// Boot CM core
//
#ifdef _FLASH
Device_bootCM(BOOTMODE_BOOT_TO_FLASH_SECTOR0);
#else
Device_bootCM(BOOTMODE_BOOT_TO_S0RAM);
#endif// Clear any IPC flags if set already
//
IPC_clearFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG_ALL);//
// Enable IPC interrupts
//
IPC_registerInterrupt(IPC_CPU1_L_CM_R, IPC_INT1, IPC_ISR1);              //注册了中断//
// Initialize message queue
//
IPC_initMessageQueue(IPC_CPU1_L_CM_R, &messageQueue, IPC_INT1, IPC_INT1);    //初始化中断//
// Synchronize both the cores
////
// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
//
EINT;
ERTM;IPC_sync(IPC_CPU1_L_CM_R, IPC_FLAG31);
//
// 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.dataw1 = 10; // Using dataw1 as data length
TxMsg.dataw2 = 1; // Message identifier//
// End of example. Loop forever
//
while(1)            //增加了循环发送用于测试
{DEVICE_DELAY_US(100000);
IPC_sendMessageToQueue(IPC_CPU1_L_CM_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE,
&TxMsg, IPC_NONBLOCKING_CALL);
DEVICE_DELAY_US(100000);}
}

,

Green Deng:

你好,我会与其他工程师咨询一下后再回复你。

,

user6328081:

用查询的方式是可以正确读取CM4返回的信息,代码如下

while(1) {

DEVICE_DELAY_US(100000); IPC_sendMessageToQueue(IPC_CPU1_L_CM_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE, &TxMsg, IPC_NONBLOCKING_CALL); DEVICE_DELAY_US(1); IPC_readMessageFromQueue(IPC_CPU1_L_CM_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE, &RxMsg, IPC_NONBLOCKING_CALL);

if((RxMsg.command == IPC_CMD_RESP) && (RxMsg.dataw1 == 10) && (RxMsg.dataw2 == 1)) pass = 1; else pass = 0; }

,

Green Deng:

你的意思是说在CM侧未触发IPC_ISR1中断吗?(或)IPC_ISR1中断未在CPU1侧触发?

然后代码是只有CPU1侧的?CM侧的代码是什么样的?

,

user6328081:

CM4侧是可以正常进入中断,CPU1侧不能进入中断,CM4用的是例程程序:

#include "cm.h"#include "ipc.h"

//// Defines//#define IPC_CMD_READ_MEM 0x1001#define IPC_CMD_RESP 0x2001

#define TEST_PASS 0x5555#define TEST_FAIL 0xAAAA

IPC_MessageQueue_t messageQueue;

//// IPC ISR for Flag 1// C28x core sends data with message queue using Flag 0//__interrupt void IPC_ISR1(){ int i; IPC_Message_t TxMsg, RxMsg; bool status = false;

// // Read the message from the message queue // IPC_readMessageFromQueue(IPC_CM_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 used TxMsg.dataw1 = status ? TEST_PASS : TEST_FAIL; TxMsg.dataw2 = RxMsg.dataw2; // Use the message identifier from the received message

IPC_sendMessageToQueue(IPC_CM_L_CPU1_R, &messageQueue, IPC_ADDR_CORRECTION_DISABLE, &TxMsg, IPC_NONBLOCKING_CALL);

// // Acknowledge the flag // IPC_ackFlagRtoL(IPC_CM_L_CPU1_R, IPC_FLAG1);}

//// Main//void main(void){ // // Initialize device clock and peripherals // CM_init();

// // Clear any IPC flags if set already // IPC_clearFlagLtoR(IPC_CM_L_CPU1_R, IPC_FLAG_ALL);

// // Enable IPC interrupts // IPC_registerInterrupt(IPC_CM_L_CPU1_R, IPC_INT1, IPC_ISR1);

// // Initialize message queue // IPC_initMessageQueue(IPC_CM_L_CPU1_R, &messageQueue, IPC_INT1, IPC_INT1);

// // Synchronize both the cores. // IPC_sync(IPC_CM_L_CPU1_R, IPC_FLAG31);

// // Loop forever. Wait for IPC interrupt // while(1);}

,

Green Deng:

好的收到,已经反馈给对方工程师了

,

Green Deng:

你好,刚收到对方工程师修改的代码:

修改版的C2000Ware msgqueue示例代码,其中有CPU1传递信息(数据传递1到10)到CM和CM使用中断方法传递信息(数据传递11到20)。

//#############################################################################
//
// FILE:ipc_ex2_msgqueue_cm.c
//
// TITLE:IPC example with interrupt and message queue
//
//! \addtogroup driver_cm_c28x_dual_example_list
//! <h1> IPC message passing example with interrupt and message queue </h1>
//!
//! This example demonstrates how to configure IPC and pass information from
//! C28x to CM core with message queues.
//! It is recommended to run the C28x1 core first, followed by the CM core.
//!
//! \b External \b Connections \n
//!- None.
//!
//! \b Watch \b Variables \n
//!- None.
//!
//
//#############################################################################
// $Copyright:
// Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti2k.com/wp-content/uploads/ti2k/DeyiSupport_C2000_
//
// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions// are met:
////Redistributions of source code must retain the above copyright//notice, this list of conditions and the following disclaimer.
////Redistributions in binary form must reproduce the above copyright
//notice, this list of conditions and the following disclaimer in the//documentation and/or other materials provided with the//distribution.
////Neither the name of Texas Instruments Incorporated nor the names of
//its contributors may be used to endorse or promote products derived
//from this software without specific prior written permission.
//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################//
// Included Files
//
#include "cm.h"
#include "ipc.h"//
// Defines
//
#define IPC_CMD_READ_MEM0x1001
#define IPC_CMD_RESP0x2001#define TEST_PASS0x5555
#define TEST_FAIL0xAAAAIPC_MessageQueue_t messageQueue;#pragma DATA_SECTION(CMData, "MSGRAM_CM_TO_CPU1")
uint32_t CMData[10];//
// IPC ISR for Flag 1
// C28x core sends data with message queue using Flag 0
//
__interrupt void IPC_ISR1()
{int i;IPC_Message_t TxMsg, RxMsg;bool status = false;//// Read the message from the message queue//IPC_readMessageFromQueue(IPC_CM_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 = (uint32_t)CMData;TxMsg.dataw1= 10;TxMsg.dataw2= 1;IPC_sendMessageToQueue(IPC_CM_L_CPU1_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE,&TxMsg, IPC_NONBLOCKING_CALL);//// Acknowledge the flag//IPC_ackFlagRtoL(IPC_CM_L_CPU1_R, IPC_FLAG1);
}//
// Main
//
void main(void)
{//// Initialize device clock and peripherals//CM_init();//// Clear any IPC flags if set already//IPC_clearFlagLtoR(IPC_CM_L_CPU1_R, IPC_FLAG_ALL);//// Enable IPC interrupts//IPC_registerInterrupt(IPC_CM_L_CPU1_R, IPC_INT1, IPC_ISR1);//// Initialize message queue//IPC_initMessageQueue(IPC_CM_L_CPU1_R, &messageQueue, IPC_INT1, IPC_INT1);//// Synchronize both the cores.//IPC_sync(IPC_CM_L_CPU1_R, IPC_FLAG31);int i;for(i=0; i<10; i++){CMData[i] = i+11;}//// Loop forever. Wait for IPC interrupt//while(1);
}//
// End of File
//

//#############################################################################
//
// FILE:ipc_ex2_msgqueue_c28x1.c
//
// TITLE:IPC example with interrupt and message queue
//
//! \addtogroup driver_cm_c28x_dual_example_list
//! <h1> IPC message passing example with interrupt and message queue </h1>
//!
//! This example demonstrates how to configure IPC and pass information from
//! C28x to CM core with message queues.
//! It is recommended to run the C28x1 core first, followed by the CM core.
//!
//! \b External \b Connections \n
//!- None.
//!
//! \b Watch \b Variables \n
//!- pass
//!
//
//#############################################################################
// $Copyright:
// Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti2k.com/wp-content/uploads/ti2k/DeyiSupport_C2000_
//
// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions// are met:
////Redistributions of source code must retain the above copyright//notice, this list of conditions and the following disclaimer.
////Redistributions in binary form must reproduce the above copyright
//notice, this list of conditions and the following disclaimer in the//documentation and/or other materials provided with the//distribution.
////Neither the name of Texas Instruments Incorporated nor the names of
//its contributors may be used to endorse or promote products derived
//from this software without specific prior written permission.
//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################//
// Included Files
//
#include "driverlib.h"
#include "device.h"//
// Defines
//
#define IPC_CMD_READ_MEM0x1001
#define IPC_CMD_RESP0x2001#define TEST_PASS0x5555
#define TEST_FAIL0xAAAA#pragma DATA_SECTION(CPU1Data, "MSGRAM_CPU_TO_CM")
uint32_t CPU1Data[10];IPC_MessageQueue_t messageQueue;
IPC_Message_tTxMsg, RxMsg;uint32_t pass;__interrupt void IPC_ISR1()
{int i;bool status = false;//// Read the message from the message queue//IPC_readMessageFromQueue(IPC_CPU1_L_CM_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE,&RxMsg, IPC_NONBLOCKING_CALL);if(RxMsg.command == IPC_CMD_RESP){status = true;for(i=0; i<RxMsg.dataw1; i++){if((*(uint32_t *)RxMsg.address + i) != i+11)status = false;}}//// Send response message//TxMsg.command = IPC_CMD_READ_MEM;TxMsg.address = (uint32_t)CPU1Data;TxMsg.dataw1= 10;// Using dataw1 as data lengthTxMsg.dataw2= 1;// Message identifierIPC_sendMessageToQueue(IPC_CPU1_L_CM_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE,&TxMsg, IPC_NONBLOCKING_CALL);//// Acknowledge the flag//IPC_ackFlagRtoL(IPC_CPU1_L_CM_R, IPC_FLAG1);Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP11);
}//
// Main
//
void main(void)
{int i;//// Initialize device clock and peripherals//Device_init();//// Boot CM core//
#ifdef _FLASHDevice_bootCM(BOOTMODE_BOOT_TO_FLASH_SECTOR0);
#elseDevice_bootCM(BOOTMODE_BOOT_TO_S0RAM);
#endif//// 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();//// Clear any IPC flags if set already//IPC_clearFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG_ALL);//// Enable IPC interrupts//IPC_registerInterrupt(IPC_CPU1_L_CM_R, IPC_INT1, IPC_ISR1);//// Initialize message queue//IPC_initMessageQueue(IPC_CPU1_L_CM_R, &messageQueue, IPC_INT1, IPC_INT1);//// Synchronize both the cores//IPC_sync(IPC_CPU1_L_CM_R, IPC_FLAG31);//// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)//EINT;ERTM;//// Fill in the data to be sent//for(i=0; i<10; i++){CPU1Data[i] = i;}//// Update the message//TxMsg.command = IPC_CMD_READ_MEM;TxMsg.address = (uint32_t)CPU1Data;TxMsg.dataw1= 10;// Using dataw1 as data lengthTxMsg.dataw2= 1;// Message identifier//// Send message to the queue// Since C28x and CM does not share the same address space for shared RAM,// ADDRESS_CORRECTION is enabled//IPC_sendMessageToQueue(IPC_CPU1_L_CM_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE,&TxMsg, IPC_NONBLOCKING_CALL);//// End of example. Loop forever//while(1);
}//
// End of File
//

,

user6328081:

谢谢!我先验证一下。

,

Green Deng:

好的

,

user6328081:

可以了,谢谢!

,

Green Deng:

客气了!

赞(0)
未经允许不得转载:TI中文支持网 » TMS320F28388D: C28XCPU1与CM4 IPC通讯不能进入中断
分享到: 更多 (0)

© 2024 TI中文支持网   网站地图 鲁ICP备2022002796号-1