1. cortex-m0 处理器内核异常中断简介			 
			在cortex‐m0内核上搭载了一个异常响应系统,支持众多的系统异常和外部中断。其中,编号为1-15的对应系统异常,大于等于16的则全是外部中断,优先级的数值越小,则优先级越高。除了个别异常的优先级被定死外,其它异常的优先级都是可编程的。
因为芯片设计可以修改内核的硬件描述源代码,所以做成芯片后,支持的中断源数目常常不到240 个,并且优先级的位数也由芯片厂商最终决定。
类型编号为 1-15 对应系统异常,在《arm cortex-m0权威指南》一书中的第12章节章节中有描述:对于arm处理器,架构采用错误异常的机制来检测问题,当一个程序产生了错误并且被处理器检测到时,异常中断会被触发,并且核心会跳转到相应的异常终端处理函数执行,错误异常的中断有如下:
reset
在上下电、nrst拉低、看门狗复位或软复位时启动复位。当复位产生时,处理器停止一切操作,并将复位当做一种特殊形式的异常来执行,进入到对应的中断函数。当复位撤销时,从向量表中复位项提供的地址处重新启动执行,芯片重新开始执行。
nmi
不可屏蔽中断(nmi),可以由外设产生,也可以由软件来触发。这是除复位之外优先级最高的异常中断,nmi永远使能,优先级固定为-2,css的时钟安全机制使能判定时钟失效后就会进入到该中断。nmi 不能:
1、被屏蔽,它的执行也不能被其他任何异常中止;
		2、被除复位之外的任何异常抢占。
hardfault
hardfault 是由于在正常操作过程中或在异常处理过程中出现错误而出现的一个异常。hardfault的优先级固定为-1,表明它的优先级要高于任何优先级可配置的异常。
svcall
管理程序调用(svc)异常是一个由svc指令触发的异常。在os环境下,应用程序可以使用 svc指令来访问os内核函数和器件驱动。
pendsv
pendsv是一个中断驱动的系统级服务请求。在os环境下,当没有其它异常有效时,使用 pendsv 来进行任务切换。
systick
systick是一个系统定时器到达零时产生的异常,软件也可以产生一个systick异常。在os环境下,处理器可以将这个异常用作系统节拍。
中断(irq)
中断(或 irq)是外设发出的一个异常,或者由软件请求产生的一个异常。在系统中,外设使用中断来与处理器通信,在中断函数中可以查询和清除标志操作。
2. hardfault异常			 
			hardfault (硬件错误,也有译为硬错误)是在mcu上编写程序中所产生的错误,硬件错误处理几乎是最高优先级,它的优先级为-1,只有复位和不可屏蔽中断(nmi)可以对其进行抢占。当它发生时,表示处理器出现了问题,需要采取紧急修复措施。
造成hardfault错误的可能原因较多,如何在代码量较大的情况下,快速定位造成的hardfault的问题代码,就成为比较关键的问题。
本文将以mm32f0130系列mcu为例,keil-mdk开发环境,总结hardfault的调试、定位方法。在其它cortex-m0 (m3,m4)内核处理器,和其它开发环境下,也可作为参考。
2.1 可能的原因			 			 			《arm cortex-m0权威指南》中提到,关于 cortex m0内核主要有以下几点引起hardfault的原因:
非法存储器访问
											非对齐数据访问
											从总线返回错误
											异常处理中的栈被破坏
											程序在某些 c 函数中崩溃
											意外地试图切换至 arm 状态
											在错误的优先级上执行系统服务调用指令(svc)
					 从软件角度,产生hardfault的可能原因有:		 							数组越界
											野指针
											未初始化硬件却开始操作,或无中断服务函数等
											任务堆栈溢出
											中断服务函数设置错误
											时钟异常
					 注意:只有复位和nmi可以抢占优先级固定的 hardfault 处理程序。hardfault可以抢占除复位、nmi 或其它硬故障之外的任何异常。		 		2.2 可能出现的异常			 	如果在执行nmi或hardfault处理程序时,或者在一个使用msp的异常返回时出栈的却是psr的时候系统产生一个总线错误,处理器进入一个锁定状态。当处理器处于锁定状态时,它不执行任何指令。处理器保持处于锁定状态,直到下面任何一种情况出现:		 							出现复位
											调试器将锁定状态终止,出现中止仿真的现象
											出现一个nmi,以及当前的锁定处于hardfault处理程序中
					 注意:如果锁定状态出现在nmi处理程序中,后面的nmi就无法使处理器离开锁定状态。		 在应用程序中,处理器处于锁定状态,会一直在void hardfault\_handler(void)函数中执行。		 void hardfault_handler(void){  /* go to infinite loop when hard fault exception occurs */  while (1)  {  }}			下面将在mm32f0130上运行的数组越界代码为例,具体阐述定位步骤:
void stacktest(void){    int data[3],i;    for(i=0; ishcsr);        printf(current lr = %x, lr_value);    }}			处理器进入到hardfault,将r0~r3、r12、lr、pc信息通过串口打印,根据寄存器信息排查问题代码。
当处理器处理异常时,除非异常是一个末尾连锁异常或迟来的异常,否则,处理器把信息都压入到当前堆栈中入栈(stacking),8个数据字的结构被称为栈帧(stack frame),栈按照双字地址对齐方式。
入栈后,堆栈指针立刻指向栈帧的最低地址单元。栈包含返回地址,这是被中止的程序中下条指令的地址。这个值在异常返回时返还给 pc,使被中止的程序恢复执行。
如下图连接仿真器查看汇编的地址可以找到是程序问题,根据pc指针地址,在程序生成的.map中查找出问题函数。
4. 处理建议			 
			根据上述的定位手段可以查找是哪一种情况造成的异常,在编程过程中需要避免出现上述异常情况,但是在恶劣复杂的环境下,可能会小概率触发hardfault中断,可以在函数中添加复位或者跳转指令,具体的实现方式需根据应用和使用环境来评估。
原文标题:hardfault定位方法和步骤
			文章出处:【微信公众号:安芯教育科技】欢迎添加关注!文章转载请注明出处。
			
			
       	 	
    	什么是avr单片机
         	 	
    	一条一元!苹果被曝出卖用户隐私
         	 	
    	工业AI视觉进化论
         	 	
    	毫米波雷达革命,成像雷达加速自动驾驶升级
         	 	
    	村田手术器械用RFID标签,助力医用物联网发展
         	 	
    	Cortex-M0处理器内核异常中断简介
         	 	
    	联想Z5 Pro的发布,让联想手机逆势增长再次回归于市场
         	 	
    	新华社专访陈天桥,称赞其为支持基础研究的先行者
         	 	
    	为什么通信行业需要数字孪生?
         	 	
    	腾讯防疫健康码累计访问量破60亿 成全国服务用户最多的健康码
         
       	 	
    	【技术贴】图像传感器的动态范围
         	 	
    	NB-IoT和5G之间有什么联系,对物联网会产生什么影响
         	 	
    	汽车芯片短缺的原因有哪些
         	 	
    	四足机器人接触检测和模型
         	 	
    	储能安全认证和银行担保的关系,UL1973和UL9540有什么用?
         	 	
    	瑞萨电子投资甲府工厂,300mm功率半导体产线恢复
         	 	
    	手机芯片市场格局将发生怎样的改变?
         	 	
    	天线方向图及增益测试场景及设备
         	 	
    	“智慧大脑”+“一楼一品”,全方位展示马尾物联网产业发展
         	 	
    	数传电台的接收灵敏/数传电台的网络诊断