C2000 RAM
回帖(4)
2020-11-24 14:58:58
2020-11-24 14:59:11
2020-11-24 14:59:21
2020-11-24 14:59:39
RAM在线检测的实现
由于需要周期性的RAM检测,以电机控制为例,可以将RAM检测放到主中断里面执行。同时关键是不能影响控制程序的运行和实时性,所以主要考虑两点:
第一是主中断时间有限,要尽可能减小RAM检测的时间,所以可以将RAM分成多个小段进行检测,每段RAM越小,占用中断的时间越小,但是所有RAM检测一遍的时间会变长,这个需要综合考虑。
第二是不能破坏RAM中的变量值,所以在检测是之前将RAM段中的内容保存到专门区域,戴检测完成并且通过之后,再将保存好的数据恢复过来,使用memCopy来提高效率。
具体实现方法如下:首先定义好各个RAM区间的地址范围,可以参考具体的数据手册,如下所示:
然后定义好检测的范围和每次检测的数据长度:
注意由于STL_MARCH_TEST_testRam函数执行32位读/写测试,而在测试RAM单元阵列时,由于RAM单元的16位体系结构,所以要求起始地址为偶数,结束地址为奇数,可以测试的最大内存范围限制为65535个32位字。所以要求测试长度也需要为奇数。
在主中断里面的RAM在线检测函数里,首先将要检测区域的RAM值保存下来:
if ((gStructSTLMonitor.NowRamAddrStart >= MARCH_RAM_START)
&& (gStructSTLMonitor.NowRamAddrStart <= (MARCH_RAM_END-RAM_CHK_NUM)))
{
gStructSTLMonitor.NowRamAddrEnd = gStructSTLMonitor.NowRamAddrStart + RAM_CHK_NUM;
memCopy((uint16_t *)gStructSTLMonitor.NowRamAddrStart,(uint16_t *)
gStructSTLMonitor.NowRamAddrEnd,(uint16_t *)MARCH_RAM_BK);
}
然后进行检测:
gStructSTLMonitor.status = STL_MARCH_TEST_testRam((uint32_t *)
gStructSTLMonitor.NowRamAddrStart,(uint32_t *)gStructSTLMonitor.NowRamAddrEnd);
if(gStructSTLMonitor.status != SIG_RAM_MARCH_TEST)
{
STL_SetFail();
}
else
{
memCopy((uint16_t *)MARCH_RAM_BK,(uint16_t *)(MARCH_RAM_BK + RAM_CHK_NUM),
(uint16_t *)gStructSTLMonitor.NowRamAddrStart);
gStructSTLMonitor.NowRamAddrStart = gStructSTLMonitor.NowRamAddrEnd + 1;
gStructSTLMonitor.gTestStep++;
}
注意检测成功之后马上恢复当前区域的RAM值,并为下一次检测做好准备。如果检测发现故障,则进入故障处理函数。
RAM在线检测的实现
由于需要周期性的RAM检测,以电机控制为例,可以将RAM检测放到主中断里面执行。同时关键是不能影响控制程序的运行和实时性,所以主要考虑两点:
第一是主中断时间有限,要尽可能减小RAM检测的时间,所以可以将RAM分成多个小段进行检测,每段RAM越小,占用中断的时间越小,但是所有RAM检测一遍的时间会变长,这个需要综合考虑。
第二是不能破坏RAM中的变量值,所以在检测是之前将RAM段中的内容保存到专门区域,戴检测完成并且通过之后,再将保存好的数据恢复过来,使用memCopy来提高效率。
具体实现方法如下:首先定义好各个RAM区间的地址范围,可以参考具体的数据手册,如下所示:
然后定义好检测的范围和每次检测的数据长度:
注意由于STL_MARCH_TEST_testRam函数执行32位读/写测试,而在测试RAM单元阵列时,由于RAM单元的16位体系结构,所以要求起始地址为偶数,结束地址为奇数,可以测试的最大内存范围限制为65535个32位字。所以要求测试长度也需要为奇数。
在主中断里面的RAM在线检测函数里,首先将要检测区域的RAM值保存下来:
if ((gStructSTLMonitor.NowRamAddrStart >= MARCH_RAM_START)
&& (gStructSTLMonitor.NowRamAddrStart <= (MARCH_RAM_END-RAM_CHK_NUM)))
{
gStructSTLMonitor.NowRamAddrEnd = gStructSTLMonitor.NowRamAddrStart + RAM_CHK_NUM;
memCopy((uint16_t *)gStructSTLMonitor.NowRamAddrStart,(uint16_t *)
gStructSTLMonitor.NowRamAddrEnd,(uint16_t *)MARCH_RAM_BK);
}
然后进行检测:
gStructSTLMonitor.status = STL_MARCH_TEST_testRam((uint32_t *)
gStructSTLMonitor.NowRamAddrStart,(uint32_t *)gStructSTLMonitor.NowRamAddrEnd);
if(gStructSTLMonitor.status != SIG_RAM_MARCH_TEST)
{
STL_SetFail();
}
else
{
memCopy((uint16_t *)MARCH_RAM_BK,(uint16_t *)(MARCH_RAM_BK + RAM_CHK_NUM),
(uint16_t *)gStructSTLMonitor.NowRamAddrStart);
gStructSTLMonitor.NowRamAddrStart = gStructSTLMonitor.NowRamAddrEnd + 1;
gStructSTLMonitor.gTestStep++;
}
注意检测成功之后马上恢复当前区域的RAM值,并为下一次检测做好准备。如果检测发现故障,则进入故障处理函数。
举报
更多回帖