2

我有一个带有 ATSAMW25 芯片的 Arduino MKR1000,我正在尝试调试我的代码中的崩溃错误。

这是有问题的功能:

void GuiDisplay::drawBitmap(rect_t frame, const uint16_t *data, rgb565_filter filter) {

    point_t origin = adjustPoint(frame.origin, _origin);
    uint16_t x = origin.x;
    uint16_t y = origin.y;

    tft->setAddrWindow(x, y, x + frame.width() - 1, y + frame.height() - 1);

    Serial.print("Drawing "); Serial.print((unsigned int)data, HEX); Serial.print(" ("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print("; "); Serial.print(x + frame.width() - 1); Serial.print(", "); Serial.print(y + frame.height() - 1); Serial.println(")");

    for (int ii = 0; ii < frame.width() * frame.height(); ii++) {

        Serial.print("  "); Serial.print((unsigned int)data, HEX); Serial.print("["); Serial.print(ii); Serial.print("] = ");

        uint16_t word = *(data + ii);

        Serial.println(word);

        tft->pushColor(word);
    }

    Serial.println("Done");
}

data从输出中可以看出,读取导致崩溃

Drawing 8AB1 (267, 14; 300, 41)
8AB1[0] =

这是一个闪存位置。ATSAMW25 不需要PROGMEM声明,只需const.

让我难过的是,它似乎只在某些内存范围内失败。我有很多这样的定义:

// Header

typedef struct bitmap_data_def {
    size_tt size;
    uint8_t count;
    const byte *data;
} bitmap_data_t;

extern const bitmap_data_t projector_bitmap;
extern const bitmap_data_t power_bitmap;
extern const bitmap_data_t slides_bitmap;
extern const bitmap_data_t camera_bitmap;
... and so on.


// CPP file

const byte power_bitmap_data[] = { [very long string!] }

const bitmap_data_t power_bitmap = {
    size_tt(26, 26),
    1,
    power_bitmap_data
};

它们都在同一个文件中声明,并且大多数都可以正常工作:

Drawing 86A0 (199, 193; 224, 212)
  86A0[0] = 0
  86A0[1] = 65535
   ... and so on ...
  86A0[519] = 0
Done

Drawing AB44 (199, 133; 224, 151)
  AB44[0] = 0
  AB44[1] = 38034
   ... and so on ...
  AB44[493] = 0
Done

等等。

到目前为止,我已经看到崩溃发生在 0x8A00 和 0x8B00 之间的内存位置以及 0x95BD 附近的位置。从上面可以看出,这些上面和下面的内存位置都很好。

如果我添加或删除一些声明,以便编译器在内存中重新排列它们,那么不同的声明会失败。它可能是导致崩溃的内存范围内的任何一个。

我看不出程序内存是如何被覆盖的,即使是它也不应该在读取时崩溃。我错过了一些微妙的记忆副本吗?如果是这种情况,那么我可能会超过 32KB SRAM 的限制,但我看不出在哪里/如何/为什么会发生这种情况。

我尝试了另一台 MKR1000 并得到完全相同的结果,所以问题似乎不是硬件故障。

任何帮助将不胜感激!谢谢你。

4

1 回答 1

0

好的,所以我解决了我自己的问题。我不确定这对其他人有多大用处,但导致崩溃是因为我正在读取 1 或 3 字节边界上的内存。这对于 ARM Cortex M0+ 系列处理器是不允许的。

这篇文章对理解内存寻址要求非常有帮助:

http://www.sumidacrossing.org/Musings/files/160606_Memory_and_the_Arduino.php

我使用 AdaFruit 的建议来解决实际问题:

https://learn.adafruit.com/adafruit-feather-m0-wifi-atwinc1500/adapting-sketches-to-m0#aligned-memory-access

基本上我替换了违规行:

uint16_t word = *(data + ii);

有了这个:

uint16_t word;
memcpy(&word, &(data[ii]), 2);
于 2016-12-16T17:43:53.610 回答