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

相关文章

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

DAY16:什么是慢查询,导致的原因,优化方法 | undo log、redo log、binlog的用处 | MySQL有哪些锁

目录 什么是慢查询,导致的原因,优化方法 undo log、redo log、binlog的用处  MySQL有哪些锁   什么是慢查询,导致的原因,优化方法 数据库查询的执行时间超过指定的超时时间时,就被称为慢查询。 导致的原因: 查询语句比较复杂:查询涉及多个表,包含复杂的连接和子查询,可能导致执行时间较长。查询数据量大:当查询的数据量庞大时,即使查询本身并不复杂,也可能导致

flume系列之:记录一次flume agent进程被异常oom kill -9的原因定位

flume系列之:记录一次flume agent进程被异常oom kill -9的原因定位 一、背景二、定位问题三、解决方法 一、背景 flume系列之:定位flume没有关闭某个时间点生成的tmp文件的原因,并制定解决方案在博主上面这篇文章的基础上,在机器内存、cpu资源、flume agent资源都足够的情况下,flume agent又出现了tmp文件无法关闭的情况 二、

71-java 导致线程上下文切换的原因

Java中导致线程上下文切换的原因通常包括: 线程时间片用完:当前线程的时间片用完,操作系统将其暂停,并切换到另一个线程。 线程被优先级更高的线程抢占:操作系统根据线程优先级决定运行哪个线程。 线程进入等待状态:如线程执行了sleep(),wait(),join()等操作,使线程进入等待状态或阻塞状态,释放CPU。 线程占用CPU时间过长:如果线程执行了大量的I/O操作,而不是CPU计算

笔记本电脑开机报错故障的原因及解决办法

笔记本电脑开机报错故障是指笔记本电脑开机自检时或启动操作系统前停止启动,在显示屏 出现一些错误提示的故障。   笔记本电脑开机报错故障的原因及解决办法   造成此类故障的原因一般是笔记本电脑在启动自检时,检测到硬件设备不能正常工作或在自 检通过后从硬盘启动时,出现硬盘的分区表损坏、硬盘主引导记录损坏、硬盘分区结束标志丢失 等故障,笔记本电脑出现相应的故障提示。   维修此类故障时

图片地址携带blob:的原因

图片地址携带blob:的原因与Blob对象(Binary Large Object)的使用有关。Blob对象代表了一个不可变的、原始数据的类文件对象,通常用于处理二进制数据,如图片、视频或音频文件等。在计算机中,Blob常用于数据库中存储二进制文件,但在Web开发中,Blob对象也被广泛用于前端处理二进制数据。 具体来说,当图片地址携带blob:时,这通常意味着图片数据是以Blob对象的形式存储

服务器数据恢复—Raid磁盘阵列故障类型和常见故障原因

出于尽可能避免数据灾难的设计初衷,RAID解决了3个问题:容量问题、IO性能问题、存储安全(冗余)问题。从数据恢复的角度讨论RAID的存储安全问题。 常见的起到存储安全作用的RAID方案有RAID1、RAID5及其变形。基本设计思路是相似的:当部分数据异常时,可通过特定算法将数据还原出来。以RAID5为例:如果要记录两个数字,可以通过再多记录这两个数字的和来达到记录冗余性的目的。例如记录3和5

Form 表单的 resetFields() 失效原因

假设我们有如下代码:  <template><ElForm ref="formRef" :model="formModel" :rules="rules"><!-- 表单内容 --></ElForm></template><script setup>import { ref } from 'vue';const formRef = ref(null);const formModel = ref

游戏开发者有必要写博客的6大原因

为什么你要写博客?在本文中我将分析为何写博客在游戏产业中如此有效的 6 大原因。 假设你是资深的游戏开发者、制作、发行商、二年级学生、测试者、设计师、程序员、美术师或者编曲者。你的爱好伴随着许多的技艺。每个人完成一款游戏的过程,方法都不同,这里也充满许多值得我们学习的有趣瞬间。当然你可以继续坚守自己的看法。但我还是看到了许多低调的开发者们在挣扎着。 1. 贡献 我的观点中最重要的一方面便是你