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);