微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

STM32调用memcpy导致hardfault调用memcpy本身,不是memcpy的执行

如何解决STM32调用memcpy导致hardfault调用memcpy本身,不是memcpy的执行

情况:我正在使用一个名为嵌入式迪斯科的加密库,我在我的 PC 上有一个演示,但是在将它移植到 MCU 时,我在执行库程序时遇到了硬故障。在错误代码中,库试图简单地将一个 strobe_s 结构的内容复制到另一个 strobe_s 中。这样做两次:一次用于 s1,一次用于 s2。对于 s1,库只分配目标。 struct 到源结构。然而,对于 s2,这样的赋值给出了一个错误。由于 Cortex-M ISA 需要对齐的内存访问,我认为用 memcpy 替换分配应该可以解决问题。然而,简单地使用调试器进入 memcpy 会导致硬故障! IE。我在带有 memcpy 的那一行有一个断点,当进入故障处理程序时被调用!我已经使用 memcpy 修复了代码其他部分中未对齐的内存访问......

单片机:STM32L552ZET6QU

错误代码

下面的代码是我对原始库代码修改,其中对 *s2 的赋值被 memcpy 替换。 library's github 的原始代码是:

  // s1 = our current strobe state
  *s1 = ss->strobe;
  if (!half_duplex) {
    // s2 = s1
    *s2 = ss->strobe;
  }

我的修改版本:

  // s1 = our current strobe state
  *s1 = ss->strobe;
  if (!half_duplex) {
    // s2 = s1
    // WARNING: The below code will give a HARD FAULT ON THE STM32L552ZE!
    // *s2 = ss->strobe;
    // Fix I tried: Use memcpy instead!
    memcpy((void*) s2,(void*)(&(ss -> strobe)),sizeof(strobe_s));
  }

memcpy 的参数值:

就在执行 memcpy 之前,调试器向我显示了相关变量的以下值:

Expr.   Type                Value
----------------------------------------------------
s1      strobe_s *          0x800c374   
s2      strobe_s *          0x800a497 <_fflush_r+66>    
ss      symmetricState *    0x2002f988  
&s1     strobe_s **         0x2002f690  
&s2     strobe_s **         0x2002f68c  
&ss     symmetricState **   0x2002f694

类型定义:

typedef struct symmetricState_ {
  strobe_s strobe;
  bool isKeyed;
} symmetricState;

/** Keccak's domain: 25 words of size b/25,or b/8 bytes. */
typedef union {
  kword_t w[25];
  uint8_t b[25 * sizeof(kword_t) / sizeof(uint8_t)];
} kdomain_s;

/** The main strobe state object. */
typedef struct strobe_s_ {
  kdomain_s state;
  uint8_t position;
  uint8_t pos_begin;
  uint8_t flags;
  uint8_t initiator;
  uint8_t initialized;  // strobe is initialized if this value is set to 111.
                        // This is because we cannot assume that a boolean would
                        // be set to false initially (C stuff). A uint8_t is a
                        // short value but here we do not care about security
                        // much,rather catching bugs early in a development
                        // environement.
} strobe_s;

问题:

  1. 调用到 memcpy 而没有实际执行 memcpy 中的单个指令怎么可能会导致硬错误
  2. 我该如何解决这个问题?

解决方法

这里:

result => { 4,5 }
expected result => { Andy: 4,Brian: 5 }

s2 strobe_s * 0x800a497 <_fflush_r+66> 是闪存(只读)地址。复制到只读内存在语义上是错误的,如果该区域设置为只读,可能会触发 MPU 故障。

我不清楚原始代码是如何工作的,或者实际上是如何工作的:

s2

也不会造成问题。当然,即使没有例外,它也不会按预期工作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。