前言:
針對RISC-V晶片進入HardFault_Handler函式的問題排查提供講解。
一、通用工程PC指標監控
在公共檔案的sys.c工程中找到HardFault_Handler函式並修改如下:
__INTERRUPT
__HIGH_CODE
__attribute__((weak))
void HardFault_Handler(void)
{
uint32_t v_mepc,v_mcause,v_mtval;
printf("hardfault\n");
v_mepc=__get_MEPC();
v_mcause=__get_MCAUSE();
v_mtval=__get_MTVAL();
printf("mepc:%08x\n",v_mepc);
printf("mcause:%08x\n",v_mcause);
printf("mtval:%08x\n",v_mtval);
#if 0
FLASH_ROM_SW_RESET();
sys_safe_access_enable();
R16_INT32K_TUNE = 0xFFFF;
sys_safe_access_disable();
sys_safe_access_enable();
R8_RST_WDOG_CTRL |= RB_SOFTWARE_RESET;
sys_safe_access_disable();
#endif
while(1);
}
啟用定時器功能也可以進行PC指標監控,以下函式新增在初始化中即可。並且可以透過定時器中斷判斷晶片是否還在工作狀態。
TMR1_TimerInit(FREQ_SYS); // 設定定時時間 1000ms
TMR1_ITCfg(ENABLE, TMR0_3_IT_CYC_END); // 開啟中斷
PFIC_EnableIRQ(TMR1_IRQn);
__INTERRUPT
__HIGH_CODE
void TMR1_IRQHandler()
{
static int seconds = 0;
if(TMR1_GetITFlag(TMR0_3_IT_CYC_END))
{
PRINT("20 = %08x\n",*((uint32_t *)0xE000E020));
PRINT("24 = %08x\n",*((uint32_t *)0xE000E024));
PRINT("30 = %08x\n",*((uint32_t *)0xE000E300));
PRINT("34 = %08x\n",*((uint32_t *)0xE000E304));
// 清除中斷標誌
TMR1_ClearITFlag(TMR0_3_IT_CYC_END);
PRINT("PC_%08x\n",__get_MEPC());
PRINT("SE_%08x\n",__get_MCAUSE());
PRINT("VL_%08x\n",__get_MTVAL());
}
}
二、藍芽工程監控
__INTERRUPT
__HIGH_CODE
__attribute__((weak))
void HardFault_Handler(void)
{
struct __MEMORY_CTL
{
struct __MEMORY_CTL * pNext;
uint16_t len;
uint16_t used;
};
typedef struct __MEMORY_CTL MemoryCtl;
extern MemoryCtl * MemCtlStart;
extern MemoryCtl * MemCtlEnd;
MemoryCtl * MemHead;
MemHead = MemCtlStart;
while( MemHead != MemCtlEnd ){
printf("|%8x,%8x,%8d.....\n",MemHead->used,(uint32_t)MemHead,\
(uint32_t)(MemHead->pNext) -(uint32_t)MemHead - sizeof(struct __MEMORY_CTL));
MemHead = MemHead->pNext;
}printf("\n");
uint32_t v_mepc,v_mcause,v_mtval;
printf("hardfault\n");
v_mepc=__get_MEPC();
v_mcause=__get_MCAUSE();
v_mtval=__get_MTVAL();
printf("mepc:%08x\n",v_mepc);
printf("mcause:%08x\n",v_mcause);
printf("mtval:%08x\n",v_mtval);
#if 0
FLASH_ROM_SW_RESET();
sys_safe_access_enable();
R16_INT32K_TUNE = 0xFFFF;
sys_safe_access_disable();
sys_safe_access_enable();
R8_RST_WDOG_CTRL |= RB_SOFTWARE_RESET;
sys_safe_access_disable();
#endif
while(1);
}
注意:
監控函式和PC指標可以同時使用。監控函式需要在藍芽工程中使用才有意義,如果列印值為空,檢查是否使用藍芽。
附錄:
PC指標列印資訊排查可以參考青稞V4手冊:QingKeV4_Processor_Manual.PDF - 南京沁恆微電子股份有限公司 (wch.cn)