Data abort为例子:数据非对齐访问异常

Data abort为例子:数据非对齐访问异常

例子1 数据非对齐异常

1. 首先看call stack 如下图:

目的:Call stack反应出任务的调用流程。

2. 分析当前指令位置:

目的:从上如可以看出,

1)当前指令的大概执行位置,以及前后函数位置;2)得到当前指令的执行情况:如寄存器,变量,内存地址等等,比如现在可以看出R4 R0 R1这些相关寄存器的值。他们的值反应出对应的数据位置,比如数组。

 

3.分析寄存器现场:

目的:

1)这里R4寄存器的值就反应出一个数据位置0x001ff8AD,这个我们可以通过该位置,Lis文件里面找到对应的数据。如下:

R4 地址对应的数据就是:NVRAM_EF_MMI_CACHE_SHORT_DEFAULT

2)最左边的一列数据就是stack dump信息,反应的是当时栈中最近执行的10条指令的地址,我们通过对这些地址的研究,也就可以找到出错的地方。

 

输入data.dump 0x001ff8ad 得到下图的数据:

从上图看出当访问0x1ff8a9地址(偏移是2c-->实际应用时要读这里的数据。

这里有人会问,cpu这个时候可以一次性取出0x1ff8a8地址开始的4个字节,不存在越过对齐边界,不需要两个CPU周期,为什么还会异常呢?

因为RISC体系是严格要求对齐的,这种情况也是属于非对齐的一种情况,LDRH指令是半字节访问,要求目标地址是访问数据单元字节数的整数倍。具体请参考CPU其他资料。

 

---综合以上我们就得出异常的大概两个位置:

函数:

1)CCC_nvram_enum_to_short_default()

{                                            

kal_uint8id_index;                 

kal_uint16*tempbuf;                

tempbuf = (kal_uint16 *)NVRAM_EF_MMI_CACHE_SHORT_DEFAULT;  //对它的访问出现问题    

id_index= mmi_cache_search_index(nDataItemId,nDataType);        

buffer[id_index] = tempbuf[id_index];//这里是访问的位置

}

-----初步分析是对数组访问NVRAM_EF_MMI_CACHE_SHORT_DEFAULT[512] 这个数组的时候 有发生字节不对齐的问题。

 

原因是0x001ffb0d是一个奇数地址。存在问题。

以前版本为什么没有问题?就是因为该数组的地址是一个偶数地址。

解决方法:

方法1:__align(4)或者__align(2) 修饰NVRAM_EF_MMI_CACHE_SHORT_DEFAULT。这个当16bit访问的时候,就是对齐访问。

  mmi_rp_mmi_cache.c

方法2:不做对齐访问修饰,改成8bit访问方式,也可以避免问题,因为字节访问不存在对齐的问题。

你可能感兴趣的:(Data abort为例子:数据非对齐访问异常)