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.
工具/软件:Code Composer Studio
您好!
我正在使用 TMS320F28388D 控制器并尝试执行以下操作、基本而言、我正在进行编程以确定某个应用是否将使用控制器的2个内核或1个内核(CPU)。
因此、如果程序不使用 CPU2、我将不会将引导加载程序加载到其中、因此它将是单核应用程序。
当连接到 CCS 调试模式时、代码工作正常、并且只能使用单核、 但是、当从 CCS 断开连接时、它无法按预期工作、也就是说、我可以在 CCS 调试模式下执行的操作是、在 CCS 调试模式下、当它未连接时、会出现相同的行为
我的代码在 CPU1和 CPU2中如下所示:
if (cpuid_1 == gu16CpuId) { DEVICE_BOOTCPU2 (BOOTMODE_BOOT_TO_FLASH_SECTOR0); }
if (cpuid_2 =gu16CpuId) { guniIpcRegs.gstrCpu2IpcRegs.CPU2TOCPU1IPCSET.bit.IPC16 = bit_set; }
if (cpuid_1 == gu16CpuId) { while (!guniIpcRegs.gstrCpu1IpcRegs.CPU2TOCPU1IPCSTS.bit.IPC16){ if (counter_exit > 0){//counter_exit = 1000 COUNTER_EXIT = COUNTER_EXIT - 1; } 否则{ 中断; } } if (guniIpcRegs.gstrCpu1IpcRegs.CPU2TOCPU1IPCSTS.bit.IPC16){ gu16ApplicationType = dual_core; } 否则{ gu16ApplicationType = single_core; } }
谢谢、
Nagesh
你好
您看到了什么行为? 是否通过引导 GPIO 正确设置了 CPU1引导模式? 您的 CPU2应用程序入口地址(CODE_START)是否位于0x80000地址?
在每个 LED 中闪烁、以便您可以查看它们是否到达其应用程序。
此致
Chris
您好 Chris、
是的、我已经使用 LED 闪烁模式来了解流速、我观察到的是、当仅选择单个内核时、控制器将得到复位。
即在 CPU1中执行语句之后。
DEVICE_BOOTCPU2 (BOOTMODE_BOOT_TO_FLASH_SECTOR0);
您能告诉我 为什么它可以得到复位、有什么调试建议吗?
谢谢、
Nagesh
你好
您是否正在禁用看门狗? 这在引导后启用、并在通过 CCS 连接时禁用。
此致
Chris
尊敬的 Chris:
是的、看门狗已禁用、我尝试在其中一个示例代码中模拟行为、我可以看到类似的行为、试图弄清楚它为什么会被复位。
情况是、输出文件应仅加载到 CPU1上。 在启动 CPU2和启动 CPU2之前、我有不同的 Keet LED 闪烁模式。
我正在使用 C28x_DUAL 中为 F2838xD 提供的示例代码、我无法在此处附加完整项目、因此无法附加更新的代码。
我已经对某些 IPC 进行了评论、因为在这里、示例代码不需要该 IPC。 并以粗体突出显示了新代码。 选择闪存。
//文件:ipc_ex1_basic_c28x1.c int gu16ApplicationType = dual_core; void main (void) { int i; int k = 0; //初始化设备时钟和外设 device_init(); DEVICE_initGPIO(); GPIO_setPadConfig (DEVICE_GPIO_PIN_LED1、GPIO_PIN_TYPE_STD); GPIO_setDirectionMode (DEVICE_GPIO_PIN_LED1、GPIO_DIR_MODE_OUT); for (k=0;k<20;k++) { //打开 LED GPIO_writePin (DEVICE_GPIO_PIN_LED1、0); DEVICE_DELAY_US (100000); GPIO_writePin (DEVICE_GPIO_PIN_LED1、1); DEVICE_DELAY_US (100000); } //启动 CPU2内核 #ifdef _flash DEVICE_BOOTCPU2 (BOOTMODE_BOOT_TO_FLASH_SECTOR0); #else DEVICE_BOOTCPU2 (BOOTMODE_BOOT_TO_M0RAM); #endif //清除任何 IPC 标志(如果已设置) IPC_clearFlagLtoR (IPC_CPU1_L_CPU2_R、IPC_FLAG_ALL); if (dual_core =gu16ApplicationType) { GPIO_setPadConfig (DEVICE_GPIO_PIN_LED2、GPIO_PIN_TYPE_STD); GPIO_setDirectionMode (DEVICE_GPIO_PIN_LED2、GPIO_DIR_MODE_OUT); //配置 CPU2以控制 LED GPIO GPIO_setMasterCore (DEVICE_GPIO_PIN_LED2、GPIO_CORE_CPU2); } for (;;) { //打开 LED GPIO_writePin (DEVICE_GPIO_PIN_LED1、0); DEVICE_DELAY_US (50000); GPIO_writePin (DEVICE_GPIO_PIN_LED1、1); DEVICE_DELAY_US (50000); }
}
您好 Chris、
我从进一步调试中还有一个观察结果。
我想知道在什么情况下 CPU2会导致控制器(F28388D)上的复位、包括 CPU1。
这仅在控制卡未连接到 CCS 时发生。
在执行"Device_bootCPU2 (bootmode_boot_boot_TO_flash_SECTOR0);"之后、它恰好发生;
谢谢、
Nagesh
Nagesh、
我将尝试在明天结束时重复并返回给您。
目前、我只能想到 CPU2具有可触发 CPU2上 NMI 的看门狗复位。 否则、CPU2无法复位整个器件。 如果 CPU1未进行复位、则有几个不同的 CPU2复位源。 请查看 TRM 章节"C28x 系统控制"->"Resets"。
我还建议独立运行后、使用删除了 GEL 的目标配置重新连接到器件。 在目标配置中、转到"Advanced"选项卡、选择"CPU1"、"CPU2"等、然后清除 GEL 的路径。 这样、当您连接时、它不会重置器件、然后您可以加载符号以查看其当前在代码中的位置。 您还可以观察 IPC 状态寄存器和其他可提供更多调试信息的寄存器。
此致
Chris
您好 Chris、
我发现它恰好在何处获得复位、我正在重复使用示例代码中的函数'void sysctl_controlCPU2Reset (sysctl_CoreReset control)'。
在它下面
if (CONTROL!= 0x0U)
{
}
其他
{
EALLOW;
clearvalue = HWREG (DEVCFG_base + SYSCTL_O_CPU2RESCTL);
clearvalue &=~SYSCTL_CPU2RESCTL_RESET;
HWREG (DEVCFG_BASE + SYSCTL_O_CPU2RESCTL)=(SYSCTL_REG_KEY 和
SYSCTL_CPU2RESCTL_KEY_M)| clearvalue;//在该宏尝试了解该宏的功能后导致复位,我可以替换它
//will a register
(i=10;i>0;i--)
{
strGpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;
DGenerateMicroSecDelay (65535);
DGenerateMicroSecDelay (65535);
DGenerateMicroSecDelay (65535);
}
EDIS;
}
谢谢
Nagesh
Nagesh
是的、当 CPU2从复位释放到启动时、您将在此处详述。 该语句将写入 CPU2RESCTL 寄存器。
我已经获取了您提供的代码并查看了场景。 我已确认 CPU2确实获得了 itrap、然后看门狗在那里触发复位、WD 复位作为 NMI 发送到 CPU1。 由于在示例中未设置 CPU1矢量表、NMI 将进入引导 ROM NMI 处理程序、该处理程序不处理 CPU2 WD NMI、因此 CPU1会由于 NMIWD 超时而复位。
如果在 Device_init()之后添加以下内容,则可以看到它在 CPU1的 NMI 默认处理程序中遇到 Estop:
// //初始化设备时钟和外设 // device_init(); // //初始化 PIE 并清除 PIE 寄存器。 禁用 CPU 中断。 // interrupt_initModule(); // //使用指向 shell 中断的指针初始化 PIE 矢量表 //服务例程(ISR)。 // interrupt_initVectorTable(); // //启用全局中断(INTM)和实时中断(DBGM) // EINT; ERTM;
您可以修改该处理程序、以便在您的方案中忽略 CPU2 WD NMI。
请注意、一种更简单的调试方法是:
此致
Chris
您好!
感谢您的分析。
我正在尝试按照您的建议更新 NMI 处理程序、并使用 C2000Ware_3_03_00_00_Software 中 TI 提供的示例代码
C:\ti\C2000Ware_3_03_00_00_Software\driverlib\f2838x\examples\C28x_DUAL_NMI
我已经更新了 NMI_ISR、将 CPU2发送回复位状态、如下所示、但我看不到它按预期工作。
我没有在 CPU2上加载任何应用、只需通过 CPU2引导而不在其中包含应用程序、我就会收到 NMI 中断、并且在该中断中将 CPU2发送回 CPU1中复位。 您能否检查我所做的工作是否正确?
void main (void) { device_init(); interrupt_initModule(); interrupt_initVectorTable(); sysctl_clearAllNMIPls(); INTERRUPT_REGISTER (INT_NMI、&NMI_ISR); SYSCTL_enableNMIPGlobalInterrupt(); INTERRUPT_ENABLE (INT_NMI); EINT; ERTM; DEVICE_BOOTCPU2 (BOOTMODE_BOOT_TO_FLASH_SECTOR0); while (1) { while (NMI_ISR_called!= 1); if (nmiflagstatus!=(SYSCTL_NMI_CPU2WDRSN | SYSCTL_NMI_NMIINT)) { ESTOP0;} NMI_ISR_called = 0; NMI_ISR_COUNT++; } }
中断空 NMI_ISR (空) { NMI_ISR_called = 1; unsigned long int 计数器= 0; unsigned long int i = 0;
//添加以在 LED 进入 NMI 中断时观察 LED 闪烁、但不观察 LED 闪烁模式 while (计数器< 5) { 计数器=计数器+ 1; GPIO_togglePin (DEVICE_GPIO_PIN_LED1); 对于(I = 0;I < 100000;I++) asm (" RPT #255 || NOP"); } nmiflagstatus = sysctl_getNMIFagStatus(); nmisdflagstatus = sysctl_getNMiShadowImage FlagStatus(); sysctl_clearAllNMIPls(); DEVICE_BOOTCPU2 (0x00); }
谢谢、
Nagesh
Nagesh
在 NMI 处理程序中、我要在 LED 闪烁之前将 NMI 标志清零、以避免 NMI WD 重置 CPU1。
DEVICE_BootCPU2 ()不会将 CPU2重新置于复位状态。 您需要调用 API sysctl_controlCPU2Reset()。 相关详细信息、请参见 driverlib 文件 sysctl.h
此致
Chris