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.

LAUNCHXL-F28379D: CPU2 Stuck During CAN Initialization After Receiving IPC Command from CPU1

Part Number: LAUNCHXL-F28379D


Tool/software:

hello,

In my project, I am utilizing two CPUs where CPU1 sends commands to CPU2 via Inter-Processor Communication (IPC). Upon receiving a command from CPU1, CPU2 transmits the CAN data stored in its buffer. CPU2 receives CAN data from an external source. However, I am encountering an issue: when I start or run the code, CPU2 gets stuck during CAN initialization. Upon debugging, the code halts at the can_initialization_RAM section.

I have configured the IPC communication between CPU1 and CPU2 as per the guidelines provided in the C2000Tm Multicore Development User Guide. Specifically, I have ensured that CPU1 writes data to the CPU1_TO_CPU2 MSGRAM, and CPU2 reads from this location. 

cpu1 code
///////////////////////////////////////////////////
//
// Included Files
//
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "ipc.h"
#include "memcfg.h"

//
// Defines
//
#define IPC_CMD_READ_CAN 0x1002

#define CPU1_TO_CPU2_FLAG IPC_FLAG0
#define CPU2_TO_CPU1_FLAG IPC_FLAG1
#define SYNC_FLAG IPC_FLAG31

#define CAN_DATA_SIZE 8

#pragma DATA_SECTION(canData, "MSGRAM_CPU2_TO_CPU1")

volatile uint32_t canData[CAN_DATA_SIZE];

//
// Function to Blink LED
//
void blinkLED()
{
GPIO_togglePin(DEVICE_GPIO_PIN_LED1);
DEVICE_DELAY_US(500000);
GPIO_togglePin(DEVICE_GPIO_PIN_LED1);
}

//
// Main Function
//
void main(void)
{
// Initialize device and peripherals
Device_init();
// MemCfg_initSections(MEMCFG_SECT_MSGRAM_CPU2_TO_CPU1);
//MemCfg_initSections(MEMCFG_SECT_MSGRAM_CPU2_TO_CPU1);
Interrupt_initModule();
Interrupt_initVectorTable();
Board_init();

// Configure LED pin
GPIO_setPinConfig(DEVICE_GPIO_PIN_LED1);
GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED1, GPIO_DIR_MODE_OUT);
GPIO_setPadConfig(DEVICE_GPIO_PIN_LED1, GPIO_PIN_TYPE_STD);
GPIO_setMasterCore(DEVICE_GPIO_PIN_LED1, GPIO_CORE_CPU1);

// Initialize IPC and synchronize with CPU2
IPC_clearFlagLtoR(IPC_CPU1_L_CPU2_R, IPC_FLAG_ALL);
IPC_sync(IPC_CPU1_L_CPU2_R, SYNC_FLAG);

EINT; // Enable global interrupts
ERTM;

// while(1)
// {
// // Request CAN data from CPU2
// IPC_sendCommand(IPC_CPU1_L_CPU2_R, CPU1_TO_CPU2_FLAG, IPC_ADDR_CORRECTION_ENABLE,
// IPC_CMD_READ_CAN, 0, 0);
//
// // Wait for CPU2 response before accessing data
// IPC_waitForAck(IPC_CPU1_L_CPU2_R, CPU2_TO_CPU1_FLAG);
//
// // Blink LED immediately when data is received
// blinkLED();
//
// DEVICE_DELAY_US(1000000);
// }

while(1)
{
// Request CAN data from CPU2
IPC_sendCommand(IPC_CPU1_L_CPU2_R, CPU1_TO_CPU2_FLAG, IPC_ADDR_CORRECTION_ENABLE,
IPC_CMD_READ_CAN, 0, 0);

// Wait for CPU2 response before accessing data
IPC_waitForAck(IPC_CPU1_L_CPU2_R, CPU2_TO_CPU1_FLAG);

// Check received data
uint8_t i;
bool valid = true;
for(i = 0; i < CAN_DATA_SIZE; i++)
{
if(canData[i] == 0)
{
valid = false;
break;
}
}

if(valid)
{
blinkLED();
}

DEVICE_DELAY_US(1000000);
}
}
cpu2 code
///////////////////////////////////////////////////////////////////////////////////////
//
// Included Files
//
#include "device.h"
#include "can.h"
#include "interrupt.h"
#include "sysctl.h"
#include "board.h"
#include "ipc.h"

