简体   繁体   English

AVR32异常:总线数据错误

[英]AVR32 exception: Bus Data Error

Recently, I am facing a - to me - strange behavior in my embedded software. 最近,我在我的嵌入式软件中遇到了一种奇怪的行为。

What I got: Running a 32 bit AVR32 controller, starting the program from an external SDRAM, as the file size is too big to start it directly from the micro-controller flash. 我得到了:运行一个32位AVR32控制器,从外部SDRAM启动程序,因为文件太大,无法直接从微控制器闪存启动它。 Due to the physical memory map, the memory areas are split between: 由于物理内存映射,内存区域分为:

stack (start at 0x1000, length of 0xF000) ( < 0x1000 is protected by the MPU) 堆栈(从0x1000开始,长度为0xF000)(<0x1000受MPU保护)

EBI SDRAM (start at 0xD0000000, length of 0x00400000). EBI SDRAM(从0xD0000000开始,长度为0x00400000)。


What happens: Unfortunately I got an exception, which is not reproducible. 会发生什么:不幸的是我得到了一个例外,这是不可重复的。 Looking at my given stack trace, the following event irregular occurs: 查看我给定的堆栈跟踪,发生以下事件不规则:

Name: Bus error data fetch - Event source: Data bus - Stored Return Address: First non-completed instruction 名称:总线错误数据获取 - 事件源:数据总线 - 存储的返回地址:第一个未完成的指令

Additionally, the stack pointer has a valid value, whereas the address where the exception occurs (last entry point for fetching instructions), points into the memory nirvana (eg 0x496e6372, something around 0x5..., 0x6....). 另外,堆栈指针具有有效值,而发生异常的地址(用于获取指令的最后入口点)指向存储器必杀技(例如0x496e6372,大约0x5 ...,0x6 ....)。 I guess, this has to be the "First non-completed instruction", the manual is talking about. 我想,这必须是“第一个未完成的指令”,手册正在谈论。 However, the line in my source code is always the same: accessing a member function from a data array via pointer. 但是,我的源代码中的行始终是相同的:通过指针从数据数组访问成员函数。

      if(mSomeArray[i])
      {
         mSomeArray[i]->someFunction(); <-- Crash
      }

The thing is: adding or deleting other source code makes the event disappear and return again. 问题是:添加或删除其他源代码会使事件消失并再次返回。


What I thought about: Something is corrupting my memory (mapping). 我的想法:有些东西正在腐蚀我的记忆(映射)。 What kinds of errors are possible for this? 这有什么样的错误?

  • A buffer overflow? 缓冲区溢出?
  • The SDRAM controller could be turned off, so it loses some data. SDRAM控制器可能会关闭,因此会丢失一些数据。 That is not impossible, but rather improbably 这不是不可能的,而是不可能的
  • The stack is big enough, I already checked this with a watermark 堆栈足够大,我已经用水印检查了这个
  • The Data Bus Rate and AVR clock are set correctly 数据总线速率和AVR时钟设置正确

How to solve this: More assert? 如何解决这个问题:更多断言? Unfortunately I cannot debug this with AVRStudio. 不幸的是我无法使用AVRStudio进行调试。 Anyone a hint or idea? 有人暗示或想法吗? Or am I missing something obvious? 还是我错过了一些明显的东西?


Edit: 编辑:

Mentioned approaches from users: 提到用户的方法:

  • Check for addresses of function pointer and array entries 检查函数指针和数组条目的地址
  • Overwrite of stack array 覆盖堆栈数组
  • Not properly written interrupts 没有正确写入中断
  • Not initialized pointers 没有初始化的指针
  • Check for array access via i at crash case 在崩溃情况下通过i检查阵列访问
  • use exception handler address for illegal memory access 使用异常处理程序地址进行非法内存访问
  • use snprintf instead of sprintf 使用snprintf而不是sprintf

Late appendix to the thread: the issue was a wrong array access (wrong index was set) in an old software module, that had nothing to do with my modules. 线程的后期附录:问题是旧的软件模块中的错误数组访问(设置了错误的索引),这与我的模块无关。 I found this by accident, it was a curiosity that it didn't appear earlier and it took me quite a while to find the line of code. 我意外地发现了这一点,这是一种好奇心,它没有出现过早,我花了很长时间才找到代码行。 I mark the only given answer as correct solution. 我将唯一给出的答案标记为正确的解决方案。

Thank you all for your input. 谢谢大家的意见。

Take care (of your software ;)) 小心(你的软件;))

Here are some ideas: 以下是一些想法:

  1. Check 'i' to make sure it is within the array bounds. 检查'i'以确保它在数组范围内。
  2. Check the address of the function pointer that is about to be called. 检查即将被调用的函数指针的地址。 It should have an address within the SDRAM. 它应该在SDRAM中有一个地址。
  3. See if the chip has an exception handler address it will jump to when it accesses illegal memory. 查看芯片是否有一个异常处理程序地址,它会在访问非法内存时跳转到该地址。 Once you are there, output some debug data 一旦你在那里,输出一些调试数据
  4. If your debugger allows, set a breakpoint on someFunction() when it is written. 如果调试器允许,在写入时在someFunction()上设置断点。 This would catch some other function when it overwrites the function pointer. 当它覆盖函数指针时,这将捕获一些其他函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM