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: F28379D

Part Number: LAUNCHXL-F28379D
Other Parts Discussed in Thread: C2000WARE, SYSCONFIG

Tool/software:

   Hi 

 

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.  

below code for CPU1

.............................................................................

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

below code for CPU2

............................................................................

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

  • Hi Keshav,

    It sounds like your issue might be with the CAN setup. Can you reference the examples in C2000Ware and compare to ensure that the setup for the CAN has been done correctly. I suspect the memory hasn't been configured properly.

    Regards,

    Ozino

  • **"Thank you for your reply, Ozino Odhara.

    Before setting up CPU2, I tested the CAN example on CPU1 using CANB, and it worked fine. I used the same configuration for CPU2, but I am facing an issue. I also compared the example code configuration and ensured that CPU2 is configured the same way, yet the issue persists. Is there any additional configuration required for CPU2?"**

  • Hi,

    I would take the IPC examples provided in C2000Ware and combine it with the CAN example and see if that works. Is that  a test you've done?

    Regards,

    Ozino

  • hello,

    thanks for your reply, I take the example code  from the libraries ipc_ex4_msgqueue_sysconfig_c28x2 and combine the can here still i facing the same issue

  • DId you compare the linker command file (.cmd) setup between the two applications to make sure that you've partitioned the memory as expected.

    Regards,
    Ozino

  • hello,

    In the example project, I couldn't find the .cmd file, so I configured it in SysConfig. Please provide a working CAN project for CPU1 and CPU2 in a dual-core setup.

    Run From
    RAMLS0

        

  • If you look under the generated sources, you should see a file named device_cmd.cmd which the linker command file. You can see the settings in the SysConfig section for the CMD file.

    Regards,

    Ozino


  • //
    // Active linker CMD configuration selected by
    // the CMD Tool global settings
    //
    #define CMD0
    #ifdef CMD0

    MEMORY
    {

    RAMM0 : origin = 0x000123, length = 0x0002DD
    RAMM1 : origin = 0x000400, length = 0x0003F8
    CLATOCPU_MSGRAM : origin = 0x001480, length = 0x000080
    CPUTOCLA_MSGRAM : origin = 0x001500, length = 0x000080
    RAMLS0 : origin = 0x008000, length = 0x000800
    RAMLS1 : origin = 0x008800, length = 0x000800
    RAMLS2 : origin = 0x009000, length = 0x000800
    RAMLS3 : origin = 0x009800, length = 0x000800
    RAMLS4 : origin = 0x00A000, length = 0x000800
    RAMLS5 : origin = 0x00A800, length = 0x000800
    RAMD0 : origin = 0x00B000, length = 0x000800
    RAMD1 : origin = 0x00B800, length = 0x000800
    RAMGS0 : origin = 0x00C000, length = 0x001000
    RAMGS1 : origin = 0x00D000, length = 0x001000
    RAMGS2 : origin = 0x00E000, length = 0x001000
    RAMGS3 : origin = 0x00F000, length = 0x001000
    RAMGS4 : origin = 0x010000, length = 0x001000
    RAMGS5 : origin = 0x011000, length = 0x001000
    RAMGS6 : origin = 0x012000, length = 0x001000
    RAMGS7 : origin = 0x013000, length = 0x001000
    RAMGS8 : origin = 0x014000, length = 0x001000
    RAMGS9 : origin = 0x015000, length = 0x001000
    RAMGS10 : origin = 0x016000, length = 0x001000
    RAMGS11 : origin = 0x017000, length = 0x001000
    RAMGS12 : origin = 0x018000, length = 0x001000
    RAMGS13 : origin = 0x019000, length = 0x001000
    RAMGS14 : origin = 0x01A000, length = 0x001000
    RAMGS15 : origin = 0x01B000, length = 0x000FF8
    CPU2TOCPU1RAM : origin = 0x03F800, length = 0x000400
    CPU1TOCPU2RAM : origin = 0x03FC00, length = 0x000400
    FLASHA : origin = 0x080000, length = 0x002000
    FLASHB : origin = 0x082000, length = 0x002000
    FLASHC : origin = 0x084000, length = 0x002000
    FLASHD : origin = 0x086000, length = 0x002000
    FLASHE : origin = 0x088000, length = 0x008000
    FLASHF : origin = 0x090000, length = 0x008000
    FLASHG : origin = 0x098000, length = 0x008000
    FLASHH : origin = 0x0A0000, length = 0x008000
    FLASHI : origin = 0x0A8000, length = 0x008000
    FLASHJ : origin = 0x0B0000, length = 0x008000
    FLASHK : origin = 0x0B8000, length = 0x002000
    FLASHL : origin = 0x0BA000, length = 0x002000
    FLASHM : origin = 0x0BC000, length = 0x002000
    FLASHN : origin = 0x0BE000, length = 0x001FF0
    RESET : origin = 0x3FFFC0, length = 0x000002
    }


    SECTIONS
    {
    //
    // C28x Sections
    //
    .reset : > RESET, TYPE = DSECT /* not used, */
    codestart : > 0x080000
    .text : >> FLASHB | FLASHC | FLASHD | FLASHE,
    ALIGN(8)
    .TI.ramfunc : LOAD > FLASHD,
    RUN > RAMLS0,
    TABLE(copyTable_ramfunc),
    ALIGN(8)
    .binit : > FLASHA,
    ALIGN(8)
    .ovly : > FLASHA,
    ALIGN(8)
    .cinit : > FLASHA,
    ALIGN(8)
    .stack : > RAMM1
    .init_array : > FLASHB,
    ALIGN(8)
    .bss : > RAMLS5
    .const : > FLASHF,
    ALIGN(8)
    .data : > RAMLS5
    .switch : > FLASHA,
    ALIGN(8)
    .sysmem : > RAMLS5
    MSGRAM_CPU1_TO_CPU2 : > CPU1TOCPU2RAM, type=NOINIT
    MSGRAM_CPU2_TO_CPU1 : > CPU2TOCPU1RAM, type=NOINIT

    }

    #endif

    /*
    //===========================================================================
    // End of file.
    //===========================================================================
    */

    //////////////////////////////////////////////////CPU2/////////////////////////////////////////


    //
    // Active linker CMD configuration selected by
    // the CMD Tool global settings
    //
    #define CMD0
    #ifdef CMD0

    MEMORY
    {

    RAMM0_BEGIN : origin = 0x000000, length = 0x000002
    RAMM0 : origin = 0x0000A2, length = 0x00035E
    RAMM1 : origin = 0x000400, length = 0x0003F8
    CLATOCPU_MSGRAM : origin = 0x001480, length = 0x000080
    CPUTOCLA_MSGRAM : origin = 0x001500, length = 0x000080
    RAMLS0 : origin = 0x008000, length = 0x000800
    RAMLS1 : origin = 0x008800, length = 0x000800
    RAMLS2 : origin = 0x009000, length = 0x000800
    RAMLS3 : origin = 0x009800, length = 0x000800
    RAMLS4 : origin = 0x00A000, length = 0x000800
    RAMLS5 : origin = 0x00A800, length = 0x000800
    RAMD0 : origin = 0x00B000, length = 0x000800
    RAMD1 : origin = 0x00B800, length = 0x000800
    RAMGS0 : origin = 0x00C000, length = 0x001000
    RAMGS1 : origin = 0x00D000, length = 0x001000
    RAMGS2 : origin = 0x00E000, length = 0x001000
    RAMGS3 : origin = 0x00F000, length = 0x001000
    RAMGS4 : origin = 0x010000, length = 0x001000
    RAMGS5 : origin = 0x011000, length = 0x001000
    RAMGS6 : origin = 0x012000, length = 0x001000
    RAMGS7 : origin = 0x013000, length = 0x001000
    RAMGS8 : origin = 0x014000, length = 0x001000
    RAMGS9 : origin = 0x015000, length = 0x001000
    RAMGS10 : origin = 0x016000, length = 0x001000
    RAMGS11 : origin = 0x017000, length = 0x001000
    RAMGS12 : origin = 0x018000, length = 0x001000
    RAMGS13 : origin = 0x019000, length = 0x001000
    RAMGS14 : origin = 0x01A000, length = 0x001000
    RAMGS15 : origin = 0x01B000, length = 0x000FF8
    CPU2TOCPU1RAM : origin = 0x03F800, length = 0x000400
    CPU1TOCPU2RAM : origin = 0x03FC00, length = 0x000400
    FLASHA : origin = 0x080000, length = 0x002000
    FLASHB : origin = 0x082000, length = 0x002000
    FLASHC : origin = 0x084000, length = 0x002000
    FLASHD : origin = 0x086000, length = 0x002000
    FLASHE : origin = 0x088000, length = 0x008000
    FLASHF : origin = 0x090000, length = 0x008000
    FLASHG : origin = 0x098000, length = 0x008000
    FLASHH : origin = 0x0A0000, length = 0x008000
    FLASHI : origin = 0x0A8000, length = 0x008000
    FLASHJ : origin = 0x0B0000, length = 0x008000
    FLASHK : origin = 0x0B8000, length = 0x002000
    FLASHL : origin = 0x0BA000, length = 0x002000
    FLASHM : origin = 0x0BC000, length = 0x002000
    FLASHN : origin = 0x0BE000, length = 0x001FF0
    RESET : origin = 0x3FFFC0, length = 0x000002
    }


    SECTIONS
    {
    //
    // C28x Sections
    //
    .reset : > RESET, TYPE = DSECT /* not used, */
    codestart : > 0x000000
    .text : >> FLASHB | FLASHC | FLASHD | FLASHE,
    ALIGN(8)
    .TI.ramfunc : LOAD > FLASHD,
    RUN > RAMLS0,
    TABLE(BINIT),
    ALIGN(8)
    .binit : > FLASHA,
    ALIGN(8)
    .ovly : > FLASHA,
    ALIGN(8)
    .cinit : > FLASHA,
    ALIGN(8)
    .stack : > RAMM1
    .init_array : > FLASHB,
    ALIGN(8)
    .bss : > RAMLS5
    .const : > FLASHF,
    ALIGN(8)
    .data : > RAMLS5
    .switch : > FLASHA,
    ALIGN(8)
    .sysmem : > RAMLS5
    MSGRAM_CPU1_TO_CPU2 : > CPU1TOCPU2RAM, type=NOINIT
    MSGRAM_CPU2_TO_CPU1 : > CPU2TOCPU1RAM, type=NOINIT

    }

    #endif

    /*
    //===========================================================================
    // End of file.
    //===========================================================================
    */

    This is my cmd-generated file, but still I'm getting the same issue. after changing the config  

  • Hi,

    Let me put you in touch with the CAN expert to provide further assistance.

    Regards,

    Ozino

  • Hey Keshav,

    Just to confirm, the code fails upon executing the CAN_initModule(CANB_BASE); function from CPU2 Main()?

    Have you tested the MCAN example only on CPU2 without IPC additions?

    Would it be possible to move your CAN initialization/configuration code to run on CPU1 before setting up the IPC? CPU2 can then still access the CANB peripheral to send the necessary messages, but the configuration of the peripheral happens earlier with CPU1 initialization.

    Best Regards,

    Zackary Fleenor

  • Hi Keshav,

    You may also want to first allocate the control of CANB to CPU2 by running the API  SysCtl_selectCPUForPeripheralInstance(SYSCTL_CPUSEL_CANB, 2,  SYSCTL_CPUSEL_CPU2) in CPU1.  Ownership of a shared module in F2837x has to be initiated in CPU1.  Once module ownership is established then module configuration (initialization, setup...etc) can be done on the selected CPU.

  • In my project,

    1.CPU1 sends a command to CPU2 via IPC (IPC_CMD_READ_CAN).
    2.CPU2 receives the command and starts receiving CAN data from an external source.
    3.CPU2 sends the received CAN data back to CPU1 via IPC.
    4.CPU1 blinks an LED (GPIO31) when it receives CAN data.
    5.CPU2 is responsible for CANB initialization and message reception.

    Issue: CPU2 Stuck Waiting for IPC Flag

    CPU2 is stuck in this loop:

    c
    CopyEdit
    while ((HWREG(IPC_CPU2_L_CPU1_R + IPC_O_FLG) & CPU1_TO_CPU2_FLAG) == 0);

    But CPU1 is calling IPC_setFlagLtoR(IPC_CPU1_L_CPU2_R, CPU1_TO_CPU2_FLAG);
     Small blue diamondHow can I confirm that CPU1 is correctly setting the IPC flag?

    Debugging Steps Tried

    1. Checked if CPU1 is calling IPC_setFlagLtoR().
    2. Toggled an LED inside the while() loop on CPU2 to check if it’s looping continuously.
    3. Verified that CPU1 executes, but it does not complete.
    4. Checked CAN ISR (canbISR()) on CPU2, but it is not triggering.

    Questions from my side.

    1. Why is CPU2 not detecting the IPC flag set by CPU1?
    2 .How can I confirm that CPU1 successfully sets the IPC flag (IPC_setFlagLtoR())?
    3. If CAN ISR (canbISR()Is not triggering, what can I check to ensure CANB is configured correctly?

    4 .Are there known issues with IPC synchronization between CPU1 and CPU2 that could cause this?

    IPC_CAN_CPU1.zipthis is my project I tried

  • Hey Keshav,

    Really appreciate the effort in providing additional information to help us continue debugging your issue.

    Since the topic has now shifted from a CAN-related issue to an IPC issue, we request that you create a new thread with this new information so we can get the right experts looped in for optimal feedback. If possible, please include a link to this original issue in the new thread for traceability/reference.

    Best Regards,

    Zackary Fleenor

  • I also tried running CANB independently using CPU2, but it's not working. Please solve this issue as well. 

  • Hi Keshav,

    Please create new E2E threads for each of these issues for additional feedback.

    Best Regards,

    Zackary Fleenor