1 背景
芯片型号:MKW36A512VFT4(NXP)
操作系统:FreeRTOS
应用类型:将KW36的内部FLASH分区,取出一半模拟EEPROM进行读写。
错误现象:对模拟EEPROM进行读写时总是发生硬件错误中断,单步执行时发生错误中断的概率变低。
2 场景描述
在应用中,K36的内部Flash的大小是512K,将其分成A(256KB)+B(256KB)两个Bank,其中取Bank B的后128KB作为模拟EEPROM进行数据读写。理想情况下,程序存储在Bank A中XIP运行,K36在进行模拟EEPROM写操作时,首先将数据写在RAM中,然后交给协处理器去进行具体写入操作,所以在对Bank B进行读写操作时应该不会被CPU的其他操作影响,但是却时常发生硬件错误中断。
3 分析原因
网上查阅大牛文章,可总结一般情况下发生硬件错误中断的原因如下:
1、非法存储器访问
这也是最常见的问题是访问非法的存储器区域。
2、非对齐数据访问
如果我们直接操作一个指针,或者使用汇编代码,就会生成试图执行非对齐访问的代码,如果错误指令为存储器访问指令,就应该确定传输用的地制止是否是对齐的。
3、从总线返回错误
如果外设没有被初始化,或者时钟没有被使能,那么该外设可能会返回错误的响应,在有些不大常见的情况下,外设只能接收32位的传输,对字节或半字传输会返回错误响应。
4、异常处理中的桟被破坏
如果程序在中断处理执行后崩溃,还可能会引起桟帧被破坏,由于局部变量存储在桟空间中,如果异常处理中定义的数组在使用时超过了数组的大小,异常桟帧可能就会被破坏了,结果就是,异常退出后程序可能崩溃。
5、程序在某些C函数中崩溃
请检查是否为桟和堆预留了足够的空间,如:Keil中NXP LPC111X的堆空间默认为0字节,如果程序中使用了malloc、printf等C函数,那么就需要修改堆的大小了。
这个问题的另一个可能的原因是,连接器没有使用正确的C库函数,连接器通常会详细的告知用户使用了哪些库函数,有些情况下,可以检查这些信息。
6、意外的试图切换至ARM状态
进入硬件错误后,如果压入栈的XPSR的T位为0,那么这个错误就是由于切换至ARM状态引起的,引起这个错误的可能原因有很多,如非法函数指针,向量表中向量的最低位不为1,异常处理时桟帧被破坏或者连接器没有使用正确的C库等。
7、在错误的优先级上执行SVC
如果SVC指令的执行发生在SVC处理中,或者其他和SVC异常优先级相同或更高的异常处理中,就会引起错误,如果在NMI处理和硬件错误处理中使用SVC,则会导致锁定。
(原创链接:嵌入式程序设计中进入硬件故障错误的原因分析)
综合我们使用场景来判断,最终将错误锁定在了地址访问冲突的原因上。
4 解决方案
在模拟EEPROM写入操作加入FreeRTOS的临界保护就没有发生问题,但是由于写入数据量大(2K),导致整个操作耗费时间较长(因为一般来说底层操作函数在进行flash相关学操作时,为了避免错误以及写入成功率都会设置等待保护机制),对于操作系统的运行稳定性来说是非常不友好的,所以最终解决方案为更改NXP官方的SDK库,在写操作底层函数中操作地址那一段关闭全局中断,最后将时间缩短为可接受范围。
问题解决了,最后来分析原因,后来经过细致查找问题,最终发现,由于代码量相对比较庞大,导致代码没有完全处于Bank A,溢出至了Bank B导致代码在中断发生时,在进行写操作时,CPU也访问了Bank B,导致地址访问冲突这才发生硬件错误中断。
END