Hallo, ich habe mal eine Frage bei der ich nicht weiß ob sie schonmal gestellt worden ist (die Suche hat jedenfalls nix ergeben). Ich möchte in einem Byte-Array (unsigned char) Zahlenwerte sowie Zeichenketten mischen können. also sowas : unsigned char data[] PROGMEM = { 23, 45, 23, "test", 12, 45, 87, 23, 0, 0, 0, 0, "write", "bla bla bla", 0, 6, 4, 43, 43, }; geht das ? ich kann keine strukturen definieren (können schon, aber nicht in dem zusammenhang), da ich einen reinen byte-stream zur compilezeit erzeugen möchte, der dann zur laufzeit abgearbeitet wird. zur not würde es auch reichen (obwohl ich das unschön fände) wenn ich den string an anderer stelle definiere, und den zeiger auf diesen string (geteilt in hi und lo byte) im array einfüge. die zeigeroperation in dem byte-stream werde ich wahrscheinlich ohnehin benötigen, aber den text würde ich gerne so (dann natülich mit null-terminierung) in dem datenstrom unterbringen.
Nein, geht leider nicht. Deine String-Literale zerfallen in diesem Kontext zu Zeigern, d.h. im Vektor landet allenfalls ein Stück dieses Zeigers (auf char abgeschnitten).
hab ich den wenigstens die möglichkeit aus dem zeiger zwei einzelne bytes zu machen die sich dann in dem byte-strom einfügen lassen oder lässt c das ebenfalls nicht zu ?!
TheMason schrieb: > Hallo, > > ich habe mal eine Frage bei der ich nicht weiß ob sie schonmal gestellt > worden ist (die Suche hat jedenfalls nix ergeben). > Ich möchte in einem Byte-Array (unsigned char) Zahlenwerte sowie > Zeichenketten mischen können. also sowas : > > unsigned char data[] PROGMEM = { 23, 45, 23, "test", 12, 45, 87, 23, 0, > 0, 0, 0, "write", "bla bla bla", 0, 6, 4, 43, 43, }; > > geht das ? > Sowas?
1 | #include <avr/pgmspace.h> |
2 | |
3 | const char data[] PROGMEM = "\027\055\027" "Hallo" "\010\000\001\033"; |
Beachte, daß in dem Falle "Hallo" nicht von einer '\0' gefolgt wird, aber am Ende von data immer eine Null steht wie bei Strings üblich. Endet data mit "\000", denn wir auch danach ein '\0' eingefügt. Wenn du "test" als null-terminierten String brauchst, kannst du data auch als Union definieren, die eine Struktur mit einem const char[] überlagern (vermeidet type-punning, oder als Struktur und dann casten).
1 | #include <avr/pgmspace.h> |
2 | |
3 | const char data[] PROGMEM = "\027\055\027" "Hallo" "\010\000\033"; |
4 | |
5 | const union |
6 | {
|
7 | struct
|
8 | {
|
9 | uint8_t a; |
10 | uint8_t b; |
11 | uint8_t c; |
12 | char d[5]; |
13 | uint8_t e; |
14 | } bytes; |
15 | |
16 | const unsigned char asCharArray[0]; |
17 | } data2 PROGMEM = |
18 | {
|
19 | .bytes = |
20 | {
|
21 | .a = 23, |
22 | .b = 45, |
23 | .c = 23, |
24 | .d = "test", |
25 | .e = 12 |
26 | }
|
27 | };
|
28 | |
29 | char foo (void) |
30 | {
|
31 | return pgm_read_byte (&data[5]) + pgm_read_byte (& data2.asCharArray[5]); |
32 | }
|
Oder oben hinter dem "Hallo" explizit ne Null einfügen. Johann
@johann die möglichkeit die bytes per \ in einen string einzufügen hatte ich total vergessen. danke fürs nochmal-dran-erinnern ;-) ich habs zwar zwischenzeitlich was anders gelöst (habe einfach text-indizes definiert, die dann als byte in dem datenstrom stehen) aber ich halte mir die möglichkeit mal im hinterkopf. die idee mit den strukturen würde auch gehen, aber ich würd ganz gerne meinen byte-stream per präprozessor generieren (und dann über defines die einzelnen bytes mit werten besetzen), von daher scheidet die möglichkeit aus. aber da vllt nochmal die frage zu der geschichte mit dem zeiger aufspalten. geht das überhaupt ? sprich das ich einen zeiger in high und low-byte aufspalten kann und diesen im bytestream einfügen kann ? ich meine letztenendes ist es ja nur ein platzhalter der erst nach dem linken eintragen werden kann, aber eigentlich sollte das doch nicht so schwierig sein ... ich meine selbst wenn das nicht geht würde, könnte ich mir immer noch ein pointer-array deklarieren und dann per byte index im bytestream darauf zurückgreifen, aber es wäre schon komfortabler.
TheMason schrieb: > aber da vllt nochmal die frage zu der geschichte mit dem zeiger > aufspalten. geht das überhaupt ? sprich das ich einen zeiger in high und > low-byte aufspalten kann und diesen im bytestream einfügen kann ? ich > meine letztenendes ist es ja nur ein platzhalter der erst nach dem > linken eintragen werden kann, aber eigentlich sollte das doch nicht so > schwierig sein ... In C sehe ich die Möglichkeit nur mittels Komposit. Aber warum denn nicht sowas?
1 | #include <avr/pgmspace.h> |
2 | |
3 | #define STRINGIFY(X) #X
|
4 | #define WERT1 STRINGIFY(42)
|
5 | #define SIZE STRINGIFY(12)
|
6 | #define TEXT "test"
|
7 | |
8 | extern int i; |
9 | |
10 | #define CR "\n"
|
11 | asm ( |
12 | ".global data" CR |
13 | " .section .progmem.data,\"a\",@progbits" CR |
14 | " .type data, @object" CR |
15 | " .size data, " SIZE CR |
16 | "data:" CR |
17 | " .byte 0x23-3" CR |
18 | " .string \"" TEXT "\"" CR |
19 | " .byte " WERT1 CR |
20 | " .word i" CR |
21 | );
|
22 | |
23 | extern const char data[]; |
24 | |
25 | char foo (void) |
26 | {
|
27 | return pgm_read_byte (& data[5]); |
28 | }
|
Oder gleich ein Assembler-Modul, das ist lesbarer und kein Hexenwerk. Auch dort kannst du den C-Präprozessor verwenden, Dateien includen und hast eine mächtige Makro-Maschinerie von gas. Ausserdem spart's die lästigen ". Mich dünkt aber, du wählst irgendwie den falschen Ansatz. Johann
TheMason schrieb: > aber da vllt nochmal die frage zu der geschichte mit dem zeiger > aufspalten. geht das überhaupt ? sprich das ich einen zeiger in high und > low-byte aufspalten kann und diesen im bytestream einfügen kann ? ich > meine letztenendes ist es ja nur ein platzhalter der erst nach dem > linken eintragen werden kann, aber eigentlich sollte das doch nicht so > schwierig sein ... An sich geht das schon, C definiert, dass ein Zeiger mit einer (unbekannten, d.h. frei vom Compiler/... festzulegenden) Abbildungsfunktion in eine Ganzzahl gewandelt werden kann und zurück. Es ist aber wimre auch nicht festgelegt, wie breit diese Ganzzahl dann sein soll. Bitte im Standard nachlesen!
Sven P. schrieb: > TheMason schrieb: >> aber da vllt nochmal die frage zu der geschichte mit dem zeiger >> aufspalten. geht das überhaupt ? sprich das ich einen zeiger in high und >> low-byte aufspalten kann und diesen im bytestream einfügen kann ? ich >> meine letztenendes ist es ja nur ein platzhalter der erst nach dem >> linken eintragen werden kann, aber eigentlich sollte das doch nicht so >> schwierig sein ... > > An sich geht das schon, C definiert, dass ein Zeiger mit einer > (unbekannten, d.h. frei vom Compiler/... festzulegenden) > Abbildungsfunktion in eine Ganzzahl gewandelt werden kann und zurück. > Es ist aber wimre auch nicht festgelegt, wie breit diese Ganzzahl dann > sein soll. Bitte im Standard nachlesen! Ich sehe aber nicht, wie man so ein Zeiger in den Vytestream reinbekommen könnte in C. Es müssen ja passende Relocs erzeugt werden, die der Linker dann auflöst. Die Werte von Symbolen sind einem C-Compiler ja nicht bekannt. Johann
@johann >Oder gleich ein Assembler-Modul, das ist lesbarer und kein Hexenwerk. >Auch dort kannst du den C-Präprozessor verwenden, Dateien includen und >hast eine mächtige Makro-Maschinerie von gas. Ausserdem spart's die >lästigen ". >Mich dünkt aber, du wählst irgendwie den falschen Ansatz. die idee mit dem assembler modul werde ich evtl weiter verfolgen. habe das problem aber zwischenzeitlich anders gelöst. es geht sich dabei um folgendes : ich bin dabei eine gui zu programmieren. um die sache platzsparend zu machen verwende ich einen bytestream. das erste byte gibt den befehl an, und danach folgen roh-daten die je nach befehl interpretiert werden. ich habe befehle für pixel setzen, vertikale/horizontale linie und eben text-ausgabe. nun wäre es bei der text ausgabe eben schön gewesen den text (nullterminiert) direkt in den bytestrom einzufügen. das ich das wohl nur mit einem assembler-modul machen kann lässt wohl nicht vermeiden. um mir die sache in c dennoch (über einen umweg) zu lösen, definiere ich die texte an anderer stelle und arbeite nur noch mit indizes. hat den vorteil das ich wiederkehrende texte nur über 1 byte darstellen kann und nicht jeweils immer den kompletten text im bytestrom habe. nachteil ist halt der das ich texte die nur einmal benötigt werden etwas mehr platz brauchen (um genau zu sein jeweils 2 byte, ein zeiger halt). ein weiterer nachteil (wobei es sich bei genauerer betrachtung eigentlich nicht vermeiden lässt) wäre wenn ich die befehle aus dem ram ausführen möchte (dynamisch) und die texte nicht im flash definiert sind, wobei das da wahrscheinlich nicht wirklich zum tragen kommt, da ich die texte dann eh von außen (z.b. uart) geliefert bekomme und dann eben nicht in c fest kompiliert vorliegen haben muß, und ich so den text direkt im byte-daten-strom unterbringen kann (da dieser byte-strom dann ja von außen kommt). ich hoffe ich hab das nicht zu umständlich erklärt ;-) die geschichte mit dem pointer-im-byte-stream hab ich verworfen da es in dem zusammenhang keinen sinn machte. ich wollte mir die möglichkeit offenhalten z.b. zeiger auf kurvenzüge, bitmaps zu ermöglichen, wobei ich bei verwendung des flashs auch den weg über indizes (und dahinterliegende zeigertabellen) nutzen kann und damit eben auch eine wiederverwendungsmöglichkeit habe. beim ram funktioniert das mit den zeigern allerdings dann nicht. trotzdem danke nochmal für die mühe.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.