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

我正在从事的项目必须在程序运行之前测试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()
可能超过了内存的末尾,但我改变了条件的界限,它仍然不喜欢运行

任何见解都会有所帮助

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++;
        }
    }
}