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.

[参考译文] TMS320F280039:PIE 处理程序诊断中的重复和永久硬件故障

Guru**** 2393725 points
Other Parts Discussed in Thread: C2000WARE, UNIFLASH

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1519933/tms320f280039-repetitive-and-permanent-hardware-fault-on-pie-handler-diagnostics

器件型号:TMS320F280039
Thread 中讨论的其他器件:C2000WAREUNIFLASH

工具/软件:

我在一个应用程序中、在启动时、我从 C2000 诊断库中添加了诊断信息、并复制了 C2000Ware v.5.04 中的示例。 安装目录中的代码C:\ti\c2000\C2000Ware_5_04_00_00\libraries\diagnostic\f28003x\examples\test_application\进行了一系列测试、其中包括 PIE RAM 和 PIE 处理程序测试。

验证所有测试是否都在运行后、我转到了我的应用程序、该应用程序对两个 SPI 通道和几个 I/O 之间交换的数据执行一些处理。 然后、我的所有工作都涉及数据协议和处理、因为硬件功能正常。

经过几周的工作、其中一个电路板在初始测试中停止工作。 使用调试器 (XDS110) 检查后发现 PIE 处理程序测试失败。 这是正确的:PIE 外围设备被断开并停止响应 不限 EOC 中断。 然后我送了一个板 MCU 更换 并开始在另一个电路板上工作。

该问题开始出现在其他一些电路板上、既从 RAM 运行代码(与调试器一起加载)、也从闪存运行代码。 最后一个事件发生在今天上午:当我加载调试器昨天完美运行的相同代码时,它导致了另一个永久的 PIE 处理程序故障。 我可以切换电源、从调试器运行代码、但是 中断外设不再工作

到目前为止、我更换了 3 个 MCU(加上今天的第 4 部分失败)。 其中一个已被更换两次,但它们都来自同一批次 — 标记为 F280039SPZ 7美元 –37CXKCW G4

我不知道什么会导致永久性损坏,总是在相同的内部外设。 该电路板有许多其他器件(一个额外的 F280049、几个 FPGA,接口逻辑等)、它们都没有发生过故障。

我可以做些什么来分析问题? 是否有任何资源可以为我提供帮助?

【编辑】

经过进一步测试、我发现 MCU 表现出奇怪的行为 可恢复正常运行 。 然而,这个过程和它的意义仍然令我感到困惑。
以下是情况和第一个解决方案 (?) 我施加了:

1. MCU 闪存、无 随机测试代码在启动时运行(遗憾的是,我没有关于确切的先例条件的记录)
2.使用调试器加载 MCU RAM 并进行诊断测试(应用程序 A )、其中两个结果中的任何一个:
  2.a. PIE 处理程序 测试成功  (小时/天/周)
  2.b. PIE 处理程序 测试失败:  对电源执行的任何操作(开/关/开循环)或调试操作的重复都会产生相同的结果

然后我做了以下工作:

-加载/运行test_application之前提到的闪存 我的诊断应用程序的闪存版本 A 登录页面
-然后加载 MCU RAM,使用调试器,带有诊断测试(应用程序 A ):PIE 处理程序  测试成功
-董事会,在上述行动后,完美的工作

