工具与软件:
您好!
我正在处理一个硬故障、目前使我无法验证应用程序。
每次复位时、FAULT_STAT 寄存器均为零。
相反、硬故障 STAT 寄存器始终为零、但当触发 ISR 硬故障时、DBG 位为1 (仅此而已)。
在数据表中、该位保留用于调试、但应用程序未处于调试状态。
我找不到有关此类硬故障的其他信息。
因此、我想问、你能否详细说明这一点的意义和可能的原因
设置为1。
期待您的友好回答、
此致。
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.
工具与软件:
您好!
我正在处理一个硬故障、目前使我无法验证应用程序。
每次复位时、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 接口。 如果出现这种情况、
当软件访问一个带有无效时钟的外设时、会触发一次硬件故障。
您好!
、因为此硬故障是随机发生的、不是在应用程序代码的特定部分。
好的、您可以排除未启动的外设作为原因。 存储器便是要查看的区域。 此外、请尝试增加堆栈和堆、尤其是当使用某种类型的动态内存分配时、如果分配不当、可能会导致错误我知道您已尝试减小堆栈大小、以缩短收到硬故障的时间。 尝试增加堆栈和堆、看看它们是否会延迟故障的发生。 这样、您就可以知道故障是否与存储器有关。
您还可以参阅 Arm TRM 关于 DEBUGEVT 位。
请参阅下面的示例、其中我为堆设置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
[报价 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。您有机会了解一下吗?
好的。 您指的是"调试"故障状态寄存器、而不是"数据"故障状态寄存器。 我们的数据表中未提及该寄存器。 但是、看看 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 上找到详细信息。
您创建的哪种类型的应用程序怀疑故障与调试有关? 正常情况下、故障会在运行时发生。 我没有看到调试故障、除非您创建一个独特的应用、使用我没有经验的监控器调试。
您好!
如果您设置了 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 */ }