Hallo zuammen, ich versuche gerade einen guten Ansatz zu finden. Ich möchte gerne die results meiner Funktionen in einer art Errorbitmap (also ein Array von ints) speicher, was nicht so schwer ist. Außderdem möchte ich dann später auf diese Errorbitmap zugreifen und dann entsprechend einen Text, der im Flash liegt, ausgeben. Die Strings liegen im Flash, das Errorbitmap wird befüllt, aber wie schaffe ich es auf diese Strings analog zu meinen Resultwerten zuzugerifen. Also wenn ein Programm mir eine 5 zurück gibt will ich auf den 5ten String in einem Result-String-Array(oder ähnlichem) für diese Funktion zugreifen. Ich habe mir überlegt structs für jede Funktion anzulegen und dort dann die Pointer auf die Strings zu speichern, jedoch muss ich dann mit Punktoperatoren auf die Pointer zugreifen (z.B. errorcode1struct.result0) was mir später nur wieder Schreibarbeit bringt und nicht schön erweiterbar ist. Hat jemand eine Idee? Wenn jemand einen besseren Lösungsansatz weiß, würde ich mich darüber auch freuen.
Pack Pointer auf die Strings in ein Array, und verwende dann den Rückgabewert als Index für das Array.
Hmm, ok. Ich hab nur keine Ahnugn wie das geht. Ich würds so machen (natürlich ein bißchen integrierter ins Programm:) :
1 | //Strings
|
2 | const char checksum00[] PROGMEM = "keine Fehler"; |
3 | const char checksum01[] PROGMEM = "krasser Fehler"; |
4 | //...
|
5 | |
6 | //Struct für die Fehlerinformationen
|
7 | struct errorbitmap |
8 | {
|
9 | uint8_t function_checksum; |
10 | //...
|
11 | } resultvalues; |
12 | |
13 | //Pointer auf Strings in ein Array wobei ich hier nicht weiß wie das geht...
|
14 | PGM_P p_strings_flash[] = {checksum00, checksum01}; |
15 | |
16 | //Speicher als Buffer reservieren da ich das später brauchen werde
|
17 | char *p_errortext = malloc(50); |
18 | //Fehlerabfrage...
|
19 | |
20 | //entsprechenden Fehlertext kopieren
|
21 | PGM_P *pflash = p_string_flash[resultvalues.function_checksum]; |
22 | if(strlen_P(pflash) <= 50) |
23 | memcpy_P(p_errortext, pflash, strlen_P(pflash)); |
24 | //damit was machen....
|
Das ist sicher voll mit Fehlern, aber so sieht man hoffentlich was ich machen will. Nur wie macht man das richtig. Vor allem bei PGM_P hab ich goße Bedenken :)
josefk(_nologin?) wrote: > memcpy_P(p_errortext, pflash, strlen_P(pflash)); Benutze kein memcpy. memcpy nimmt man, wenn man Speicherbereiche umkopieren will, von denen man ausser der Länge nichts kennt. Du weißt aber noch was von einem String. Nämlich, dass er 0-terminiert ist. Und strcpy weiß das auch. Und sein Cousing strcpy_P sowie strncpy_P ebenfalls. > //Speicher als Buffer reservieren da ich das später brauchen werde > char *p_errortext = malloc(50); > //Fehlerabfrage... Naja. Der malloc ist hier so nicht unbedingt notwendig. Wenn du sowieso weißt das das immer 50 Zeichen sein werden, dann allokier das genz einfach so char errortext[50]; Dadurch brauchst du dich nicht darum zu kümmern, dass der Speicher auch wieder frei gegeben wird. > Das ist sicher voll mit Fehlern, aber so sieht man hoffentlich was ich > machen will. > Nur wie macht man das richtig. Vor allem bei PGM_P hab ich goße Bedenken > :) Im Grossen und Ganzen passt das schon. Ein bischen viele Aufrufe von strlen_P hast du da drinnen, aber ansonsten: Das Prinzip stimmt.
Hmm. Wie verteile ich denn am besten die Strings auf mein ganzes Programm? Ich hab momentan eine stringlib.h in der die Strings abgespeichert werden. Wenn ich diese stringlib nun in mein main.c einbinde, kann ich von dort auf die Strings zugreifen. Wenn ich danach diese lib noch in eine ander C-Datei includiere, kann ich das nicht mehr, da ich ja logischerweise meine Strings nicht nocheinmal anlegen kann/will. Ich will aber darauf zugreifen. Wie mache ich das?
1 | //stringlib.h Beispiel
|
2 | #ifndef STRINGLIB_H_
|
3 | #define STRINGLIB_H_
|
4 | |
5 | #include <avr/pgmspace.h> |
6 | |
7 | static const char device_start[] PROGMEM = "Initalisiere Schaltung:"; |
8 | static const char spi_start[] PROGMEM = "Aktiviere SPI..."; |
9 | static const char sdparser_start[] PROGMEM = "SD Parser starten..."; |
10 | static const char eth_status_ports[] PROGMEM = "Ports geöffnet..."; |
11 | #endif
|
josefk(_nologin?) wrote:
> will aber darauf zugreifen. Wie mache ich das?
So wie bei jeder anderen Resource auch, die es in einem
Programm nur 1-mal geben darf:
Du verfrachtest diese Resource in ein *.c File, welches kompiliert
wird und du schreibst ein Header File, welches den Rest des Programmes
darüber informiert, dass diese Resource verfügbar ist.
Texte, die im Flash stehen sind da keine Ausnahme
StringLib.h
***********
1 | #ifndef STRINGLIB_H_
|
2 | #define STRINGLIB_H_
|
3 | |
4 | #include <avr/pgmspace.h> |
5 | |
6 | extern const char device_start[] PROGMEM; |
7 | extern const char spi_start[] PROGMEM; |
8 | extern const char sdparser_start[] PROGMEM; |
9 | extern const char eth_status_ports[] PROGMEM; |
10 | |
11 | #endif
|
StringLib.c ***********
1 | #include "StringLib.h" |
2 | |
3 | const char device_start[] PROGMEM = "Initalisiere Schaltung:"; |
4 | const char spi_start[] PROGMEM = "Aktiviere SPI..."; |
5 | const char sdparser_start[] PROGMEM = "SD Parser starten..."; |
6 | const char eth_status_ports[] PROGMEM = "Ports geöffnet..."; |
Ein ähnliches Problem habe (hatte) ich auch seit längeren und noch nie eine anständige Lösung gefunden. Mir ging es darum, Strings die mehrfach verwendet werden, zentral zu verwalten um mein Proggi wartungsfreundlicher zu machen. Nun weiß ich endlich was zu tun ist. Ein großes Dankeschön an Karl Heinz!
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.