Ich habe auch überprüft, ob die Indizes stimmen und ob sizeof() den
richtigen Wert zurück gibt, beides positiv.
Nun bin ich mit meinem Latein am Ende und hoffe auf eure Hilfe.
Gruß
Hannes
Da targetimage aufs Flash zeigt: Kann es sein, dass der Compiler den
Wert von targetimage->image_progfuses[0] aus dem Kontext heraus direkt
kennt, bei targetimage->image_progfuses[index] aber nicht weiss, dass er
auf ROM statt RAM zugreifen muss?
Ja. Und Text und Bild passen nicht zusammen. Im Text sind vier HEX-Werte
zu sehen, im Bild 8.
Edit: prx wird wohl die richtige Spur gefunden haben. Welchen Datentyp
hat showHex() ?
Bei AVR zeigen alle Pointer standardmäßig auf RAM.
Die CPU Befehle, die normalerweise zum Einsatz kommen, können nicht auf
FLASH zugreifen. Um auf FLASH zuzugreifen, müssen die Funktionen aus
https://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html
verwendet werden, dann wird Code mit den richtigen Befehlen erzeugt.
muss es also lauten.
D.h. solange die entsprechenden Anweisungen zur Compile-Zeit eindeutig
sind, weiß das Programm, welches die korrekten Adressen der Daten sind?
Denn die meisten anderen Zugriffe auf die weiteren Elemente dieses
target_image erfolgen in dem Code (aus einem Adafruit-Projekt) ohne
dieses Makro.
showHex() ist eine void-Funktion für die Ausgabe auf der seriellen
Schnittstelle, die ein Byte erwartet.
Weil sie ein "normales" byte erwartet, geht der Compiler davon aus, dass
das im RAM liegt.
Aus diesem Grund gibt es auch printf() versus printf_p(), sowie puts()
versus puts_p() und viele weitere. Diese Funktionen erwarten einen
Zeiger auf eine Zeichenkette. Am Zeiger alleine kann der Compiler nicht
erkennen, ob RAM oder FLASH gemeint ist. Die Adressen 0, 1, 2, 3, 4,
usw. gibt es in beiden Speichern. Außerdem kann eine Funktion nicht
beide Speicher abdecken, denn zum Zugriff auf diese Speicher werden
unterschiedliche CPU-Befehle benötigt. Du brauchst also zwangsläufig
zwei unterschiedliche Varianten dieser Funktionen.
Bei PC und ARM Controllern ist das anders. Die haben einen
Segmentierten Adressraum, in dem RAM und FLASH hintereinander liegen.
Alle Adressen zeigen dort eindeutig auf eine bestimmten Speicher (z.B.
0-32768 ist FLASH und 1048510-1068990 ist RAM), deswegen brauchen sie
dazu auch keine unterschiedlichen Befehle.
Ich weiß nicht, ob du __flash benutzt hast. Das wurde erst relativ spät
nachträglich zum Compiler hinzugefügt und seine Funktionsweise ist
zumindest mir immer etwas unklar. Deswegen nutze ich es nicht.
Siehe
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Flash_mit_flash_und_Embedded-C
Johannes H. schrieb:> D.h. solange die entsprechenden Anweisungen zur Compile-Zeit eindeutig> sind, weiß das Programm, welches die korrekten Adressen der Daten sind?
Nein. Ohne pgm_read_ / write wird immer nur das SRAM angesprochen. Der
gcc kennt das Konzept „Flash/SRAM“ überhaupt nicht.
Er berechnet zur Compilezeit die Werte, und dabei spielt es dann keine
Rolle, ob die konstanten Werte zur Laufzeit im Flash oder im SRAM
liegen.
Oliver
Eine eigene Frage?
Dieser Thread ist über 5 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.