最近,我在嵌入式软件中面临一种奇怪的行为。

我得到了什么:运行32位AVR32 Controller ,从外部SDRAM启动程序,因为文件太大,无法直接从微 Controller 闪存启动。由于存在物理内存映射,因此将内存区域划分为:

堆栈(从0x1000开始,长度为0xF000)(
EBI SDRAM(从0xD0000000开始,长度为0x00400000)。


会发生什么:不幸的是,我遇到了一个异常,该异常无法重现。查看我给定的堆栈跟踪,发生以下不规则事件:

名称:总线错误数据获取-事件源:数据总线-存储的返回地址:第一条未完成的指令

此外,堆栈指针具有有效值,而发生异常的地址(获取指令的最后入口)指向内存必杀技(例如0x496e6372,大约为0x5 ...,0x6 ....)。我猜,这必须是《手册》所讲的“第一条未完成的说明”。但是,我的源代码中的行始终是相同的:通过指针从数据数组访问成员函数。

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

问题是:添加或删除其他源代码会使事件消失并再次返回。

我的想法:某件事破坏了我的记忆(映射)。可能发生哪种错误?
  • 缓冲区溢出?
  • SDRAM Controller 可能已关闭,因此会丢失一些数据。这不是不可能,而是
  • 堆栈足够大,我已经用水印
  • 进行了检查
  • 正确设置了数据总线速率和AVR时钟


  • 如何解决此问题:更有效?不幸的是,我无法使用AVRStudio进行调试。任何提示或想法?还是我缺少明显的东西?

    编辑:

    用户提到的方法:
  • 检查函数指针和数组条目的地址
  • 覆盖堆栈数组
  • 写入不正确会打断
  • 未初始化的指针
  • 在崩溃情况下通过i检查数组访问
  • 使用异常处理程序地址进行非法内存访问
  • 使用snprintf代替sprintf


  • 该线程的最新附录:问题是旧软件模块中的数组访问错误(设置了错误的索引),与我的模块无关。我偶然发现了这个,是出于好奇,它没有更早出现,并且花了我一段时间才找到代码行。我将唯一给出的答案标记为正确的解决方案。

    谢谢大家的意见。

    保重(您的软件;))

    最佳答案

    这里有一些想法:

  • 选中“i”以确保它在数组范围内。
  • 检查将要调用的函数指针的地址。它应该在SDRAM中有一个地址。
  • 查看芯片是否具有异常处理程序地址,当其访问非法内存时将跳转至该地址。到那里后,输出一些调试数据
  • 如果调试器允许,请在写入时在someFunction()上设置一个断点。当它覆盖函数指针时,这将捕获其他函数。
  • 关于c - AVR32异常:总线数据错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32712816/

    10-11 07:01
    查看更多