zephyr死机原因追踪

2023-10-18 10:20
文章标签 原因 追踪 死机 zephyr

本文主要是介绍zephyr死机原因追踪,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

找到这个文件下面的lst文件

根据pc指针找到当前运行的地方,在zephyr.lst文件中可以定位到pc地址

MMFA:MemManage Fault Address Register

BFAR: bus fault  address register

HFSR; hardfault status register

CFSR:configurable fault status register

ICSR:interrupt control and state register

下面以zephyr为例举例说明:

测试代码:


bool is_key_down = false;//该变量在按键中断里面触发,当按键按下,该位被置位为trueint main(void)
{for(;;){if(is_key_down){uint8_t *hardfault_data = NULL;*hardfault_data = 7;//对空指针进行赋值会导致死机}}
}

死机分析:

debug过程中代码会停在fault.S的汇编代码这个地方:

SECTION_SUBSEC_FUNC(TEXT,__fault,z_arm_exc_spurious)mrs r0, MSPmrs r1, PSPpush {r0, lr}
#if defined(CONFIG_EXTRA_EXCEPTION_INFO)/* Build _callee_saved_t. To match the struct* definition we push the psp & then r11-r4*/push { r1, r2 }
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)mov  r3, r11mov  r2, r10push {r2, r3}mov  r3, r9mov  r2, r8push {r2, r3}push {r4-r7}
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)push {r4-r11}
#endifmov  r3, sp /* pointer to _callee_saved_t */
#endif /* CONFIG_EXTRA_EXCEPTION_INFO */mov r2, lr /* EXC_RETURN */bl z_arm_fault      //这个函数是c语言写的,主要功能是打印16个内核寄存器信息,以及复位
#if defined(CONFIG_EXTRA_EXCEPTION_INFO)/* We do not need to restore any register state here* because we did not use any callee-saved registers* in this routine. Therefore, we can just reset* the MSP to its value prior to entering the function*/add sp, #40
#endifpop {r0, pc}.end

z_arm_fault()函数在fault.c中

void z_arm_fault(uint32_t msp, uint32_t psp, uint32_t exc_return,_callee_saved_t *callee_regs)
{uint32_t reason = K_ERR_CPU_EXCEPTION;int fault = SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk;bool recoverable, nested_exc;z_arch_esf_t *esf;/* Create a stack-ed copy of the ESF to be used during* the fault handling process.*/z_arch_esf_t esf_copy;/* Force unlock interrupts */arch_irq_unlock(0);/* Retrieve the Exception Stack Frame (ESF) to be supplied* as argument to the remainder of the fault handling process.*/esf = get_esf(msp, psp, exc_return, &nested_exc);__ASSERT(esf != NULL,"ESF could not be retrieved successfully. Shall never occur.");esf_cp_for_info(esf, fault);#ifdef CONFIG_DEBUG_COREDUMPz_arm_coredump_fault_sp = POINTER_TO_UINT(esf);
#endifreason = fault_handle(esf, fault, &recoverable);if (recoverable) {return;}/* Copy ESF */
#if !defined(CONFIG_EXTRA_EXCEPTION_INFO)memcpy(&esf_copy, esf, sizeof(z_arch_esf_t));ARG_UNUSED(callee_regs);
#else/* the extra exception info is not present in the original esf* so we only copy the fields before those.*/memcpy(&esf_copy, esf, offsetof(z_arch_esf_t, extra_info));esf_copy.extra_info = (struct __extra_esf_info) {.callee = callee_regs,.exc_return = exc_return,.msp = msp};
#endif /* CONFIG_EXTRA_EXCEPTION_INFO *//* Overwrite stacked IPSR to mark a nested exception,* or a return to Thread mode. Note that this may be* required, if the retrieved ESF contents are invalid* due to, for instance, a stacking error.*///LOG_INF("-->nested_exc:0x%x\r\n\r\n",nested_exc);if (nested_exc) {if ((esf_copy.basic.xpsr & IPSR_ISR_Msk) == 0) {esf_copy.basic.xpsr |= IPSR_ISR_Msk;}} else {esf_copy.basic.xpsr &= ~(IPSR_ISR_Msk);}//while(1);当你想在debug模式下看层级调用关系,而不是要代码自动复位,把while(1)加上就行了z_arm_fatal_error(reason, &esf_copy);
}

z_arm_fatal_error(reason, &esf_copy);这个函数就是就是读取内核的16个寄存器信息

