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.

[参考译文] TM4C1237H6PZ:DBG 硬故障

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1373950/tm4c1237h6pz-dbg-hard-fault

器件型号:TM4C1237H6PZ

工具与软件:

您好!

我正在处理一个硬故障、目前使我无法验证应用程序。

每次复位时、FAULT_STAT 寄存器均为零。

相反、硬故障 STAT 寄存器始终为零、但当触发 ISR 硬故障时、DBG 位为1 (仅此而已)。

在数据表中、该位保留用于调试、但应用程序未处于调试状态。
我找不到有关此类硬故障的其他信息。

因此、我想问、你能否详细说明这一点的意义和可能的原因
设置为1。

期待您的友好回答、

此致。

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

    您好!

     我不知道为什么只设置了 DBG、而没有其他设置。 通常、我希望设置额外的位。 . 如果您单步执行、您是否知道在代码行导致了故障发生。 通常、硬故障是由1)栈不够以及2)访问尚未启用的外设所导致的。 因此、请确保仅在启用外设后访问(例如读取或写入)外设寄存器并保留足够的堆栈、从而使处理器不会超出堆栈存储器的绑定范围。 尝试增加您的堆栈、看看这是否有什么不同。 请参阅此应用手册、以诊断故障异常。  https://www.ti.com/lit/pdf/spma043

     以下是可能导致硬故障的其他情况。  

    死锁
    当处理器执行 NMI 或硬故障时、如果一个硬件故障发生、那么处理器进入死锁状态
    处理程序。 当处理器处于死锁状态时、它不执行任何指令。 。
    处理器将保持在死锁状态、直到它被复位、NMI 发生或被调试器停止。

    警告–如果 Cortex-M4F 调试访问端口(DAP)已经被启用、并且器件将从中唤醒
    低功耗睡眠或深度睡眠模式、内核可能会在所有外设时钟之前开始执行代码
    已经恢复到运行模式配置。 DAP 通常通过软件工具启用
    调试或闪存编程时访问 JTAG 或 SWD 接口。 如果出现这种情况、
    当软件访问一个带有无效时钟的外设时、会触发一次硬件故障。

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

    您好!  

    我已尝试减少堆栈以触发硬故障、在这种情况下、我设置了 BFARV、BSTKE、FAULT_STAT 的精确位、还强制设置了 HARD_FAULT_STAT 位、DBG 位为零、

    我很确定我不使用统一外设、因为这种硬错误随机发生、不在应用代码的特定部分中。

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

    您好!

    、因为此硬故障是随机发生的、不是在应用程序代码的特定部分。

    好的、您可以排除未启动的外设作为原因。 存储器便是要查看的区域。 此外、请尝试增加堆栈和堆、尤其是当使用某种类型的动态内存分配时、如果分配不当、可能会导致错误我知道您已尝试减小堆栈大小、以缩短收到硬故障的时间。 尝试增加堆栈和堆、看看它们是否会延迟故障的发生。 这样、您就可以知道故障是否与存储器有关。  

    您还可以参阅 Arm TRM 关于 DEBUGEVT 位。  

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

    您好!  

    好的、我将尝试扩展堆和堆栈。

    如何更改堆维度? 我使用的是 CCS

    谢谢。

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

    请参阅下面的示例、其中我为堆设置1024、为堆栈设置2048。 我不知道您的现有设置是什么。 尝试增加它们、看看它们是否有所不同、然后微调尺寸。  

    在.cmd 文件中、您需要考虑新的栈大小、以便栈指针指向正确的地址。  

    /* The starting address of the application. Normally the interrupt vectors */
    /* must be located at the beginning of the application. */
    #define APP_BASE 0x00000000
    #define RAM_BASE 0x20000000

    /* System memory map */

    MEMORY
    {
    /* Application stored in and executes from internal flash */
    FLASH (RX) : origin = APP_BASE, length = 0x00040000
    /* Application uses internal RAM for data */
    SRAM (RWX) : origin = 0x20000000, length = 0x00008000
    }

    /* Section allocation in memory */

    SECTIONS
    {
    .intvecs: > APP_BASE
    .text : > FLASH
    .const : > FLASH
    .cinit : > FLASH
    .pinit : > FLASH
    .init_array : > FLASH

    .vtable : > RAM_BASE
    .data : > SRAM
    .bss : > SRAM
    .sysmem : > SRAM
    .stack : > SRAM
    }

    __STACK_TOP = __stack + 2048;

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

    您好!

    我使用具有 GNU 连接器选项的 GCC 编译器、

    如果我在 GNU 链接器符号中定义 HEAPSIZE=2048符号、它是否相同?  

    我的文件.lds 遇到以下代码。

    .heap :{
    __heap_start__=.;
    keep (*(.heap))
    __heap_end__=.;
    __HeapLimit =__heap_end__;
    end =__heap_end__;
    _end =结束;
    __end = end;
    }> REGION_HEAP

    此外、我还拥有3K 的堆栈大小、并将在4K 处增加

    您能告诉我更多关于 DFSR 寄存器的信息吗? 因为我找不到任何基准

    数据表中的相应部分进行比较。  

    谢谢。

    此致、

    Alberto

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

    您好!

     抱歉、我对 GCC 的了解有限。 我找到这些网页、希望 它们对您有所帮助。 你也可以在 google 上搜索如何为 gcc 分配堆大小。  

    https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gnat_ugn/Setting-Heap-Size-from-gnatlink.html

    https://software-dl.ti.com/codegen/docs/tiarmclang/compiler_tools_user_guide/compiler_manual/linker_description/04_linker_options/basic-options.html#stdz0752477

    [报价 userid="610057" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1373950/tm4c1237h6pz-dbg-hard-fault/5252312 #5252312"]

    您能告诉我更多关于 DFSR 寄存器的信息吗? 因为我找不到任何基准

    [报价]

    您在哪里找到 DFSR? 我想确保我们谈论的是同一件事。 对于 Cortex-M4F 处理器、实际上并没有 DFSR (数据故障状态寄存器)。 如数据表中所述、您可以看到它只是 FAULTSTAT 寄存器、可以进一步归类为 MFAULTSTAT、BFAULTSTAT 或 UFAULTSTAT。 数据表中没有 DFSR 的说明。 我已经看到不同 Arm 处理器(例如 Cortex-R4/R5)的 DFSR 和 IFSR (指令故障状态寄存器)、但它在这里无关紧要。 如果您想了解我认为与此处无关的 DFSR、我会在下面提供说明以供参考。 或者、您也可以转到 Arm 网站并搜索它。  

     在我之前的回复中、我曾向您介绍过 诊断故障异常的应用手册。  https://www.ti.com/lit/pdf/spma043。您有机会了解一下吗?  

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

    你(们)好

    根据您发送给我的以下文档:

    我看到了  

    0xE000ED30 DFSR RW 0x00000000 调试故障状态寄存器

    在微控制器的头文件中、我有:

    #define NVIC_DEBUG_STAT_R    (*(volatile uint32_t *) 0xE000ED30)

    但我在数据表中找不到它。

    此致

    Alberto

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

    好的。 您指的是"调试"故障状态寄存器、而不是"数据"故障状态寄存器。 我们的数据表中未提及该寄存器。 但是、看看 Arm Cortex-M3 TRM、确实有这个寄存器。 您可以在 Arm 网站 https://developer.arm.com/documentation/ddi0419/c/Debug-Architecture/ARMv6-M-Debug/Debug-register-support-in-the-SCS/Debug-Fault-Status-Register--DFSR 上找到详细信息。

    您创建的哪种类型的应用程序怀疑故障与调试有关? 正常情况下、故障会在运行时发生。 我没有看到调试故障、除非您创建一个独特的应用、使用我没有经验的监控器调试。  

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

    我正在开发用于 燃气锅炉管理的 C 类固件,我不怀疑该故障与调试有关。

    我很想明白为什么我有这种不动机的硬故障。  

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

    嗨、在检查调试故障状态寄存器后、我发现当 DBG 位设置为1时、硬故障也设置了 BKPT 位。 我仍然无法弄清楚在调试模式下运行时有 BKPT 指令是如何实现的。

    您在此有任何信息/提示吗?

    谢谢。

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

    您好!

     如果您设置了 BKPT 位、我认为您代码中的某个位置具有将断点置为处理器的指令。 您可能需要搜索这行代码。 下面只是一个示例、在 C 代码中、它具有用于断点处理器的内联汇编指令。 如果您编写了整个代码、那么您就会知道将 bkpt 指令插入到了哪里。 但是、如果您与其他人合作开发固件、那么您可以在项目中搜索 bkpt 指令。 如果在您的工程中没有发生此类情况、那么我真的不知道是什么导致设置 BKPT 位。 您可以编写一个简单的代码来使用 BKPT 指令进行实验、以了解其使用情况。   

    if (g_ui32Tick1ms <= EXPECTED_CPU_FREQUENCY_MAX && g_ui32Tick1ms >= EXPECTED_CPU_FREQUENCY_MIN) {
    MAP_GPIOPinWrite(GPIO_PORTF_BASE, RED_LED, 0);
    MAP_GPIOPinWrite(GPIO_PORTF_BASE, GREEN_LED, GREEN_LED);

    } else {

    MAP_GPIOPinWrite(GPIO_PORTF_BASE, GREEN_LED, 0);
    MAP_GPIOPinWrite(GPIO_PORTF_BASE, RED_LED, RED_LED);
    asm(" bkpt #1");
    }

    Refer to Arm website about BKPT instruction. 

    https://developer.arm.com/documentation/dui0473/m/arm-and-thumb-instructions/bkpt

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

    您好!

    我已经在我所有的源代码中搜索,没有参考 bkpt 指令,而是看反汇编文件:

    _exit():
    00034564:F04F31FF mov.w R1、#-1
    00034568:F000B800 b.w _kill
    _kill():
    0003456c:b530 push{r4、r5、r14}
    0003456e:B083 SUB R13、#0xc
    00034570:460D MOV R5、R1
    00034572:9101 str R1、[R13、#4]
    00034574:F7FFFFCC BL _has_ext_exit_extended
    00034578:2800 CMP r0、#0
    0003457a:BF14铁粉
    0003457c:2420 movne R4、#0x20
    0003457e:2418 moveq R4、#0x18
    00034580:2D06 CMP R5、#6
    00034582:BF0C 点均衡
    00034584:4B05 ldreq R3、[PC、#0x14]
    00034586:4B06 ldrne R3、[PC、#0x18]
    00034588:9300 str R3、[R13]
    0003458a:466D MOV R5、R13
    0003458c:4620 mv r0、r4
    0003458e:4629 MOV R1、R5
    00034590:BEAB bkpt #0xab
    00034592:4604 mov R4、r0
    00034594:4620 mov r0、r4
    00034596:B003、添加 R13、#0xc
    00034598:BD30 POP{R4、R5、PC}
    0003459a:BF00 nop
    0003459c:0023 MOVs R3、R4
    0003459e:0002 MOVS R2、r0
    000345a0:0026 MOVS R6、R4
    000345a2:0002 MOVS R2、r0

    我找到这些,但我无法理解这是在哪里生成的,它似乎通过这些指令之前硬故障。

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

    如果你看看反汇编,它似乎是来自_exit()。 您正在使用 GCC 编译器、我认为这是 GCC RTS 库的一部分。 至于_exit()如何以及为什么在你的项目中登陆,我不知道,你需要调查。 但我可以分享一条线索。 尝试这个非常简单的程序,你很可能会在_exit()中结束,这是在 main ()退出后的正常程序终止行为。 通常、对于微控制器固件、除非您打算退出 main ()函数、否则不应退出该函数。 看看这是否是您问题的原因。

    内部
    main (void)

    返回0;

    }

    当我使用 TI Arm 编译器在 CCS 上运行该程序时、它将以中止函数结尾、该函数除了循环旋转之外不执行任何操作。 GCC 可能已经添加了其他东西、例如使 BKPT 生效、以便调试器可以诊断。  

    #include <stdlib.h>
    #include <_lock.h>
    #include <pprof.h>
    
    #ifdef __TI_RTS_BUILD
    /*---------------------------------------------------------------------------*/
    /* __TI_default_exit indicates that the default TI exit routine is being     */
    /* used.  The linker makes assumptions about what exit does when this symbol */
    /* is seen. This symbols should NOT be defined if a customized exit routine  */
    /* is used.                                                                  */
    /*---------------------------------------------------------------------------*/
    __asm("__TI_default_exit .set 1");
    #endif
    
    void                     (*__TI_cleanup_ptr)(void) = NULL;
    void   _DATA_ACCESS      (*__TI_dtors_ptr)(int)    = NULL;
    
    typedef void (*PTRFUNC)();
    int __TI_enable_exit_profile_output = 1;
    
    extern void abort(void);
    
    /****************************************************************************/
    /* EXIT() - NORMAL PROGRAM TERMINATION.                                     */
    /****************************************************************************/
    extern void exit(int status)
    {
       /*----------------------------------------------------------------------*/
       /* Output profile info if we have a valid path profile output handler   */
       /*----------------------------------------------------------------------*/
       if (__TI_enable_exit_profile_output &&
           _symval(&__TI_pprof_out_hndl) != (unsigned)-1)
       {
           PTRFUNC ppfunc = (PTRFUNC)(_symval(&__TI_pprof_out_hndl));
           (ppfunc)();
       }
    
       /*-------------------------------------------------------------------*/
       /* MUST LOCK WHEN ACCESSING GLOBALS, like __TI_dtors_ptr,            */
       /* __TI_cleanup_ptr                                                  */
       /*-------------------------------------------------------------------*/
       _lock();
    
       /*-------------------------------------------------------------------*/
       /* BOTH ATEXIT FUNCTIONS AND STATIC OBJECT DESTRUCTORS ARE           */
       /* REGISTERED IN A LINK LIST TO BE PROCESSED BY THE FUNCTION POINTED */
       /* TO BY __TI_dtors_ptr.  PROCESS THEM NOW.                          */
       /*-------------------------------------------------------------------*/
       if (__TI_dtors_ptr)  (*__TI_dtors_ptr)(status);
    
       /*-------------------------------------------------------------------*/
       /* IF FILES ARE POSSIBLY OPEN, __TI_cleanup_ptr() WILL BE SETUP TO   */
       /* CLOSE THEM.                                                       */
       /*-------------------------------------------------------------------*/
       if (__TI_cleanup_ptr)  (*__TI_cleanup_ptr)();
    
       _unlock();
       abort();
    }
    
    
    
    
    /****************************************************************************/
    /* ABORT - ABNORMAL PROGRAM TERMINATION.  CURRENTLY JUST HALTS EXECUTION.   */
    /****************************************************************************/
    __attribute__((section(".text:abort")))
    void abort(void)
    {
    #if defined(EMBED_CIO_BP)
       __asm("         .global C$$EXITE");
    #if defined(__32bis__)
       __asm("C$$EXITE:.word 0xDEFED0FE");
    #else
       __asm("	 .align  4");
    #if defined(__big_endian__)
       __asm("C$$EXITE:.half 0xDEFE");
    #else
       __asm("C$$EXITE:.half 0xD0FE");
    #endif /* __big_endian__ */
    #endif /* __32bis__      */
    
    #else  /* !EMBED_CIO_BP */
       __asm("        .global C$$EXIT");
       __asm("C$$EXIT: nop");
    #endif
    
        for (;;);   /* SPINS FOREVER */
    }

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

    您好!

     我没有听到你的声音。 我希望您的问题得到解决。 我现在将结束该主题。 如果您有任何更新、您可以回写此帖子、并且状态将更改为再次打开。