2016-12-15 3 views
2

Ich habe ein Arduino MKR1000 mit einem ATSAMW25-Chip, und ich versuche, einen Absturzfehler in meinem Code zu debuggen.Flash lesen bei bestimmten Adressen abstürzt ATSAMW25

Dies ist die beanstandete Funktion:

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

von data bewirkt, dass der Absturz Lesen, wie Sie aus dem Ausgang

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

Dies ist eine Flash-Speicherstelle zu sehen. Die ATSAMW25 benötigt keine PROGMEM Deklarationen, nur const.

Was mich ratlos ist, ist, dass es anscheinend nur für einige Speicherbereiche fehlschlägt. Ich habe eine Reihe von Definitionen wie folgt aus:

// 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 
}; 

Sie sind alle in der gleichen Datei deklariert und die meisten von ihnen funktionieren:

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 

und so weiter.

Bisher habe ich den Absturz für Speicherorte zwischen 0x8A00 und 0x8B00 und für Standorte um 0x95BD geschehen. Wie Sie oben sehen können, waren Speicherplätze über und unter diesen in Ordnung.

Wenn ich einige der Deklarationen hinzufüge oder entferne, so dass der Compiler sie im Speicher neu anordnet, schlägt eine andere Deklaration fehl. Es könnte sein, was auch immer in den Speicherbereichen darüber fällt, die den Absturz verursachen.

Ich kann nicht sehen, wie der Programmspeicher überschrieben werden könnte, und selbst wenn es war, sollte es beim Lesen nicht abstürzen. Gibt es eine subtile Erinnerung, die ich verpasst habe? Wenn das der Fall wäre, könnte ich die Grenze von 32 KB SRAM überschreiten, aber ich kann nicht sehen, wo/wie/warum das passieren würde.

Ich habe ein anderes MKR1000 versucht und bekomme genau das gleiche Ergebnis, also scheint das Problem kein Hardwarefehler zu sein.

Jede Hilfe würde sehr geschätzt werden! Vielen Dank.

Antwort

0

OK, also habe ich mein eigenes Problem gelöst. Ich bin mir nicht sicher, wie nützlich das für andere sein wird, aber der Absturz wurde verursacht, weil ich Speicher auf 1- oder 3-Byte-Grenzen gelesen habe. Das ist für die ARM Cortex M0 + -Prozessorfamilie nicht erlaubt.

Dieser Artikel war sehr hilfreich bei der Adressierung des Speichers Anforderungen zu verstehen:

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

verwendete ich den Vorschlag von Adafruit das eigentliche Problem zu lösen:

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

Grundsätzlich ersetzt ich das störende Linie:

uint16_t word = *(data + ii); 

Mit diesem:

uint16_t word; 
memcpy(&word, &(data[ii]), 2);