C RAM测试步骤通过,但在运行时失败
我正在从事的项目必须在程序运行之前测试dsPIC30F芯片的数据存储器。由于行业要求,我们不能使用C提供的任何预定义库。也就是说,以下是我测试RAM的方法:C RAM测试步骤通过,但在运行时失败,c,testing,embedded,ram,pic,C,Testing,Embedded,Ram,Pic,我正在从事的项目必须在程序运行之前测试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 S
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()
可能超过了内存的末尾,但我改变了条件的界限,它仍然不喜欢运行
任何见解都会有所帮助
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
我认为您实际上想要
(C\u RAM\u START\u ADDRESS+LoopIndex)
作为循环条件。目前,您正在从C\u RAM\u START\u ADDRESS
循环到C\u RAM\u START\u ADDRESS+C\u RAM\u END\u ADDRESS
,我假设它正在写入RAM的末尾
您还应该将重复的代码分解成一个单独的函数,该函数将测试模式作为参数()。好的,因此我们可以查看一些内容,以便更好地了解问题所在。我想指出一些事情,希望我们能一起解决。我注意到的第一件似乎有点不合时宜的事情是这样的评论: “…总RAM为0x17FFE…” 我在数据表上查了一下。您可以在图3-8(第33页)中看到,SRAM空间为8K,从0x0800到0x2800运行。此外,还有一个小道消息: “所有有效地址均为16位宽,并指向数据空间中的字节” 因此,您可以使用16位值作为地址。我对你的更新也有点困惑
SPLIM
是一个寄存器,您可以为其设置值,该值限制堆栈的大小。我不确定SPLIMIT
的值是多少,但是W15
是实际的堆栈指针寄存器,存储在那里的值是堆栈顶部的地址:
“有一个堆栈指针限制寄存器(SPLIM)关联
使用堆栈指针。SPLIM在
与堆栈指针的情况一样,SPLIM
强制为“0”,因为所有堆栈操作都必须
单词对齐。每当使用有效地址(EA)时
使用W15作为源或目标生成
指针,则将由此生成的地址与
SPLIM中的值。如果堆栈指针的内容
(W15)和SPLIM寄存器相等,且为推送
如果执行此操作,则不会出现堆栈错误陷阱
发生。“
最后,堆栈从最低可用SRAM地址值增长到SPLIM
。因此,我建议将SPLIM
值设置为合理的值,比如512字节(尽管最好设置为)
由于这个特定堆栈向上增长,我将从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++;
}
}
}
void性能测试(void)
{
#定义SRAM_开始地址0x0800
/*堆栈大小=512字节。指定堆栈大小限制
在配置期间对寄存器进行SPLIM*/
#定义堆栈大小0x0200
/*-2,见dsPIC30F6012A数据表第35页*/
#定义堆栈限制((SRAM开始地址+堆栈大小)-2)
#定义SRAM开始测试地址((易失性uint16测试*)(堆栈限制+2))
#定义SRAM_END_TEST_地址0x2800
#定义测试值0xAAAA
/*在此平台上不需要32位地址值*/
易失性uint16\u t*AddressUnderTest=SRAM\u BEGIN\u TEST\u地址
/*写入内存*/
while(AddressUnderTest
我的代码有点仓促,所以我确信可能会有一些错误(请随意编辑),但希望这将有助于您走上正确的道路 你的程序和堆栈在内存中的什么位置?你不应该将
(C\u RAM\u START\u ADDRESS+LoopIndex)
转换为(uint16\u t*)
?@leedinelcrocker-数据内存理论上应该从0x0800开始,程序内存开始,我们不知道。我们知道W15寄存器是堆栈指针,我们有一个变量SPLIMIT,我试图验证它并使LoopIndex跳过它,但是,它也不起作用。@Magtheridon96-理论上,是的,但是,总RAM为0x17FFE,而且,这也是基于给我的代码。所以,在程序运行时,您可能正在写入程序指令/数据/堆栈?这不能很好地结束。我已将LoopIndex
更改为(C\u RAM\u START\u ADDRESS+LoopIndex)
,程序仍然停止。此外,我之前将write和read函数拆分为两个不同的for()
循环,以测试一种理论,即我们遇到的问题是由于写入后读取的竞争条件造成的。不,拆分后仍然不起作用。这有很大帮助,而且在很大程度上是有效的。我目前正在调试它,看看哪里出错了,但它肯定比我最初使用的更简洁。所以,我做了更多的挖掘,实际上,SPLIMIT
是SPLIM<
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++;
}
}
}