Part Number: TMS320F28377D
Other Parts Discussed in Thread: C2000WARE
Hi team,
Here're few questions may need your help:
The program architecture is as follows:
CPU1 is used for functions such as control algorithms and PWM, CPU2 is used for communication, and data exchange between CPUs is done through IPC.
The program needs to run offline, that is, write to flash. Both cores need to move some of the functions into ram to run faster, where the functions moved into CPU1 are as follows:
//Functions that need to be moved into ram to run #ifdef _FLASH #pragma CODE_SECTION(EPWM2_ISR,"ramfuncs"); #pragma CODE_SECTION(Getresult,"ramfuncs"); #pragma CODE_SECTION(set_epwmcmp,"ramfuncs"); #pragma CODE_SECTION(PI_stop,"ramfuncs"); #endif #ifdef _FLASH memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize); Getresult(); memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize); set_epwmcmp(); memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize); PI_stop(); memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize); EPWM2_ISR();//interrupt function #endif
In CPU2, the functions moved into ram are as follows:
#ifdef _FLASH // These are defined by the linker (see device linker command file) extern Uint16 RamfuncsLoadStart; extern Uint16 RamfuncsLoadSize; extern Uint16 RamfuncsRunStart; #pragma CODE_SECTION(IPC11_RX,"ramfuncs"); #pragma CODE_SECTION(CPU01toCPU02IPC1IntHandler,"ramfuncs"); #endif #ifdef _FLASH memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize); IPC11_RX(); memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize); CPU01toCPU02IPC1IntHandler();//interrupt function #endif
When the receive function and IPC interrupt function in CPU2 are moved into ram, the program is stuck in the interrupt function of CPU2 and the program in CPU1 is functional. There are the following questions:
1) The CPU1 program does not run much differently in flash and in ram, and the difference in CPU2 is much greater. Is this normal? If an interrupt function is moved into ram, do the child functions used in the interrupt function also need to be moved into ram?
2) the program in CPU2 functions normally in flash and gets stuck in the IPC interrupt function once the interrupt function is moved into ram. Can these two cores run by moving functions into ram at the same time? Is it required to modify the cmd file?
3) In the routine, the cmd files for CPU1 and CPU2, the addresses of each partition are the same. According to the datasheet, each CPU has separate RAM and flash sections, and the RAM and flash sections of the two CPUs overlap at addresses after the flash initialization of the dual-core program. Does it contradict the description of the datasheet? Or need to define the ownership of each ram and flash in the cmd file?
The transmit function in CPU1 is as follows:
/* Data transmit */
void IPC11_TX(Uint16 *AMBFB)
{
Uint16 i;
if(IPCRtoLFlagBusy(IPC_FLAG11) == 1)//Flag bit if CPU2 is set
{
if((MemCfgRegs.GSxMSEL.bit.MSEL_GS0) == 1)//Set CPU1 as the master of the GS0 RAM
{
EALLOW;
MemCfgRegs.GSxMSEL.bit.MSEL_GS0 = 0;
EDIS;
}
for(i=0;i<10;i++)//Write the data to the shared ram
{
pusCPU01BufferPt[i] = AMBFB[i];
}
//Write the data in the shared ram to the location specified by the message ram of CPU2-1
IPCLtoRBlockWrite(&g_sIpcController2, pulMsgRam2[1],(uint32_t)pusCPU01BufferPt,10,IPC_LENGTH_16_BITS,ENABLE_BLOCKING);
IPCRtoLFlagAcknowledge(IPC_FLAG11);
//IPCLtoRFlagClear(IPC_FLAG11);
}
}
The IPC interrupt routines in CPU2 are as follows:
__interrupt void
CPU01toCPU02IPC1IntHandler (void)
{
tIpcMessage sMessage;
GPIO_WritePin(37,1);
IPCLtoRFlagSet(IPC_FLAG11);
// Continue processing messages as long as CPU01toCPU02 GetBuffer2 is full
while (IpcGet (&g_sIpcController2, &sMessage,
DISABLE_BLOCKING)!= STATUS_FAIL)
{
switch (sMessage.ulcommand)
{
case IPC_BLOCK_WRITE://CPU1 writes the data into the shared ram
IPCRtoLBlockWrite(&sMessage);
IPC11_RX();
break;
case IPC_BLOCK_READ:
IPCRtoLBlockRead(&sMessage);//CPU2 writes data at the specified address to the shared ram
break;
default:
//ErrorFlag = 1;
break;
}
}
// Acknowledge IPC INT1 Flag and PIE to receive more interrupts
IpcRegs.IPCACK.bit.IPC1 = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
GPIO_WritePin(37,0);
}
Could you help check this case? Thanks.
Best Regards,
Cherry