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.

TMS320F28378D: Dual CPU Startup From Flash

Part Number: TMS320F28378D

I've flashed both CPUs on the microcontroller to boot in standalone operation.  When power is cycled to the microcontroller, the desired results is to have both CPUs start up and begin running.  Sometimes after a power cycle, however, the microcontroller doesn't seem to begin execution.  Other times, it does begin execution.  I use IPCs to make sure that CPU1 has initialized and started the internal ADCs so that CPU2 can read from the registers.

Here's what's on CPU1 in main:

    InitSysCtrl();

    InitFlash();



    // Give Memory Access to GS0/ GS14 SARAM to CPU02
    //
    while( !(MemCfgRegs.GSxMSEL.bit.MSEL_GS0 & MemCfgRegs.GSxMSEL.bit.MSEL_GS14))
    {
        EALLOW;
        MemCfgRegs.GSxMSEL.bit.MSEL_GS0 = 1;
        MemCfgRegs.GSxMSEL.bit.MSEL_GS14 = 1;
        EDIS;
    }

    IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);

    Device_init();
    InitCpuTimers();
// Step 2. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
    DINT;

// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
    InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
    IER = 0x0000;
    IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
    InitPieVectTable();

    //Enable desired GPIO Inputs and outputs here. Reference GPIO.c for guides (file excluded from build)
    Device_initGPIO();

    // Let CPU2 know that the internal ADCs are initialized and running
    HWREG(IPC_BASE + IPC_O_SET) = 1UL << IPC_ADC_READY;

    // Wait for CPU2 to ack
    while((HWREG(IPC_BASE + IPC_O_STS) & (1UL << IPC_GPIO_READY)))
    {
    }

Here's what's in CPU2 main:

    // Copy time critical code and Flash setup code to RAM
    // This includes InitFlash(), Flash API functions and any functions that are
    // assigned to ramfuncs section.
    // The  RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
    // symbols are created by the linker. Refer to the device .cmd file.
    //
    #ifdef _FLASH
      memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
    #endif

    InitSysCtrl();
    InitFlash();

    IpcRegs.IPCBOOTSTS = C2_BOOTROM_BOOTSTS_SYSTEM_READY;

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

    //
    // Initialize GPIO and configure the GPIO pin as a push-pull output
    //
    Device_initGPIO();

    //
    // Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    //
    DINT;

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



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

    InitCpuTimers();

    // Wait until shared RAM is available.
    while((HWREGH(MEMCFG_BASE + MEMCFG_O_GSXMSEL) &
           (MEMCFG_GSXMSEL_MSEL_GS14 | MEMCFG_GSXMSEL_MSEL_GS15)) == 0U)
    {
    }

    //
    // Wait until CPU1 has init'd the ADC
    //
    while(!(HWREG(IPC_BASE + IPC_O_STS) & (1UL << IPC_ADC_READY)))
    {
    }

    //
    // ACK IPC flag 17 for CPU2
    //
    HWREG(IPC_BASE + IPC_O_ACK) = 1UL << IPC_ADC_READY;
    HWREG(IPC_BASE + IPC_O_CLR) = 1UL << IPC_GPIO_READY;

How can I ensure that after a power cycle, both CPUs begin executing?

Thanks!

  • Also of note, if the microcontroller doesn't start back up after power cycling the device, pressing the reset button has reliably started the execution of both CPUs.

  • Curtis,

    When the CPU don't seem to start your application code, did you try to connect to the device where your CPUs stuck? If you have not tried that is the first thing to do.

    Regards,

    Manoj

  • Manoj,

    When you say connect to the device, do you mean to run the debugger?  It always works if it's starting from the debugger or if it has been reset using the reset button on the LaunchPad.  It doesn't always start back properly if power has been cycled.  If working properly, it should be putting out messages on CAN, but it doesn't.

    Thanks,

    Curtis

  • Curtis,

    No, I'm not asking you to run with emulator connected. I want you to disable gel file and connect to the device. You can then load the symbols of your COFF file to know where your PC is stuck.

    Regards,

    Manoj

  • Manoj,

    Thank you for your clarification.  I'm not sure if I'm performing that properly.  In CCS 9.0.1.00004, I have clicked on the debug button in order to connect to the device.  Then I view the GEL files in the GEL Files view for both CPUs and remove them.  Then I go to Run->Load->Load Symbols for both CPUs.  After that, I click the run button for both CPUs.  Is this correct?  What is the correct procedure?

    Thank you,

    Curtis

  • Curtis,

    1) Run the device in standalone mode and recreate the problem.

    2) Remove the gel files in both CPU1 and CPU2

    3) Connect to the device and load the symbols of your COFF file. (Please don't load the program. Just load the symbols)

    Note: Make sure you don't run your code.

    Regards,

    Manoj

  • Manoj,

    I was able to determine what the issue was by connecting and loading the symbols.  I could see where the program counter seemed to loop, but I was not able to go to the disassembler to see what was happening around that location.  This is because the GUI wouldn't allow me to type in the address to search the disassembly, and the PC address was quite high to scroll all the way to from 0x0.  After step 3, the connection showed that the code was running so I paused operation. This brought me to the functions that were looping in C and the assembly.  I'm not sure if I did what was proper to do, but it allowed me to fix the problem.

    Thanks again!

    Curtis