void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf)
{if (esf != NULL) {esf_dump(esf);}z_fatal_error(reason, esf);
}static void esf_dump(const z_arch_esf_t *esf)
{LOG_ERR("r0/a1:  0x%08x  r1/a2:  0x%08x  r2/a3:  0x%08x",esf->basic.a1, esf->basic.a2, esf->basic.a3);LOG_ERR("r3/a4:  0x%08x r12/ip:  0x%08x r14/lr:  0x%08x",esf->basic.a4, esf->basic.ip, esf->basic.lr);LOG_ERR(" xpsr:  0x%08x", esf->basic.xpsr);
#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)for (int i = 0; i < 16; i += 4) {LOG_ERR("s[%2d]:  0x%08x  s[%2d]:  0x%08x""  s[%2d]:  0x%08x  s[%2d]:  0x%08x",i, (uint32_t)esf->s[i],i + 1, (uint32_t)esf->s[i + 1],i + 2, (uint32_t)esf->s[i + 2],i + 3, (uint32_t)esf->s[i + 3]);}LOG_ERR("fpscr:  0x%08x", esf->fpscr);
#endif
#if defined(CONFIG_EXTRA_EXCEPTION_INFO)const struct _callee_saved *callee = esf->extra_info.callee;if (callee != NULL) {LOG_ERR("r4/v1:  0x%08x  r5/v2:  0x%08x  r6/v3:  0x%08x",callee->v1, callee->v2, callee->v3);LOG_ERR("r7/v4:  0x%08x  r8/v5:  0x%08x  r9/v6:  0x%08x",callee->v4, callee->v5, callee->v6);LOG_ERR("r10/v7: 0x%08x  r11/v8: 0x%08x    psp:  0x%08x",callee->v7, callee->v8, callee->psp);}
#endif /* CONFIG_EXTRA_EXCEPTION_INFO */LOG_ERR("Faulting instruction address (r15/pc): 0x%08x",esf->basic.pc);
}

参考手册:STM32 Cortex®-M33 MCUs programming manual

这篇关于zephyr死机原因追踪的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/231940

相关文章

MySQL追踪数据库表更新操作来源的全面指南

《MySQL追踪数据库表更新操作来源的全面指南》本文将以一个具体问题为例,如何监测哪个IP来源对数据库表statistics_test进行了UPDATE操作,文内探讨了多种方法,并提供了详细的代码... 目录引言1. 为什么需要监控数据库更新操作2. 方法1:启用数据库审计日志(1)mysql/mariad

SpringSecurity显示用户账号已被锁定的原因及解决方案

《SpringSecurity显示用户账号已被锁定的原因及解决方案》SpringSecurity中用户账号被锁定问题源于UserDetails接口方法返回值错误,解决方案是修正isAccountNon... 目录SpringSecurity显示用户账号已被锁定的解决方案1.问题出现前的工作2.问题出现原因各

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

IDEA中Maven Dependencies出现红色波浪线的原因及解决方法

《IDEA中MavenDependencies出现红色波浪线的原因及解决方法》在使用IntelliJIDEA开发Java项目时,尤其是基于Maven的项目,您可能会遇到MavenDependenci... 目录一、问题概述二、解决步骤2.1 检查 Maven 配置2.2 更新 Maven 项目2.3 清理本

Java空指针异常NullPointerException的原因与解决方案

《Java空指针异常NullPointerException的原因与解决方案》在Java开发中,NullPointerException(空指针异常)是最常见的运行时异常之一,通常发生在程序尝试访问或... 目录一、空指针异常产生的原因1. 变量未初始化2. 对象引用被显式置为null3. 方法返回null

IDEA下"File is read-only"可能原因分析及"找不到或无法加载主类"的问题

《IDEA下Fileisread-only可能原因分析及找不到或无法加载主类的问题》:本文主要介绍IDEA下Fileisread-only可能原因分析及找不到或无法加载主类的问题,具有很好的参... 目录1.File is read-only”可能原因2.“找不到或无法加载主类”问题的解决总结1.File

使用@Cacheable注解Redis时Redis宕机或其他原因连不上继续调用原方法的解决方案

《使用@Cacheable注解Redis时Redis宕机或其他原因连不上继续调用原方法的解决方案》在SpringBoot应用中,我们经常使用​​@Cacheable​​注解来缓存数据,以提高应用的性能... 目录@Cacheable注解Redis时,Redis宕机或其他原因连不上,继续调用原方法的解决方案1

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

电脑死机无反应怎么强制重启? 一文读懂方法及注意事项

《电脑死机无反应怎么强制重启?一文读懂方法及注意事项》在日常使用电脑的过程中,我们难免会遇到电脑无法正常启动的情况,本文将详细介绍几种常见的电脑强制开机方法,并探讨在强制开机后应注意的事项,以及如何... 在日常生活和工作中,我们经常会遇到电脑突然无反应的情况,这时候强制重启就成了解决问题的“救命稻草”。那