我正在研究的项目必须在程序运行之前测试dsPIC30F芯片的数据存储器。由于行业要求,我们无法使用C提供的任何预定义库。话虽这么说,这是我测试RAM的方法:
Step 1 - Write the word 0xAAAA to a specific location in memory (defined by a LoopIndex added to the START_OF_RAM address)
Step 2 - increment LoopIndex
Step 3 - Repeat Steps 1-2 until LoopIndex + START_OF_RAM >= END_OF_RAM
Step 4 - Reset LoopIndex = 0
Step 5 - Read memory at LoopIndex+START_OF_RAM
Step 6 - If memory = 0xAAAA, continue, else throw RAM_FAULT_HANDLER
Step 7 - increment LoopIndex
Step 8 - Repeat Step 5 - 7 until LoopIndex + START_OF_RAM >= END_OF_RAM
现在,奇怪的部分是我可以单步执行代码,没问题。只要我的小指按下F8,它就会慢慢地遍历每个内存地址,但是当我尝试在步骤4设置一个断点时,它会抛出一个随机的通用中断处理程序,没有明显的原因。我认为可能是因为我使用的for()
可能超过END_OF_RAM,但我已经改变了条件的界限,但它仍然不喜欢运行。
任何见解都会有所帮助。
void PerformRAMTest()
{
// Locals
uint32_t LoopIndex = 0;
uint16_t *AddressUnderTest;
uint32_t RAMvar = 0;
uint16_t i = 0;
// Loop through RAM and write the first pattern (0xAA) - from the beginning to the first RESERVED block
for(LoopIndex = 0x0000; LoopIndex < C_RAM_END_ADDRESS; LoopIndex+= 2)
{
AddressUnderTest = (uint32_t*)(C_RAM_START_ADDRESS + LoopIndex);
*AddressUnderTest = 0xAAAA;
}// end for
for(LoopIndex = 0x0000; LoopIndex < C_RAM_END_ADDRESS; LoopIndex += 2)
{
AddressUnderTest = (uint32_t*)(C_RAM_START_ADDRESS + LoopIndex);
if(*AddressUnderTest != 0xAAAA)
{
// If what was read does not equal what was written, log the
// RAM fault in NVM and call the RAMFaultHandler()
RAMFaultHandler();
}// end if
}
// Loop through RAM and write then verify the second pattern (0x55)
// - from the beginning to the first RESERVED block
// for(LoopIndex = C_RAM_START_ADDRESS; LoopIndex < C_RAM_END_ADDRESS; LoopIndex++)
// {
// AddressUnderTest = (uint32_t*)(C_RAM_START_ADDRESS + LoopIndex);
// *AddressUnderTest = 0x5555;
// if(*AddressUnderTest != 0x5555)
// {
// // If what was read does not equal what was written, log the
// // RAM fault in NVM and call the RAMFaultHandler()
// RAMFaultHandler();
// }
// }
}// end PerformRAMTest
您可以看到测试的第二遍写0x55
。这是给我的原始实现,但它从未起作用(至少就调试/运行而言;这种写入方法遇到了相同的随机中断,然后在继续之前立即读取相同的地址)
UPDATE :经过一些Clean&amp; Builds后,代码现在将运行直到它到达堆栈指针(WREG15),跳过,然后出错。以下是相关代码的新示例:
if(AddressUnderTest >= &SPLIMIT && AddressUnderTest <= SPLIMIT)
{
// if true, set the Loop Index to point to the end of the stack
LoopIndex = (uint16_t)SPLIMIT;
}
else if(AddressUnderTest == &SPLIMIT) // checkint to see if AddressUnderTest points directly to the stack [This works while the previous >= &SPLIMIT does not. It will increment into the stack, update, THEN say "oops, I just hit the stack" and error out.]
{
LoopIndex = &SPLIMIT;
}
else
{
*AddressUnderTest = 0xAAAA;
}
答案 0 :(得分:1)
我认为你实际上想要(C_RAM_START_ADDRESS + LoopIndex) < C_RAM_END_ADDRESS
作为你的循环条件。目前,您正在从C_RAM_START_ADDRESS
循环到C_RAM_START_ADDRESS + C_RAM_END_ADDRESS
,我假设它正在写入RAM的末尾。
您还应该将重复的代码分解为一个单独的函数,该函数将测试模式作为参数(DRY)。
答案 1 :(得分:1)
好的,我们可以通过一些方法来更好地了解您的问题所在。我想指出一些事情 - 希望我们可以一起解决这个问题。我注意到的第一件事似乎有点不合适就是这个评论:
“......总RAM变为0x17FFE ...”
我查看了dsPIC30F6012A的数据表。您可以在图3-8(第33页)中看到,SRAM空间为8K,运行范围为0x0800至0x2800。还有,这是一个小小的问题:
“所有有效地址都是16位宽,指向数据空间中的字节”
因此,您可以为地址使用16位值。我也对你的更新感到有些困惑。 SPLIM
是一个为 - 设置值的寄存器 - 该值限制了堆栈的大小。我不确定SPLIMIT
的值是多少,但是W15
是你的实际堆栈指针寄存器,而那里存储的值是堆栈顶部的地址:
“有一个堆栈指针限制寄存器(SPLIM)关联 使用堆栈指针。 SPLIM未初始化 重启。与堆栈指针的情况一样,SPLIM&lt; 0&gt; 被强制为'0',因为所有堆栈操作必须是 单词对齐。 每当有效地址(EA)为 使用W15作为源或目标生成 指针,将生成的地址与之比较 SPLIM中的值。如果是堆栈指针的内容 (W15)和SPLIM寄存器相等并且是推送 执行操作时,Stack Error Trap不会 发生。强>“
最后,堆栈从最低可用SRAM地址值增加到SPLIM
。所以我建议将SPLIM
值设置为合理的值,假设为512字节(尽管最好是test how much room you need for your stack)。
由于这个特定的堆栈向上增长,我将从0x0800开始加上我们为堆栈限制添加的内容然后从那里进行测试(这将是0x1000)。这样您就不必担心堆栈区域了。
鉴于上述情况,我将采取以下措施。
void PerformRAMTest (void)
{
#define SRAM_START_ADDRESS 0x0800
/* Stack size = 512 bytes. Assign STACK_LIMIT
to SPLIM register during configuration. */
#define STACK_SIZE 0x0200
/* -2, see pg 35 of dsPIC30F6012A datasheet. */
#define STACK_LIMIT ((SRAM_START_ADDRESS + STACK_SIZE) - 2)
#define SRAM_BEGIN_TEST_ADDRESS ((volatile uint16_t *)(STACK_LIMIT + 2))
#define SRAM_END_TEST_ADDRESS 0x2800
#define TEST_VALUE 0xAAAA
/* No need for 32 bit address values on this platform */
volatile uint16_t * AddressUnderTest = SRAM_BEGIN_TEST_ADDRESS
/* Write to memory */
while (AddressUnderTest < SRAM_END_TEST_ADDRESS)
{
*AddressUnderTest = TEST_VALUE;
AddressUnderTest++;
}
AddressUnderTest = SRAM_BEGIN_TEST_ADDRESS;
/* Read from memory */
while (AddressUnderTest < SRAM_END_TEST_ADDRESS)
{
if (*AddressUnderTest != TEST_VALUE)
{
RAMFaultHandler();
break;
}
else
{
AddressUnderTest++;
}
}
}
我的代码有点匆忙所以我确信可能存在一些错误(随意编辑),但希望这有助于您走上正确的轨道!