www.mikrocontroller.net

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


Autor: Josef Kaeufl (josefk)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Ernst (sternst)
Datum:

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

Autor: josefk(_nologin?) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, ok. Ich hab nur keine Ahnugn wie das geht. Ich würds so machen 
(natürlich ein bißchen integrierter ins Programm:) :
//Strings
const char checksum00[] PROGMEM = "keine Fehler";
const char checksum01[] PROGMEM = "krasser Fehler";
//...

//Struct für die Fehlerinformationen
struct errorbitmap
{
 uint8_t  function_checksum;
 //...
} resultvalues;

//Pointer auf Strings in ein Array wobei ich hier nicht weiß wie das geht...
PGM_P p_strings_flash[] = {checksum00, checksum01};

//Speicher als Buffer reservieren da ich das später brauchen werde
char *p_errortext = malloc(50);
//Fehlerabfrage...

//entsprechenden Fehlertext kopieren
PGM_P *pflash = p_string_flash[resultvalues.function_checksum];
if(strlen_P(pflash) <= 50)
   memcpy_P(p_errortext, pflash, strlen_P(pflash));
//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 
:)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: josefk(_nologin?) (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?
//stringlib.h Beispiel
#ifndef STRINGLIB_H_
#define STRINGLIB_H_

#include <avr/pgmspace.h>

static const char device_start[] PROGMEM = "Initalisiere Schaltung:";
static const char spi_start[] PROGMEM = "Aktiviere SPI...";
static const char sdparser_start[] PROGMEM = "SD Parser starten...";
static const char eth_status_ports[] PROGMEM = "Ports geöffnet...";
#endif

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
***********
#ifndef STRINGLIB_H_
#define STRINGLIB_H_
 
#include <avr/pgmspace.h>
 
extern const char device_start[] PROGMEM;
extern const char spi_start[] PROGMEM;
extern const char sdparser_start[] PROGMEM;
extern const char eth_status_ports[] PROGMEM;

#endif

StringLib.c
***********
#include "StringLib.h"
 
const char device_start[] PROGMEM = "Initalisiere Schaltung:";
const char spi_start[] PROGMEM = "Aktiviere SPI...";
const char sdparser_start[] PROGMEM = "SD Parser starten...";
const char eth_status_ports[] PROGMEM = "Ports geöffnet...";

Autor: Torsten S. (tse)
Datum:

Bewertung
0 lesenswert
nicht 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!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.