//
// Defines
//
#define IPC_CMD_READ_CAN 0x1002
#define IPC_CMD_RESP 0x2002

#define CPU1_TO_CPU2_FLAG IPC_FLAG0
#define CPU2_TO_CPU1_FLAG IPC_FLAG1
#define SYNC_FLAG IPC_FLAG31

#define TX_MSG_OBJ_ID 1
#define RX_MSG_OBJ_ID 1
#define MSG_DATA_LENGTH 8


//#pragma DATA_SECTION(rxMsgData, "MSGRAM_CPU1_TO_CPU2")
//volatile uint16_t rxMsgData[MSG_DATA_LENGTH] = {0};

#pragma DATA_SECTION(rxMsgData, "GSRAM");
volatile uint16_t rxMsgData[MSG_DATA_LENGTH] = {0};

//
// Function Prototypes
//
__interrupt void IPC_ISR0(void);
__interrupt void canbISR(void);

//
// Main Function
//
void main(void)
{
// Initialize Device & GPIOs
Device_init();
// MemCfg_initSections(MSGRAM_CPU1_TO_CPU2);
Device_initGPIO();

// Configure CANB for RX
GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXB);
GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXB);


// Initialize CANB Module
CAN_initModule(CANB_BASE);
CAN_setBitRate(CANB_BASE, DEVICE_SYSCLK_FREQ, 500000, 20);

// Enable CANB interrupts
CAN_enableInterrupt(CANB_BASE, CAN_INT_IE0 | CAN_INT_ERROR | CAN_INT_STATUS);

// Initialize Interrupt System
Interrupt_initModule();
Interrupt_register(INT_CANB0, &canbISR);
Interrupt_enable(INT_CANB0);

// Setup RX Message Object
CAN_setupMessageObject(CANB_BASE, RX_MSG_OBJ_ID, 0x1, CAN_MSG_FRAME_STD,
CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE, MSG_DATA_LENGTH);

CAN_startModule(CANB_BASE);

// IPC Initialization
IPC_clearFlagLtoR(IPC_CPU2_L_CPU1_R, IPC_FLAG_ALL);
IPC_sync(IPC_CPU2_L_CPU1_R, SYNC_FLAG);

// Register IPC Interrupt
Interrupt_register(INT_IPC_0, IPC_ISR0);
Interrupt_enable(INT_IPC_0);

// Enable Global Interrupts
EINT;
ERTM;

while (1);
}

//
// CANB Interrupt Service Routine (ISR)
//
__interrupt void canbISR(void)
{
uint32_t status = CAN_getInterruptCause(CANB_BASE);

if (status == RX_MSG_OBJ_ID)
{
// Read received CAN data
CAN_readMessage(CANB_BASE, RX_MSG_OBJ_ID,(uint16_t*)rxMsgData);
}

CAN_clearGlobalInterruptStatus(CANB_BASE, CAN_GLOBAL_INT_CANINT0);
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}

//
// IPC Interrupt Service Routine (Handles CPU1 -> CPU2 Command)
//
__interrupt void IPC_ISR0(void)
{
uint32_t command;

// Read IPC command from CPU1
IPC_readCommand(IPC_CPU2_L_CPU1_R, CPU1_TO_CPU2_FLAG, IPC_ADDR_CORRECTION_ENABLE,
&command, NULL, NULL);

if (command == IPC_CMD_READ_CAN)
{
uint8_t i;
// Send stored CAN data to CPU1 via IPC
for(i = 0; i < MSG_DATA_LENGTH; i++)
{
IPC_sendCommand(IPC_CPU2_L_CPU1_R, CPU2_TO_CPU1_FLAG, IPC_ADDR_CORRECTION_ENABLE,
IPC_CMD_RESP, rxMsgData[i], i);
}

// Wait for CPU1 to acknowledge reception
IPC_waitForAck(IPC_CPU2_L_CPU1_R, CPU2_TO_CPU1_FLAG);
}

IPC_ackFlagRtoL(IPC_CPU2_L_CPU1_R, CPU1_TO_CPU2_FLAG);
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}