【问题标题】:Fault on CortexM0+ From LDRH Instruction来自 LDRH 指令的 CortexM0+ 故障
【发布时间】:2014-02-09 15:41:29
【问题描述】:

我有一个在 M3 架构上运行良好的代码库,并且正在将一些代码移植到 M0+。我遇到了错误,我不知道为什么。我使用的确切微型是 KL36Z128(飞思卡尔)。我正在为我的工具链使用 ARM-GCC-2013-Q3 版本。

这里是 C 代码(它用于在数据包进入时对其进行解析,所以一旦我获得足够的数据,我就开始挑选我需要填写命令结构的内容):

state->cmd = *((U16*)&din[15]); // 代码库有 'legacy' 类型定义

生成的程序集是:

0x4250 添加r1,#15

0x4252 ldrh r1, [r1, #0]

0x4254 strh r1, [r0, #2]

并且寄存器值在故障发生时是:

r0 = 0x1ffff2cc r1 = 0x1ffffad8

我不知道这里发生了什么 - 这看起来很简单的组装。寻址似乎还可以。飞思卡尔数据表说 RAM 分为 2 个部分:

SRAM_L: (0x20000000-1KB) to 0x20000000 (所以它的下半部分是总SRAM的1/4)

SRAM_H:0x20000000 到 (0x20000000+3KB)

我最初认为生成的代码可能有问题,以及可以使用哪些指令来访问不同存储区中的内存 - 但我想不到。

此外,“din”值在函数参数列表中定义为:const U8 *din

有什么想法吗?

【问题讨论】:

  • dinuint8_t 类型的数组吗?在这种情况下,您违反了对齐规则!
  • 是的,参数列表中的声明是“const U8 *din”。在这个代码库中,U8 映射到 uint8_t。
  • 所以你的程序调用了未定义的行为。您正在以 uint16_t 对象的形式访问 uint8t_t 对象。 Cortex-M0+ 不支持未对齐访问,尝试执行未对齐访问会引发 HardFault。
  • 是的。我只是查了一下-显然不知道。感谢您的帮助。
  • Ouah 回答了这个问题 - 但我不知道如何将他的回答标记为“已接受”。

标签: c gcc embedded fault cortex-m


【解决方案1】:
state->cmd = *((U16*)&din[15]);

* 操作执行非对齐访问,因为 din[15] 元素的类型为 uint8_t,但作为 uint16_t(或 U16)对象访问。 Cortex-M0 / M0+ 不支持未对齐访问,任何执行未对齐访问的尝试都会引发 HardFault。

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/BABFAIGG.html

要修复您的程序,请将din 元素作为uint8_t 对象访问:

 state->cmd = (din[16] << 8) | din[15];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-16
    • 1970-01-01
    • 2012-03-28
    • 2021-07-23
    • 2020-03-14
    • 2017-05-04
    • 2015-07-27
    • 2014-02-12
    相关资源
    最近更新 更多