它的含义是什么? 我不知道。

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

    尊敬的 Luca:

    我将邀请我们的诊断库专家查看您的问题。 请期待他们在接下来的 1-2 天内给予答复。

    此致、

    Delaney

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

    所以你指的是 STL_PIE_RAM_testHandler () 测试失败? 中断号参数的一个特定值还是多个特定值失败?

    如果您在 STL_PIE_RAM_testHandler() 之外手动触发中断(设置 PIEIFR 位)(它以模拟的冗余矢量表不匹配运行并触发错误处理程序而不是预期的 ISR)、它是否会执行?

    在加载应用程序之前完全擦除闪存是否可以解决问题、或者只有您在上面描述的顺序迄今为止有效?

    Whitney

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

    您好 Whitney、

    我使用一些 EPWM 单元的中断尝试了处理程序测试、并始终获得相同的结果。

    请注意、 PFIEFR 上 STL_PIE_RAM_testHandler () 的测试/结果扩展到我使用的任何其他中断:它们都不再是矢量的。 在一些初始尝试中、我注释掉了测试函数以允许我的代码运行。 但是、不再处理其他中断 (SPI、ADC、ePWM)。

    擦除闪存也起到了作用。 我很久没有意识到这一点、因为我的代码最初是由调试器探针加载到 RAM 中的。 稍后、我重点介绍了在闪存中对代码进行编程(几乎所有代码都复制到 RAM 中并从 RAM 运行)。

    请注意、即使从 RAM 运行、我也可以对闪存的某些部分进行一次编程、看看电路板是否能够在没有调试器的情况下运行。
    经过多次尝试后、我可以想象它一直重复以下内容:上电、从闪存启动我旧的测试代码、从 RAM 调试(使用新代码重复多次)、此例程的小时/天/周、而不再触摸闪存...在某些时候、中断根本不会得到处理(关闭/打开电源,从调试器断开电路板连接,将其存储几天,不会进行任何更改 — 此时刷新)。

    【编辑】

    现在、这似乎无关、但我可以从运行 HWBIST 测试中获得一条线索、当时我的 PIE 也不是像上文所述的引导中断。

    实际上、在这些情况下、即使 HWBIST 也失败。 MCU 卡在 BootROM 等待点(在 0x3FEEC9–0x3FEEF9 范围内、ITRAP ISR) 。  阅读“应用手册 — C2000 硬件内置自检“文档 SPRACA7A、我发现这是最后一条注释:

    如果 CPU 恢复正常、但它会引导至 BootROM 或闪存、一个可能的原因是 PIE 没有
    被启用。 HWBIST 在完成后执行 CPU 复位、但如果未启用 PIE、则 CPU 向引导
    BootROM、而不是诊断库 STL_HWBIST_restoreContext() 代码。

    在 PIE 处理程序测试中、我在运行 STL_HWBIST_runMicro () 之前检查了 PIECTRL.ENPIE 是否设置了、和  好了 “1"符合“符合预期。

    可能是我有另一个 PIE 设置导致无法进行正确的 PIE 处理程序测试?

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

    它只会影响 PIE 中断吗? 如果您强制使用非 PIE 中断(如计时器 1、2、甚至 NMI)、它是否有效?

    影响所有中断的中断执行的事情将是您指出的 ENPIE、或者它们在 CPU INTM 位中被屏蔽。

    执行所有各种中断寄存器(PIEIFR、PIEIER、CPU IFR、CPU IER 等) 出现这种情况时、您会期待什么?

    Whitney

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

    我以前没有尝试过非 PIE 中断,但现在我看到即使这些中断也没有得到响应 — 我尝试了 CPU TIMER2。

    寄存器始终看起来正常:ST1.INTM = 0、IER.INT14 = 1、TIMER2 正在运行、但是 IFR.INT14 为 0

    我修改了应用、使其仅限于如下所示、其中计时器函数从自检应用示例中提取、并针对 TIMER2 进行了修改

    int main(void)
    {
    Device_init();
    Device_initGPIO();

    SysCtl_setWatchdogMode(SYSCTL_WD_MODE_INTERRUPT);

    DINT;

    Interrupt_initModule();
    Interrupt_initVectorTable();

    self_test_timer_config(1000u); // ******************************

    STL_PIE_RAM_configHandler(&regular_pieVectError);

    sys_init_LED0(); // GPIO line setup
    sys_init_LED1(); // GPIO line setup

    EINT;
    ERTM;

    while (!self_test_timer_has_timedout()) // ******************************
    {
    sys_set_LED0(1u); // GPIO, LED on
    SysCtl_delay((DEVICE_SYSCLK_FREQ / 5000u) * 125u);
    sys_set_LED0(0u); // GPIO, LED off
    SysCtl_delay((DEVICE_SYSCLK_FREQ / 5000u) * 125u);
    }

    do {
    sys_set_LED0(1u);
    sys_set_LED1(0u);
    } while (true); // ******************************

    // ... the rest of the code is then ignored

    ...
    }


    volatile bool timer2_OutFlag;
    volatile uint16_t timer2_OutCount;
    volatile uint16_t timer2_isrTimeout;

    #define TIMER2_RES (100u)
    #define TIMER2_PERIOD (DEVICE_SYSCLK_FREQ / TIMER2_RES)

    #pragma CODE_SECTION(timer2_ISR,".TI.ramfunc")
    __interrupt void timer2_ISR(void)
    {

    if(timer2_isrTimeout++ >= timer2_OutCount)
    {
    timer2_isrTimeout = 0u;
    timer2_OutFlag = true;
    }
    }


    static void self_test_timer_config(uint16_t msTimeOut)
    {
    Interrupt_register(INT_TIMER2, &timer2_ISR);

    timer2_OutCount = msTimeOut / TIMER2_RES;
    timer2_OutFlag = false;
    timer2_isrTimeout = 0u;

    CPUTimer_setPeriod(CPUTIMER2_BASE, (TIMER2_PERIOD - 1));
    CPUTimer_setPreScaler(CPUTIMER2_BASE, 0);
    CPUTimer_stopTimer(CPUTIMER2_BASE);
    CPUTimer_reloadTimerCounter(CPUTIMER2_BASE);
    CPUTimer_setEmulationMode(CPUTIMER2_BASE,
    CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
    CPUTimer_enableInterrupt(CPUTIMER2_BASE);
    CPUTimer_startTimer(CPUTIMER2_BASE);

    Interrupt_enable(INT_TIMER2);
    }


    static bool self_test_timer_has_timedout(void)
    {
    return timer2_OutFlag;
    }

    请注意、使用上面的代码、我确实完成了 这些测试按顺序(从非工作中断条件开始)

    • 中断失败的系统 — 为其编译 闪存中 ;应用程序循环 永远 等待 TIMER2 中断
    • 中断失败的系统 — 为其编译 RAM ; 应用程序循环 永远 等待 TIMER2 中断
    • 电流 闪存擦除 使用 UniFlash — 仍在运行编译的 RAM 二进制:应用程序提供 TIMER2 中断、在第二个循环和最后一个循环中结束
    • 再次运行为编译的 闪存中 二进制;应用程序提供 TIMER2 中断

    由于代码现在过于简化,我在某处添加了一个荒谬的错误,我仍然看不到它。

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

    您在电路板上的引导模式引脚设置为什么? 擦除闪存可以解决问题、这让我想知道您的器件是否正在引导至闪存、执行一些将器件置于奇怪状态的代码、然后在连接调试器并将其加载到 CCS 中后影响应用程序的行为。

    假设现在将它们设置为闪存引导、如果您将它们更改为等待引导、并且问题消失(重启电路板,它位于“等待“函数中,而不是运行闪存中的任何内容)、那么这就是该理论、尽管我们仍然必须缩小导致该问题的之前编程应用程序的具体范围。

    Whitney

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

    我仔细检查了板载和原理图上的引导引脚。 GPIO24 和 GPIO32 有一个上拉电阻器、并且从 main () 中的软件对它们进行测试的级别为`1`。
    请注意、板载 GPIO24 用作 MCU 的输出、驱动逻辑门;在我的测试代码中、我将其保留为输入。

    可以生成所有好结果和坏结果的应用程序是一个。 “我知道,就一会儿。 我把它附在这里 这是一个很好的方法,但它是一个很好的方法。
    在原始板上、我只使用并配置了两条信号线:GPIO54 和 GPIO56。 它们都连接到 LED、通过`0`转动 LED on.e2e.ti.com/.../f28003x_5F00_mini.zip

    以下是它可以按顺序执行的操作:

    1. 从已擦除的闪存开始
    2. 从 RAM 运行(CPU1_RAM 配置):一切正常、诊断完成、应用程序在 main () 末尾的阻塞循环结束
    3. 从闪存 (CPU1_FLASH) 运行它:PIE 处理程序诊断结束到 BootROM 等待点 0x3FEEC9 处
    4. 重新启动调试、再次运行 CPU1_FLASH:不再提供中断、函数 main () 卡在循环中、等待提供 TIMER2 中断;IER.INT14 = 1、IFR.INT14 = 0
    5. 下电上电:在不进行调试的情况下、我看到 LED 卡在打开位置,就像进入等待点时一样 — 我假设它又出现了
    6. 再次开始 CPU1_RAM 调试:未处理中断、导致的结果与第 4 点相同。

    我现在的唯一假设是、从闪存运行时、该应用可以通过使用调试器在 RAM 中重新启动应用程序来执行不可恢复的操作。

    -----

    有关诊断库的一两个问题。 在该函数中STL_PIE_RAM_testHandler()可以访问 PIEIFRn 寄存器以强制进行中断处理:是否应该在原子访问中将其围起来以防止任何竞态条件?
    在上面的函数中、中断屏蔽是否用于设置 PIEIERn 和 PIEIFRn、从而将任何其他 IER/IFR 位清零?

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

    我想我最终找到了我的问题的原因 我跳过的代码行 ,虽然我还没有一个完整的解释的现象。

    这组诊断从 HWBIST 开始、这除其他外、需要在 RAM 中复制库代码、在示例应用程序中、该代码与类似

    memcpy(&HwbistRunStart, &HwbistLoadStart, (size_t)&HwbistLoadSize);

    这是我代码中的缺失行。

    由于 HWBIST 测试仅与闪存版本一起使用,因此当电路板具有带有这个缺失行的闪存代码时,它从故障开始 — 作为 ITRAP。

    现在、当加载 RAM 版本的代码时、即使它没有 HWBIST 测试、MCU 也只能几乎正常工作。 有些功能正常、其他功能正常(例如中断处理)则不能正常工作。 这是我无法解释的部分: 调试器没有很好地复位所有内容 插入损耗。
    由于 HWBIST 调试相当困难、因此我没有在闪存版本上正确分析它。
    我的实验是、加上“Run > Disconnect target“和“Run">"Connect target"“ target"等“等字“字、将 MCU 恢复到功能状态。

    我将对实际代码进行新的测试,但我相信,混乱的根源是我愚蠢的错误。

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

    该 memcpy 用于 HWBIST 上下文恢复函数、因此在 HWBIST 运行后、CPU 处于未知状态、因此您运行存储在地址 0x0 处的上下文恢复函数再次设置它、因此可能存在未恢复的 CPU 状态的遗留问题。  

    通常、在调试时、它是 GEL 文件进行器件初始化(除非您正在执行强制通过引导 ROM 运行)。 GEL 文件可能缺少某些内容。

    Whitney