STM32调用memcpy导致hardfault(调用memcpy本身,不是memcpy的执行)
STM32 call to memcpy causes hardfault (the call to memcpy itself, not the execution of memcpy)
情况: 我正在使用一个名为嵌入式 disco 的加密库,我有一个在我的 PC 上运行的演示,但是当将它移植到 MCU 时,我遇到了一个硬故障执行库程序。在错误代码中,库试图简单地将一个 strobe_s
结构的内容复制到另一个 strobe_s
中。这样做了两次:一次是 s1
,一次是 s2
。对于 s1
,图书馆只是分配目标。结构到源结构。然而,对于 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
Typedefs:
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;
问题:
- 仅仅 调用 到 memcpy 而没有实际执行 memcpy 中的单个指令怎么可能给出硬错误?
- 我该如何解决这个问题?
这里:
s2 strobe_s * 0x800a497 <_fflush_r+66>
s2
是flash(只读)地址。复制到只读内存在语义上都是错误的,如果区域设置为只读,则可能会触发 MPU 故障。
我不清楚原始代码是如何工作的,或者实际上是如何工作的:
*s1 = ss->strobe;
不过也没有引起问题。当然,即使没有异常,它也不会按预期工作。
情况: 我正在使用一个名为嵌入式 disco 的加密库,我有一个在我的 PC 上运行的演示,但是当将它移植到 MCU 时,我遇到了一个硬故障执行库程序。在错误代码中,库试图简单地将一个 strobe_s
结构的内容复制到另一个 strobe_s
中。这样做了两次:一次是 s1
,一次是 s2
。对于 s1
,图书馆只是分配目标。结构到源结构。然而,对于 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
Typedefs:
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;
问题:
- 仅仅 调用 到 memcpy 而没有实际执行 memcpy 中的单个指令怎么可能给出硬错误?
- 我该如何解决这个问题?
这里:
s2 strobe_s * 0x800a497 <_fflush_r+66>
s2
是flash(只读)地址。复制到只读内存在语义上都是错误的,如果区域设置为只读,则可能会触发 MPU 故障。
我不清楚原始代码是如何工作的,或者实际上是如何工作的:
*s1 = ss->strobe;
不过也没有引起问题。当然,即使没有异常,它也不会按预期工作。