程序里的cahce问题
自己做的板子,在调试程序的时候,发现一个问题,想不太明白是为什么,求专家给指导一下
程序分为核0上跑的程序和核1~4上跑的程序,核0通过上位机接收下发的命令字,等待FPGA数据缓存区里的buffer满,满了之后通过emif读空其中的数据,然后发消息给核1,消息传递通过查询共享内存里的标志位实现。
typedefstruct
{
int frame_front;//帧头
int frame_cnt;//帧计数
int frame_lenth;//帧长
int Ord;//命令类型 10-设置参数,20-控制命令
int WorkMode;//工作模式10测量20标校
int CarryFre;//载频/10 10.5G/10
int MeasureState;//开始/结束测量 命令类型为控制命令时有效 10-开始,20-结束
int RotateSpeed;//转速 周/min
int FFTNum;//FFT点数
int RutterMaxNum;//目标最大航迹数
int VMin;//目标速度下限
int VMax;//目标速度上限
int RMin;//目标距离下限
int RMax;//目标距离上限
int SNRRCatch;//距离捕获门限
int SNRRLock;//距离跟踪门限
int LfmBandWidth;//扫频带宽
int LfmScanCycle;//扫频周期
unsignedint absolute_time;
float azimuth;
int frame_end;//帧尾
//int reserve[11];
}Control_word,*PControl_word;
trigger大小为84个字节
核 0 的主程序如下:
volatileint cnt0 =0,cycle_cnt = 0;
//通过网络下发的雷达控制字,存放在共享内存区
Control_word trigger;
PControl_word Ptrigger;
#pragma DATA_SECTION (trigger,"control_data");
#pragma DATA_ALIGN(trigger, 16);
//核间消息传递标志,L1cache为64BYTE一个line,对齐在line上
volatileint coretocore_flag[8][16];
#pragma DATA_SECTION (coretocore_flag,"control_data");
#pragma DATA_ALIGN(coretocore_flag,64);
main()
{
while(cnt0<=(TEST_NUM/2))
{
cnt0++;
if(cnt0%(TEST_NUM/2)==0)
printf("cnt0 is %d\n", cnt0);
//判断第一对buffer是否已满标志0101
flag = *(unsignedshort*)(0x78000000 + INT_STATUS*4);
while ((flag & 0x05) != 0x05)
{
flag = *(unsignedshort*)(0x78000000 + INT_STATUS*4);
}
if ((flag & 0x05) == 0x05)
{
for (i = 0; i < 4000; i++)
{
dataA1[i] = (*(unsignedshort*)(0x78000000 + A1_READ_DATA*4));
dataB1[i] = (*(unsignedshort*)(0x78000000 + B1_READ_DATA*4));
*(dataIA1+i) = dataA1[i];
*(dataQB1+i) = dataB1[i];
}
*(unsignedshort*)(0x78000000 + INT_CLEAR*4) = 0x05;//清中断
coretocore_flag[0][0] = 10;
CACHE_wbInvL1d((void *)(&coretocore_flag[0][0]),4,CACHE_WAIT);
//判断第二队buffer是否已满标志1010
flag = *(unsignedshort*)(0x78000000 + INT_STATUS*4);
while ((flag & 0x0A) != 0x0A)
{
flag = *(unsignedshort*)(0x78000000 + INT_STATUS*4);
}
if ((flag & 0x0A) == 0x0A)
{
for (i = 0; i < 4000; i++)
{
dataA2[i] = (*(unsignedshort*)(0x78000000 + A2_READ_DATA*4));
dataB2[i] = (*(unsignedshort*)(0x78000000 + B2_READ_DATA*4));
*(dataIA2+i) = dataA2[i];
*(dataQB2+i) = dataB2[i];
}
*(unsignedshort*)(0x78000000 + INT_CLEAR*4) = 0x0A;//清中断 coretocore_flag[0][0] = 10;
CACHE_wbInvL1d((void *)(&coretocore_flag[0][0]),4,CACHE_WAIT);
}
}
}
核1~4的主程序
//通过网络下发的雷达控制字,存放在共享内存区
Control_word trigger;
PControl_word Ptrigger;
#pragma DATA_SECTION (trigger, "control_data");
#pragma DATA_ALIGN(trigger, 16);
//核间消息传递标志,L1cache为64BYTE一个line
volatileint coretocore_flag[8][16];
#pragma DATA_SECTION (coretocore_flag,"control_data");
#pragma DATA_ALIGN(coretocore_flag, 64);
voidmain()
{
int i;
volatileint coreID =CSL_chipReadReg(CSL_CHIP_DNUM);//读取当前核的编号
int rad;
int j = 0;
int a,b,time_cycle;
int flag;
volatileint cnt1=0,cnt2=0,cnt3=0,cnt4=0;
if(coreID==1)
{
while(1)
{
CACHE_invL1d((void *)(&coretocore_flag[0][0]),4,CACHE_WAIT);
if(coretocore_flag[0][0]==10 )
{
cnt1++;
if(cnt1%(TEST_NUM)==0)
{
printf("cnt1 is %d\n", cnt1);
}
coretocore_flag[0][0]=0;
CACHE_wbInvL1d((void *)(&coretocore_flag[0][0]),4,CACHE_WAIT);
}
通过核0接收的雷达控制字trigger在核0上看共享内存开始的地方,跟上位机发下来的完全
一致
核1上看共享内存开始的地方,勾选L1D cache 与L2cahce
为什么只有从0x0c100080开始的地方好像被刷cahce了,其它的没刷,而且我理解,核0只是接收发下来的控制字,放在trigger开始的地址里,并没有操作它给它赋值,核1里只是读这个地方开始的值,也没有给它赋值,应该不会出现cahce一致性的问题啊!
没有勾选时
我核0 执行CACHE_wbInvL1d((void *)(&trigger),128,CACHE_WAIT);
核1 CACHE_invL1d((void *)(&trigger),128,CACHE_WAIT);
这样操作了后,确实cahce里的和共享内存里的是一致的,但我取第二个cahceline即0x0c100080开始地方的数,取出来的还是0,但内存里和cache里看到的不是0,这是为何啊?求TI专家给指点一下……
执行cache操作后,从共享内存里看到的数
勾选L1D cache 与L2cahce
取出来的数,放到变量test里是0,不是2
当我把trigger扩充成128字节时
typedefstruct
{
int frame_front;//帧头
int frame_cnt;//帧计数
int frame_lenth;//帧长
int Ord;//命令类型 10-设置参数,20-控制命令
int WorkMode;//工作模式10测量20标校
int CarryFre;//载频/10 10.5G/10
int MeasureState;//开始/结束测量 命令类型为控制命令时有效 10-开始,20-结束
int RotateSpeed;//转速 周/min
int FFTNum;//FFT点数
int RutterMaxNum;//目标最大航迹数
int VMin;//目标速度下限
int VMax;//目标速度上限
int RMin;//目标距离下限
int RMax;//目标距离上限
int SNRRCatch;//距离捕获门限
int SNRRLock;//距离跟踪门限
int LfmBandWidth;//扫频带宽
int LfmScanCycle;//扫频周期
unsignedint absolute_time;
float azimuth;
int frame_end;//帧尾
int reserve[11];
}Control_word,*PControl_word;
就不会出现上面所说的问题。
我想不明白的是为啥84个字节的时候就不行啊,coretocore_flag地址对齐在64边界上,刷cache也不会影响到trigger,只不过中间的44个字节没有使用而已。
//核间消息传递标志,L1cache为64BYTE一个line,对齐在line上
volatileint coretocore_flag[8][16];
#pragma DATA_SECTION (coretocore_flag,"control_data");
#pragma DATA_ALIGN(coretocore_flag,64);
user1212849:
我也遇到跟你一样的问题。应该是cache一致性的问题。我也在研究好多天了。咱们可以联系一下18610121165
Allen35065:
回复 user1212849:
如果你使用的是6678的SL2,先把prefetch buffer关掉,具体参考6678的silicon errata。
如果使用的是DDR,注意看DDR手册的说明,一个写一个读时,写的master需要做一次对DDR version寄存器的空写空读操作确保上一次写入已经生效。
Bin Ma2:
回复 user1212849:
手机号??
Bin Ma2:
回复 Allen35065:
Allen Yin
如果你使用的是6678的SL2,先把prefetch buffer关掉,具体参考6678的silicon errata。
如果使用的是DDR,注意看DDR手册的说明,一个写一个读时,写的master需要做一次对DDR version寄存器的空写空读操作确保上一次写入已经生效。
Allen35065:
回复 Bin Ma2:
在www.ti.com搜索C6678页面就可以找到了
Chi Wang1:
回复 Allen35065:
你好。请问DDR version寄存器是哪一个?我在《Keystone Architecture DDR3 Memory Controller User's Guide》(SPRUGV8E)中没有发现。请问是哪一个寄存器中哪一位?非常感谢!