【问题标题】:Pointer randomly assigned mysterious values (A5A5A5A5 and FFFFFFFF) on a stm32 using freeRTOS causing hardfault指针在 stm32 上使用 freeRTOS 随机分配神秘值(A5A5A5A5 和 FFFFFFFF)导致硬故障
【发布时间】:2012-12-14 08:27:32
【问题描述】:

我遇到了一个硬故障问题,它出现在看似随机的时间,其中一个指针指向地址 A5 或 FF(我允许的内存空间远低于 80000000 及以上的内存空间)。这两个值似乎总是同一个指针。

我正在使用一个运行 STM32F205RE 处理器的嵌入式系统,该处理器与一个名为 cg2900 的 fm/蓝牙/gps 芯片进行通信,并在该芯片上发生此错误。

使用调试器,我可以看到在几次测试运行期间指针分别指向地址 A5 和 FF。然而,它似乎是随机发生的,有时我可以运行测试一个小时而不会失败,而其他时候它会崩溃 20 秒。

我正在运行 freeRTOS 作为调度程序,以在可能会以某种方式干扰的不同任务(一个用于无线电,一个用于蓝牙,一个用于其他定期维护)之间切换。

这可能是什么原因?由于它正在运行自定义硬件,因此不能排除这是硬件问题(可能)。关于如何解决问题的任何指示(不是双关语)?

编辑:

经过进一步调查,似乎它崩溃的地方非常随机,而不仅仅是那个特定的指针。我使用了一个硬故障处理程序来获取这些寄存器的以下值(所有值都是十六进制):

崩溃前的半长跑(分钟):

R0 = 1
R1 = fffffffd
R2 = 20000400
R3 = 20007f7c
R12 = 7
LR [R14] = 200000c8  subroutine call return address
PC [R15] = 1010101  program counter
PSR = 8013d0f
BFAR = e000ed38
CFSR = 10000
HFSR = 40000000
DFSR = 0
AFSR = 0
SCB_SHCSR = 0

崩溃前的非常短的运行时间(秒):

R0 = 40026088
R1 = fffffff1
R2 = cb3
R3 = 1
R12 = 34d
LR [R14] = 40026088  subroutine call return address
PC [R15] = a5a5a5a5  program counter
PSR = fffffffd
BFAR = e000ed38
CFSR = 100
HFSR = 40000000
DFSR = 0
AFSR = 0
SCB_SHCSR = 0

另一个短的(秒):

R0 = 0
R1 = fffffffd
R2 = 20000400
R3 = 20007f7c
R12 = 7
LR [R14] = 200000c8  subroutine call return address
PC [R15] = 1010101  program counter
PSR = 8013d0f
BFAR = e000ed38
CFSR = 1
HFSR = 40000000
DFSR = 0
AFSR = 0
SCB_SHCSR = 0

经过很长时间(1 小时以上):

R0 = e80000d0
R1 = fffffffd
R2 = 20000400
R3 = 2000877c
R12 = 7
LR [R14] = 200000c8  subroutine call return address
PC [R15] = 1010101  program counter
PSR = 8013d0f
BFAR = 200400d4
CFSR = 8200
HFSR = 40000000
DFSR = 0
AFSR = 0
SCB_SHCSR = 0

似乎大部分时间都在同一点崩溃。我根据之前的建议调整了内存,但我似乎仍然有同样的问题。

感谢您的宝贵时间!

亲切的问候

【问题讨论】:

  • 这些看起来像是故障安全魔法字节。您确定在某处没有悬空指针、取消引用的 NULL 或返回的本地数组吗?
  • @H2CO3 是的,它们确实看起来像魔术字节。指针指向数组的基础(全局范围),并且我已经有一个条件来检查以确保我不会在它之外写入。指针本身一旦被初始化为数组的基数,就永远不会被分配。
  • 如果您可以添加一些实际代码,那会有所帮助。
  • 如果数组是全局的,并且指针只指向数组并且不改变它在任何情况下都不是多余的吗?也就是说,出于各种原因here,任何全球性的事情几乎总是一个坏主意。
  • @Clifford 有问题的代码是一些遗留的遗留代码,因此它是全球性的。它使用指针的原因是特定设备可以包含其他设备中不包含的一组功能,因此使用不同的缓冲区(请注意,这不是一个非常优雅的解决方案,但这超出了这里的范围)。

