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.

[参考译文] UCD3138:后台循环未响应、但时间中断正常

Guru**** 2541950 points
Other Parts Discussed in Thread: UCD3138

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

https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1050276/ucd3138-background-loop-is-not-responding-but-time-interrupt-is-fine

器件型号:UCD3138

各位专家、您好!

 -我遇到一个问题,PMBus 在运行应用程序几天后没有响应。 由于 PMBus_handler ()在后台循环中,因此我在后台循环中添加了 DEBUG_PIN 切换,并在 PMBus 没有响应时查找 DEBUG_PIN 停止切换。

 -同时、当 PMBus 没有响应(后台循环 DEBUG_PIN 停止切换)时、计时器中断中的函数仍在工作。

 -我还尝试在 while 循环中添加 debug_PIN 切换、但在出现问题时 DEBUG_PIN 不会切换。 (我想这意味着后台循环不会卡在 while 循环中。)

 -是否有任何可能导致此问题的原因,后台循环在运行几天后停止?

 这真的很奇怪。 任何建议都将非常有帮助。 提前感谢。

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

    您好、Jack、

    一个快速问题是:您是否测试了固件或 TI EVM 代码?

    谢谢、

    肖恩

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

    Jack、这种情况并不经常发生、但 PFC EVM 代码中对此进行了修复。

    我将首先给出修复方法、然后解释复杂的背景

    有3个处理不同异常的异常处理程序:

    -未定义_指令_异常

    - abort_prefet_exception

    - abort_data_fetch_exception

    最简单的操作是向每个模块添加软件复位、如下所示:

    void undefined_instruction_exception (void)

         SysRegs.SYSECR.bit.reset = 2;

    这将解决您的问题。  

    如果您想进一步提高噪声导致的复位的可靠性、甚至调试代码、您可以查看 PFC EVM 如何处理此问题。  我在下面的解释之后对其进行了说明。

    所发生的情况是、后台循环会丢失。  每次我们看到它、都是由于布局/噪声问题导致 UCD 丢失。   

    从理论上讲、它也可能是由程序中存在错误导致的、但我想我们从未见过这种情况。

    如果由噪声或错误引起的单个故障、ARM7通常会检测到非法存储器访问或非法指令故障。  发生这种情况时、它将转到故障处理程序、该处理程序将尝试将内容推入堆栈。  我们的大多数代码不会初始化这些堆栈指针、因此它们通常指向非法地址。  由于存在2个类似的故障、UCD 似乎会自动复位。  

    特定的 UCD 器件往往每次都会出现相同的堆栈指针、少数器件会具有合法地址。  这些将显示此问题。

    此外、要解决此问题、噪声及其各个部件对它的敏感度必须正确、以便噪声仅导致一个故障。  通常情况下、故障更多、同样、即时复位也是如此。   

    这是解释为什么您不经常看到这种情况的背景。   

    接下来、解释发生这种情况的原因:

    ARM7最初设计用于 PC。  非法存储器访问和指令中止背后的想法是、操作系统可以选择修复此问题、然后返回到发生中止的同一位置。  因此异常返回到找到异常中断的地址。  这意味着它们只会返回指令并获得另一个中止。  因此背景循环会卡住。   

    但是、当中止返回到后台循环时、可能会发生中断、以便它们保持运行。   

    修复它的方法是确保中止复位处理器。

    如果您还 为所有中止输入了有效的堆栈指针地址。

    这可确保间歇性故障也会使处理器复位。  当发生间歇性故障时、其他东西可能会损坏。  即使该特定故障消失、也最好复位处理器以避免损坏电源。   

    对于堆栈指针设置、您需要找到 load.asm。  在较旧的代码中、它位于主源目录中。  在支持多个处理器的较新代码中、每个 UCD 器件型号都有一个唯一的 load.asm。  例如、它将位于 Device/UCD3138/Source 中。

    您需要将 ABT_STACK_TOP 添加到文件顶部的.equ 语句:

    SUP_STACK_TOP .equ 0x19ffc;监控器模式(SWI 堆栈)从存储器顶部开始
    fiq_stack_top .equ 0x19e00;为监控器堆栈分配256个字节、然后执行 FIQ 堆栈
    IRQ_STACK_TOP .equ 0x19d00;为 FIQ 堆栈分配256个字节、然后启动 IRQ 堆栈
    abt_stack_top .equ 0x19b50;为 IRQ 堆栈分配432个字节
    UND_STACK_TOP .equ 0x19b50;为异常栈分配80个字节
    USER_STACK_TOP .equ 0x19b00;为堆栈分配80个字节、常规堆栈会停止、一直到变量

    然后、您需要添加初始 化2个中止堆栈。  可以将它们全部放在同一个地址、因为每次只使用一个地址:

    ;*--------------------------------------------------
    ;*设置为 IRQ 模式,初始化 IRQ 堆栈
    ;*--------------------------------------------------
    R0夫人、CPSR
    BIC r0、r0、#0x1F;清除模式
    ORR r0、r0、#0x12;设置 IRQ 模式
    MSR CPSR_CF、r0

    LDR R13,c_irq_stack_top;初始化堆栈指针

    ;*--------------------------------------------------
    ;*设置为中止模式,初始化中止堆栈
    ;*--------------------------------------------------
    R0夫人、CPSR
    BIC r0、r0、#0x1F;清除模式
    ORR r0、r0、#0x17;设置中止模式
    MSR CPSR_CF、r0

    LDR R13、c_abt_stack_top;初始化堆栈指针
    ;*--------------------------------------------------
    ;*设置为未定义模式,初始化未定义的栈
    ;*--------------------------------------------------
    R0夫人、CPSR
    BIC r0、r0、#0x1F;清除模式
    ORR r0、r0、#0x1B;设置未定义模式
    MSR CPSR_CF、r0

    LDR R13,c_und_stack_top;初始化堆栈指针

    ;*--------------------------------------------------
    ;*设置为用户模式,初始化用户堆栈

    您还需要添加命令、将地址放入闪存中、以便处理器读取:

    c_sup_stack_top .long SUP_stack_top
    c_abt_stack_top .long ABT_stack_top
    c_und_stack_top .long und_stack_top
    c_user_stack_top .long user_stack_top

    如果这样设置堆栈指针、则应该为所有芯片获得更可靠的复位、而不仅仅是那些拥有合法地址中的堆栈指针的少数芯片。   

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

    感谢您的解释。 您的答案非常有用。 我将添加堆栈指针并在异常处理程序中放置一个 debug_PIN 以进行检查。 非常感谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="5121" URL"~/support/power-management-group/power-management/f/power-management-forum/1050276/ucd3138-background-loop-is-not-responding-but-time-interrupt-is-fine/3886709 #3886709"]

    -未定义_指令_异常

    - abort_prefet_exception

    - abort_data_fetch_exception

    [/报价]

    尊敬的 Ian:

     -我想在异常处理程序中添加一个 debug_PIN 切换、并测试我遇到了什么异常。 但是、首先、我需要确保添加的异常处理程序代码是正确的。

     1) 1)我尝试为异常堆栈和处理程序添加代码。 但是、我第一次遇到 ROM 模式问题(UCD 未复位)。 然后、我发现 UCD 有一个异常触发器需要复位。  

        func_ptr =(FUNC_ptr) 0x10000
        func_ptr ();

     2) 2)所以我注释这2行、并替换为软件复位。

        // func_ptr =(FUNC_ptr) 0x10000
         //  func_ptr ();
        SysRegs.SYSECR.bit.reset = 0;
     
     3) 3)但是、UCD 在 ROM 模式后仍然不会复位。 然后、我将 zoiw_size 修改为0x100。 它的工作原理。 ROM 模式现在正常。
        // for (counter=0;counter < zoiw_size;counter++) //将程序从 pflash 复制到 RAM
        for (counter=0;counter<0x100 ;counter++//将程序从 pflash 复制到 RAM
        {
         *(program_index++)=*(source_index++);
        }
     4) 4)然后我删除了软件复位、并重新添加了异常触发器。 ROM 模式正常。
        // SysRegs.SYSECR.bit.reset = 0;
        func_ptr =(FUNC_ptr) 0x10000
         func_ptr ();
     5) 5)现在、我在所有3个异常处理程序中添加了一个 DEBUG_PIN 切换、用于检查异常处理程序是否正常工作。 但是、当我应用 ROM 模式命令时、DEBUG_PIN 不会切换。
        DEBUG_PIN =DEBUG_PIN;
        SysRegs.SYSECR.bit.reset = 0//软件复位
     -您是否知道为什么 DEBUG_PIN 不切换? 在异常触发 ROM 模式命令后 UCD 是否真正复位?
     -或者、您是否建议任何方法来验证异常处理程序? 以便我可以看到我确实正确执行了异常代码。
    非常感谢。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我希望该引脚根据您所说的内容切换。   

    我认为有两 到三件事可能会阻止您看到它:

    1.调试引脚切换后的重置可能会导致调试引脚立即接地或高阻抗、切换后可能会400ns、因此您可能会错过它。 或者、您可能无论如何将其拉至接地、在这种情况下、您将看不到它。  我建议在复位前多次切换。

    2、 可能零输出完整性字中也会发生复位、因此您可能需要查看该复位

    3. 在切换之前,可能还有其他的东西会将其复位。

    您始终可以尝试将计数器中的0x100改回500、这将导致复位。   

    复位后、您还可以在 ROM 模式下从 SYSESR 寄存器读取。  如果存在异常、则应设置其中一个异常位。   

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

    尊敬的 Ian:

     感谢您的建议。

     -我将 zoiw_size 更改为500,并实际触发了非法的内存访问(下面的屏幕截图)。 但是、在这种情况下会触发哪个异常? 因为我仍然看不到 DEBUG_PIN 切换。

     如何触发3个异常? 这样、我就可以确保下次遇到异常时 DEBUG_PIN 将正常工作。

    电源 下面 对3个异常处理程序进行了编码 。 你可以吗?

    #pragma INTERRUPT (ABORT_DATA_Fetch 例外、 DABT)
    void abort_data_fetch_exception (void)
      int i、j;

      对于(j = 0;j <= 5;j++)
      {
       DEBUG_PIN =DEBUG_PIN;
       对于(i = 0;i < 10000;i++){
        asm (" nop ");
       }
      }

      SysRegs.SYSECR.bit.reset = 2; // SOfrw
    **更新2021/11/17**
     我很抱歉。 我认为是"nop" for 循环导致 ROM 模式失败和缺少 DEBUG_PIN 切换。
     -删除 for 循环后,只保留 DEBUG_PIN 切换。 现在工作正常。 我可以很清楚地看到 DEBUG_PIN 切换、一切都正常。
     -下面的屏幕截图。
    异常处理程序:
    #pragma  INTERRUPT (ABORT_DATA_Fetch 例外、 DABT)
    void  abort_data_fetch_exception (void)
       DEBUG_PIN  = DEBUG_PIN;
       DEBUG_PIN  = DEBUG_PIN;
       DEBUG_PIN  = DEBUG_PIN;
       DEBUG_PIN  = DEBUG_PIN;
       DEBUG_PIN  = DEBUG_PIN;
       DEBUG_PIN  = DEBUG_PIN;

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

    很好。  我将关闭此线程、您可以测试是否仍然在后台循环崩溃且计时器中断仍在运行的情况下看到您的情况。  如果发生这种情况、请启动另一个线程。  我不希望这种情况发生。