Forum: Compiler & IDEs Flash-Strings als Result ausgeben, nur wie?


von Josef K. (josefk)


Lesenswert?

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.

von Stefan E. (sternst)


Lesenswert?

Pack Pointer auf die Strings in ein Array, und verwende dann den 
Rückgabewert als Index für das Array.

von josefk(_nologin?) (Gast)


Lesenswert?

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 
:)

von Karl H. (kbuchegg)


Lesenswert?

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.

von josefk(_nologin?) (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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...";

von Torsten S. (tse)


Lesenswert?

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
Noch kein Account? Hier anmelden.