标签: pointers operating-system embedded hardware stm32


【解决方案1】:

在您的评论中,您提到此指针被显式分配一次,然后从未被写入。在这种情况下,您至少应该声明它const 并使用初始化而不是赋值,例如

arraytype* const ptr = array ;

这将允许编译器检测任何显式写入。然而,指针更有可能被一些不相关的编码错误破坏。

Coretx-M3 片上调试支持数据访问断点;您应该在有问题的指针上设置这样的断点,以便捕获对它的所有写访问。您将在初始化时休息一下,然后在修改后休息 - 有意或无意。

可能的原因是相邻数组或线程堆栈溢出。

【讨论】:

  • 感谢您的反馈!它不是常量的原因是代码可以使用几个单独的缓冲区,具体取决于它正在运行的特定设备上的当前功能集。仅出于调试目的,我现在尝试将其设置为 const 并且编译器似乎仍然接受代码,因此至少这似乎不是问题。
  • 就数据访问断点而言,我将如何激活它们?我无法在谷歌或 ST 网站/文档上找到任何详细信息。我正在使用编辑器 Ride7 并通过 Rlink Pro 进行调试,但在 IDE 中找不到此功能。有人对如何手动设置(通过asm代码或其他东西)有任何建议或示例吗?
  • @ChewToy:我没有使用过 RIDE,但谷歌搜索可能会建议:Debug->advanced commands->advanced breakpoints。我建议您查阅您的产品手册;该功能可能是目标和/或调试器硬件特定的。
  • @ChewToy:如果您的 IDE 不支持硬件支持的数据断点,您可能可以直接对 the DWT 进行编程(虽然可能并不容易 - 我从未尝试过!)。
【解决方案2】:

如果您尝试重新定位阵列并继续遇到同样的问题,

那么有些任务溢出了。

正如您所提到的,您使用的是 FreeRTOS,并且由于行为是随机的,因此您在调用 xTaskCreate 时的设置 STACK_SIZE 可能有问题

这通常发生在分配的大小小于您真正需要的大小时。

如果您阅读有关 usStackDepth 的文档,您会注意到 表示乘数而不是字节数。

我个人会排除你嵌入式主板的硬件问题,我会专注于 FreeRTOS 的配置问题

【讨论】:

  • 感谢您的回复!很可能就是这种情况。我确实使用了 xTaskCreate,就好像它是字节数一样!我会在新年前夜回来工作时通过一些测试进一步研究它
  • 我确实遇到了您建议的问题,但似乎没有帮助。我仍然有和以前一样的问题。虽然我仍然同意它看起来像溢出
  • 查看您添加的数据,我注意到您的“链接寄存器”始终指向 RAM 位置,并且一旦指向端口 DMA1... 这让我认为 DMA 传输初始化是被更高优先级的任务打断,所以你应该把你的代码保护成一个序列 xSemaphoreTake(...) ~ xSemaphoreGive(...) 你可以阅读更多关于mutex的信息。
【解决方案3】:

认为问题是由内存存储引起的。当我以最高速度(120 Mhz)运行处理器并使用 1.8 伏电源(主要为 3 伏电源设计)时,我的内存出现了一些竞争状况。通过使用更高的等待状态来解决它。

【讨论】:

    【解决方案4】:

    我还没有准备好完整的问题,但听起来 0xa5a5a5a5a5 值是位解压缩的症状,类似于位腐烂。基本上, 0xffffffff = 0b11111111111111111111111111111111 的叠层结构开始剥离,1 的相互偏离。他们甚至可以开始侵入相邻的单词。

    【讨论】:

      猜你喜欢
      • 2018-05-27
      • 1970-01-01
      • 2016-03-04
      • 2021-01-29
      • 1970-01-01
      • 1970-01-01
      • 2012-01-05
      • 2021-07-23
      • 2019-05-07
      相关资源
      最近更新 更多