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.
您好,
我正在尝试将数据从一个CPU1传递到CPU2,反之亦然(以阵列形式)。 我已成功地将数据从CPU1传输到CPU2,但似乎不能实现相反效果。
以下是两个数组,其中具有用于内存分配的#pragma语句:
#pragma DATA_SECTION(mT,"Cpu1ToCpu2RAM") uint16_t mT[4]; #pragma DATA_SECTION(iT,"Cpu2ToCpu1RAM") uint16_t iT[2];
在CPU1中更新MT,如果在以下ISR中传递到CPU2,则由CPU1触发:
interrupt void probe_CPU2(void) { // stuff to ship to CPU2 dummy update -------------------- if((ISR_count1 % 40000) == 0){ slider1++; slider2 += 2; } // Communicate with CPU2 via IPC SendDataToCpu2 = slider1; SendAddrToCpu2 = slider2; IpcRegs.IPCSENDDATA = (Uint32) SendDataToCpu2; // Write the result to the IPC data register IpcRegs.IPCSENDADDR = (Uint32) SendAddrToCpu2; // Write the result to the IPC addr register IpcRegs.IPCSET.bit.IPC1 = 1; // Set the IPC1 flag for CPU2 RecDataFromCpu2 = (Uint16) IpcRegs.IPCRECVDATA; // Read data on IPC data register RecAddrFromCpu2 = (Uint16) IpcRegs.IPCRECVADDR; // Read data on IPC addr register // Arrays management // Transfer modulation signals from CPU1 to CPU2 mT[0] = slider1; mT[1] = slider2; mT[2] = slider1; mT[3] = slider2; // data updated by CPU2 --- NOT WORKING!!! input1 = iT[0]; input2 = iT[1]; PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; // Acknowledge PIE group 3 to enable further interrupts EPwm2Regs.ETCLR.bit.INT = 1; // Clear EPWM1_INT flag to allow further interrupts }
此ISR为CPU2设置IPC1标志,以使用以下ISR (在修改后)进行响应:
interrupt void ipc1_isr(void) { // Read data from CPU1 temp1 = (Uint16) IpcRegs.IPCRECVDATA; temp2 = (Uint16) IpcRegs.IPCRECVADDR; // Send data back to CPU1 multiplied IpcRegs.IPCSENDDATA = (Uint16) temp1*4; // send CPU2.CLA response back to CPU1 IpcRegs.IPCSENDADDR = (Uint16) temp2*4; ISR_count1_cpu2++; // ISR coutner if(ISR_count1_cpu2 % 20000 == 0){ dummy1++; iT[0] = dummy1; iT[1] = dummy1 + 1; } // Return from interrupt house keeping IpcRegs.IPCACK.bit.IPC1 = 1; // Clear IPC1 bit PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge PIE group 1 to enable further interrupts }
调试我在CPU2中看到正确更新了mt时没有问题。 我也可以看到它在CPU2中正确更新,但我看不到CPU1对它的任何修改,因为input1和input2变量始终保持0,而不使用它的实际新值更新,CPU2确实修改了该值。
似乎我可以从CPU1修改mt并使它对CPU2可见,这是可以的,但似乎虽然我可以在CPU2中修改它的阵列,但我看不到CPU1的修改发生。
我们非常感谢您的任何帮助。
非常感谢,
尼古拉
作为更新,我实际上能够看到以下命令:
#pragma data_section(MT,"Cpu1ToCpu2RAM")
uINT16_t mt[4];
#pragma data_section(it,"Cpu2ToCpu1RAM")
UINT16_t it[2];
尽管定义方式相同,但实际上不要为两个不同的CPU标识相同的内存地址。 仅第二个阵列会发生这种情况。 换言之,内存中的地址与从CPU1和CPU2调试器中看到的MT阵列的地址相同,但它们却不同。 我检查了.cmd文件中的内存部分,但它们看起来是一致的。 有什么建议?
非常感谢,
尼古拉
您好,Nicola,
您是否在两个项目中定义了相同的变量? 这可能无法保证变量在两个内核中被分配到相同的地址,因为它们都是独立的CCS项目。 如果您有多个区段分配给 Cpu1ToCpu2RAM / Cpu2ToCpu1RAM,则可能会发生这种情况。
解决这个问题的方法很少是-
1)仅在一个项目中定义变量,并在初始化过程中使用IPC将阵列的地址传递给CPU2
2) 为 需要分配给MSGRAM的每个全局设置单独的部分
#pragma DATA_SECTION(mT,"Cpu1ToCpu2RAM_1") uint16_t mT[4]; #pragma DATA_SECTION(iT,"Cpu2ToCpu1RAM_1") uint16_t iT[2]; #pragma DATA_SECTION(otherVar,"Cpu1ToCpu2RAM_2") uint16_t otherVar[4]; #pragma DATA_SECTION(otherVar,"Cpu2ToCpu1RAM_2") uint16_t otherVar[2];
在链接程序cmd文件中,您可以使用Group来确保按完全相同的顺序分配各部分
GROUP : > CPU1TOCPU2RAM { Cpu1ToCpu2RAM_1 Cpu1ToCpu2RAM_2 }
3)不使用data_sectionpragma,而是使用位置pragma强制链接器在指定的内存位置分配数组
示例用法:
#pragma LOCATION( x , address ) int x;
此致,
Veena
您好,Veena,
谢谢。
是的,我在两个项目中都指定了#pragma语句。
感谢您的建议,我将尝试这些建议。
此致,
尼古拉
您好,Nicola,
以下是编译器团队的响应-
强制全局变量排序的方法一文 说明了如何将一个或多个变量放在特定地址。 在您的情况下,两个项目必须共享执行此操作的代码。 关于实现它的源文件,我建议它们位于两个CCS项目之外的一个位置,然后按照 此处所述将这些文件链接到每个项目。 请记住,链接程序命令文件也可以#include文件。 最好的编程方法是在 一个位置定义重要的细节(如共享内存的基本地址),然后自动将其传播到需要它的所有其他位置。
此致,
Veena