6 posts / 0 new
Last post
z0806020433
Offline
Last seen:8 months 1 week ago
加入:2016-05-05 13:32
异常HardFault_HandlerC的跟踪思路

你好,
系统老是挂死在hardFault_handler.c中void HardFault_HandlerC(unsigned long *hardfault_args)的如下地方:
void HardFault_HandlerC(unsigned long *hardfault_args)
{

if (DEVELOPMENT_DEBUG)
{
SetBits16(SYS_CTRL_REG, DEBUGGER_ENABLE, 1); // enable debugger to be able to re-attach
*(不稳定的无符号长*)(STATUS_BASE ) = hardfault_args[0]; // R0
*(不稳定的无符号长*)(STATUS_BASE + 0x04) = hardfault_args[1]; // R1
*(不稳定的无符号长*)(STATUS_BASE + 0x08) = hardfault_args[2]; // R2
*(不稳定的无符号长*)(STATUS_BASE + 0x0C) = hardfault_args[3]; // R3
*(不稳定的无符号长*)(STATUS_BASE + 0x10) = hardfault_args[4]; // R12
*(不稳定的无符号长*)(STATUS_BASE + 0x14) = hardfault_args[5]; // LR
*(不稳定的无符号长*)(STATUS_BASE + 0x18) = hardfault_args[6]; // PC
*(不稳定的无符号长*)(STATUS_BASE + 0x1C) = hardfault_args[7]; // PSR
*(不稳定的无符号长*)(STATUS_BASE + 0x20) = (unsigned long)hardfault_args; // Stack Pointer

*(不稳定的无符号长*)(STATUS_BASE + 0x24) = (*((volatile unsigned long *)(0xE000ED28))); // CFSR
*(不稳定的无符号长*)(STATUS_BASE + 0x28) = (*((volatile unsigned long *)(0xE000ED2C))); // HFSR
*(不稳定的无符号长*)(STATUS_BASE + 0x2C) = (*((volatile unsigned long *)(0xE000ED30))); // DFSR
*(不稳定的无符号长*)(STATUS_BASE + 0x30) = (*((volatile unsigned long *)(0xE000ED3C))); // AFSR
*(不稳定的无符号长*)(STATUS_BASE + 0x34) = (*((volatile unsigned long *)(0xE000ED34))); // MMAR
*(不稳定的无符号长*)(STATUS_BASE + 0x38) = (*((volatile unsigned long *)(0xE000ED38))); // BFAR
if (USE_WDOG)
wdg_freeze(); // Stop WDOG

if ((GetWord16(SYS_STAT_REG) & DBG_IS_UP) == DBG_IS_UP)
__asm("BKPT #0\n"); //挂死在此处
else
while(1);
}

}

这个一般是什么原因啊?硬件的有虚焊还是?软件上能定位这个问题吗,前面的那些寄存器有助于定位问题吗?
谢谢!

Keywords:
Device:
Gongyu_Dialog
Offline
Last seen:32分钟前2天
加入:2016-04-27 07:07
找到*(volatile unsigned long *)

找到*(volatile unsigned long *)(STATUS_BASE + 0x14) = hardfault_args[5]; // LR,在生成的的map文件里面找到相应的函数。看看是哪里异常了

z0806020433
Offline
Last seen:8 months 1 week ago
加入:2016-05-05 13:32
map文件在哪里?

map文件在哪里?
LR是什么啊?要观察STATUS_BASE + 0x14的值吗?还是说hardfault_args[5]记录的就是程序发生异常时,挂死的位置?

Gongyu_Dialog
Offline
Last seen:32分钟前2天
加入:2016-04-27 07:07
LR是栈上保存的返回地址。

LR是栈上保存的返回地址。

map文件一般在 工程目录\keil_5\out_580\lst下面

z0806020433
Offline
Last seen:8 months 1 week ago
加入:2016-05-05 13:32
你好,

你好,
LR是栈上保存的返回地址,PC指向当前执行的代码地址,是不是根据这两个地址在map文件中查找它属于哪个函数的地址范围。
如附件范例中,程序挂死在app_task.c中的gapc_connection_req_ind_handler函数了。
谢谢

Attachment:
Gongyu_Dialog
Offline
Last seen:32分钟前2天
加入:2016-04-27 07:07
看代码,应该是触发assert了,你检查一下当前的状态看看

看代码,应该是触发assert了,你检查一下当前的状态看看?
int gapc_connection_req_ind_handler(ke_msg_id_t const msgid,
struct gapc_connection_req_ind const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
// Connection Index
if (ke_state_get(dest_id) == APP_CONNECTABLE)
{
app_env.conidx = KE_IDX_GET(src_id);

app_connection_func(param);
}
else
{
// APP_CONNECTABLE state is used to wait the GAP_LE_CREATE_CONN_REQ_CMP_EVT message
ASSERT_ERR(0);
}

return (KE_MSG_CONSUMED);
}