CH58x芯片Hardfault问题排查

前言:

针对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)

 

posted @ 2024-04-26 13:57  SweetTea_lllpc  阅读(31)  评论(0编辑  收藏  举报