Flash читает по определенным адресам вылетает ATSAMW25

У меня Arduino MKR1000 с чипом ATSAMW25, и я пытаюсь отладить ошибку в моем коде.

Это оскорбительная функция:

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. Как вы можете видеть из приведенного выше, места памяти над и под ними были в порядке.

Если я добавляю или удаляю некоторые из объявлений, так что компилятор переставляет их в памяти, то другое объявление завершается ошибкой. Это может произойти в зависимости от того, какой диапазон памяти окажется выше, что приведет к сбою.

Я не могу понять, как память программы могла быть перезаписана, и даже если бы это было так, она не должна давать сбой при чтении. Есть ли какая-то тонкая копия памяти, которую я пропустил? Если бы это было так, то я мог бы превысить ограничение в 32 КБ SRAM, но я не вижу, где / как / почему это произойдет.

Я попробовал другой MKR1000 и получил точно такой же результат, поэтому проблема, похоже, не является аппаратной ошибкой.

Любая помощь будет принята с благодарностью! Спасибо.

1 ответ

Итак, я решил свою проблему. Я не уверен, насколько это будет полезно для кого-то еще, но сбой был вызван тем, что я читал память на 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

В основном я заменил оскорбительную строку:

uint16_t word = *(data + ii);

С этим:

uint16_t word;
memcpy(&word, &(data[ii]), 2);
Другие вопросы по тегам