This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] [参考译文] 【常见问题解答】TMS320F28388D:【常见问题解答】为什么 F2838xD 器件上的 CM 内核有时会发生 NMI 异常、报告运行时指向非闪存地址的不可纠正的闪存 ECC 错误?

Guru**** 2448780 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1549908/faq-tms320f28388d-faq-why-does-the-cm-core-on-the-f2838xd-device-sometimes-gets-into-an-nmi-exception-reporting-an-uncorrectable-flash-ecc-error-that-points-to-a-non-flash-address-at-runtime

器件型号:TMS320F28388D


工具/软件:

详细信息:

       Cortex-M4 临界情况条件在完成之前终止暂停的 AHB 事务、并与特定的访问序列对齐、这将导致 CM 互连和 CM 闪存包装程序不同步。  这将触发错误的不可纠正 ECC 错误、从而导致 NMI。  如果未处理 NMI、则会触发 NMIWD、从而使 CM 内核复位。

权变措施:

  • 选项 1:在 NMI ISR 中、如果闪存控制器记录的不可纠正错误不在闪存地址范围内、则可以忽略错误、在这种情况下、应清除错误和 NMI 标志、代码执行可以从 NMI ISR 返回。  需要在以下代码片段上修改文件 startup_cm.c 中的 NMI 处理程序。
  • 选项 2:通过禁用程序缓存 (PROG_CACHE_EN=0) 来避免临界情况、但这会对性能产生影响、因为这会关闭预取功能。

static void nmiISR(void)
{
    //
    // Enter an infinite loop.
    //

    //Workaround for False Flash ECC Error

    if(HWREG(NMI_BASE + NMI_O_CMNMIFLG) & 0x8)
    {
        if(HWREG(FLASH0ECC_BASE + FLASH_O_ERR_STATUS) & 0x4)
        {
            if((HWREG(FLASH0ECC_BASE + FLASH_O_UNC_ERR_ADDR_LOW) & 0xFFE00000) == 0x200000)
            {
                //Real Flash ECC Error Handler
                while(1)
                {
                }
            } else
            {
                FalseECCErrorCount++;
                HWREG(FLASH0ECC_BASE + FLASH_O_ERR_STATUS_CLR) = 0x4;
                HWREG(FLASH0ECC_BASE + FLASH_O_ERR_INTCLR) = 0x2;
                HWREG(NMI_BASE + NMI_O_CMNMIFLGCLR) = 0x56740009;
            }
        }

        if (HWREG(FLASH0ECC_BASE + FLASH_O_ERR_STATUS) & 0x40000)
        {
            if((HWREG(FLASH0ECC_BASE + FLASH_O_UNC_ERR_ADDR_HIGH) & 0xFFE00000) == 0x200000)
            {
                //Real Flash ECC Error Handler
                while(1)
                {
                }
            } else
            {
                FalseECCErrorCount++;
                HWREG(FLASH0ECC_BASE + FLASH_O_ERR_STATUS_CLR) = 0x40000;
                HWREG(FLASH0ECC_BASE + FLASH_O_ERR_INTCLR) = 0x2;
                HWREG(NMI_BASE + NMI_O_CMNMIFLGCLR) = 0x56740009;
            }
        }
    }
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    不跟踪 FALSE 闪存 ECC 错误数量的代码变体:

    static void nmiISR(void)
    {
        //
        // Enter an infinite loop if real Flash ECC error.
        //
    
        //
        // Workaround for False Flash ECC Error
        // Variable FalseECCErrorCount needs to be uncommented and declared as global with type uint32_t and initialized to 0
        // if the number of false uncorrectable instances needs to be recorded
        //
    
        if(HWREG(NMI_BASE + NMI_O_CMNMIFLG) & 0x8)
        {
            if(HWREG(FLASH0ECC_BASE + FLASH_O_ERR_STATUS) & 0x4)
            {
                if((HWREG(FLASH0ECC_BASE + FLASH_O_UNC_ERR_ADDR_LOW) & 0xFFE00000) == 0x200000)
                {
                    //Real Flash ECC Error Handler
                    while(1)
                    {
                    }
                } else
                {
                    //FalseECCErrorCount++;
                    HWREG(FLASH0ECC_BASE + FLASH_O_ERR_STATUS_CLR) = 0x4;
                    HWREG(FLASH0ECC_BASE + FLASH_O_ERR_INTCLR) = 0x2;
                    HWREG(NMI_BASE + NMI_O_CMNMIFLGCLR) = 0x56740009;
                }
            }
    
            if (HWREG(FLASH0ECC_BASE + FLASH_O_ERR_STATUS) & 0x40000)
            {
                if((HWREG(FLASH0ECC_BASE + FLASH_O_UNC_ERR_ADDR_HIGH) & 0xFFE00000) == 0x200000)
                {
                    //Real Flash ECC Error Handler
                    while(1)
                    {
                    }
                } else
                {
                    //FalseECCErrorCount++;
                    HWREG(FLASH0ECC_BASE + FLASH_O_ERR_STATUS_CLR) = 0x40000;
                    HWREG(FLASH0ECC_BASE + FLASH_O_ERR_INTCLR) = 0x2;
                    HWREG(NMI_BASE + NMI_O_CMNMIFLGCLR) = 0x56740009;
                }
            }
        }
    }