Liebe Leute,
ich möchte im Programmspeicher ein Bytearray ablegen, welches ich zur
Compilezeit "zusammenstelle". Dazu habe ich einige #defines erstelle,
über die die die Feldinhalte festlege:
// hier soll jetzt das "Char-Array" eingefügt werden
6
// und dann kommen noch weitere Bytes und Words ....
7
};
Das klappt auch bis auf den String "NMEA2000_MFMODELID". Hier weiß ich
nicht, wie ich den zur Compilezeit geeignet zerlegen lassen kann, so
dass die einzelnen Buchtaben sukkzessive in den Bytes von
"NMEA2000_ProductInformation_Data" abgelegt werden.
Außerdem ist in der Spezifikation vorgeschrieben, das
"NMEA2000_MFMODELID" 32 Byte lang zu sein hat und alle nicht vewendeten
Bytes mit 0xFF aufgefüllt werden. Kann mann das auch irgendwie geschickt
mit Präprozessor und Compiler lösen?
Ich hätte gern den fertigen Datensatz im Flash, damit ich im Programm
dann nurnoch die Daten kopieren muss.
lG Phili
>// hier soll jetzt das "Char-Array" eingefügt werden
6
>// und dann kommen noch weitere Bytes und Words ....
7
>};
8
>
>> Das klappt auch bis auf den String "NMEA2000_MFMODELID".
Das klappt auch mit dem Rest nicht.
Wenn du NMEA2000_NMEADATABASEVERSION auf uint8_t castest, wird der Rest
(obere 8 Bits) abgeschnitten und du hast nen falschen Wert drin.
Hallo Sven,
danke für Deine Antwort.
>> Das klappt auch bis auf den String "NMEA2000_MFMODELID".> Das klappt auch mit dem Rest nicht.>> Wenn du NMEA2000_NMEADATABASEVERSION auf uint8_t castest, wird der Rest> (obere 8 Bits) abgeschnitten und du hast nen falschen Wert drin.
Mein System erwartet die Daten im Little-Endian Format. Somit müssen die
Daten für das Byte 0 abgeschnitten werden. Für Byte 1 wird geeignet
geshiftet.
Hast Du eine Idee für den String?
Geht das überhaupt so?
Phili
Da wäre ich vorsichtig, die Schieberei und so wird m.W.n. arithmetisch
durchgeführt. Schreibs lieber explizit dazu.
Ein Stringliteral à la "blablabla" zerfällt normalerweise in einen
Zeiger. Lediglich im Kontext einer Vektorinitialisierung zerfällts in
einzelne Zeichen:
1
charvektor[]="abc";
Ich wüsste jetzt nicht, wie man dein Problem ohne gescheite Strukturen
so lösen könnte :-(
ach und noch ein Tipp:
falls die ID von Fall zu Fall unterschiedlich lang ist, kann
man auch einfach soviele \xFF zum Auffüllen nehmen, daß es
auch für eine kurze ID sicher reicht (also am sichersten 32 hier).
Das erzeugt dann zwar eine Warnung, ist sonst aber nicht weiter
schädlich.
Der Compiler weiß ja, daß das Feld nur 32 Byte hat und ignoriert
die überzähligen Bytes der Initialisierung.
Warum eigentlich mit 0xFF auffüllen?
Bei einem String wird laut C immer ein 0x00 angehängt.
Die Initialisierung eines character Feldes kann auch kürzer sein, nur
das abschließende 0x00 wird von C gebraucht.
Klaus Falser schrieb:
> Warum eigentlich mit 0xFF auffüllen?> Bei einem String wird laut C immer ein 0x00 angehängt.> Die Initialisierung eines character Feldes kann auch kürzer sein, nur> das abschließende 0x00 wird von C gebraucht.
Hallo Klaus,
die Daten werden über einen CAN-Bus versendet. Die Spezifikation des
verwendeten Protokolls erwartet, dass mit 0xFF aufgefüllt wird
Klaus Wachtler schrieb:
> ach und noch ein Tipp:>> falls die ID von Fall zu Fall unterschiedlich lang ist, kann> man auch einfach soviele \xFF zum Auffüllen nehmen, daß es> auch für eine kurze ID sicher reicht (also am sichersten 32 hier).>> Das erzeugt dann zwar eine Warnung, ist sonst aber nicht weiter> schädlich.>> Der Compiler weiß ja, daß das Feld nur 32 Byte hat und ignoriert> die überzähligen Bytes der Initialisierung.
Und noch eine weitere Anmerkung / Frage hierzu. Damit die Strings auch
im Flash landen, muss das folgende Vorgehen verfolgt werden:
Beitrag "[AVR-GCC] struct-Initialisierung. PROGMEM und Strings"
Da ich dann im Struct ja aber den Pointer habe, muss ich die Länge von
32 Byte direkt in der String-Definition vorgeben. Hier der aktuelle
Code-Ausschnitt
Und dann ergibt sich damit das Problem, dass ich auf die uints mit Hilfe
der "pgm_read_xxx"-Routinen zugreifen kann. Für die Strings benötige ich
aber "geschachtelte" "pgm_read_word" und "pgm_read_char" Routinen um
erst die Start-Adresse des Strings zu holen und dann den Inhalt lesen zu
können.
Ich meiner Implementation würde ich später aber gern nur mit "memcpy_P"
arbeiten und keine weiteren "i"-angängigen Entscheidungen treffen.
Hier ein Code-Ausschnitt.
Meine Frage ist also weiterhin:
Wie erhalte ich eine sequentielle Datenstruktur im Flash, die aus
unsigned Integers verschiedener Größe und mehreren Strings besteht, zur
Compilezeit zusammengebaut wird und später sukzessive mit Hilfe von
"memcpy_P" gelesen werden kann??
Danke noch einmal für alle bisherigen Vorschläge, Nachfragen und
Anregungen!!
Euer Phili