Bauplan 512-Byte-Array

#1679976
Lesenswert?

Hallo

ich will mir eine Art Datenlogger bauen, der Daten auf eine SD-Karte 
speichert.
Von der Karte bekomme ich immer 512 Bytes in Form eines Arrays.
Nun will ich am Anfang des Codes sozusagen den Bauplan eines Logs (bspw. 
benötigt ein Log 20 Bytes; 0-5: Zeit, 6-15: Ort, 16-19: Information)
festlegen. Diese einzelnen Logs sind nacheinander in den 512 Bytes zu 
finden.
Das Programm soll nun nach übergabe der Startposition im 512-Byte-Array 
den Log entschlüssen, also dass man dann auf die einzelnen Attribute 
zugreifen kann.

Ich hätte an einen Struct gedacht, aber ich weiß nicht, wie man dem dann 
die Daten übergibt.


Gruß
Richi
#1679998
Lesenswert?

Richard W. schrieb:

> Nun will ich am Anfang des Codes sozusagen den Bauplan eines Logs (bspw.
> benötigt ein Log 20 Bytes; 0-5: Zeit, 6-15: Ort, 16-19: Information)
> festlegen.

Hier muss ich nachhaken.
Ist dieser Aufbau fix oder kann sich der verändern?

> Diese einzelnen Logs sind nacheinander in den 512 Bytes zu
> finden.
> Das Programm soll nun nach übergabe der Startposition im 512-Byte-Array
> den Log entschlüssen, also dass man dann auf die einzelnen Attribute
> zugreifen kann.
>
> Ich hätte an einen Struct gedacht, aber ich weiß nicht, wie man dem dann
> die Daten übergibt.

Indem du die Einzelteile an die Member zuweist. Ein struct ist in diesem 
Sinne nichts anderes als mehrere Einzelvariablen, die unter einem 
Überbegriff zusammengefasst werden. Mit den Membern arbeitet man ganz 
genau so, wie man es auch tun würde, wenn die Varablen einzeln da 
stünden.
1
struct Datum {
2
  uint8_t  Tag;
3
  uint8_t  Monat;
4
  uint16_t Jahr;
5
  char     Wochentag[10];
6
};
7

8
int main()
9
{
10
  struct Datum Geburtstag;
11

12
  Geburtstag.Tag   = 22;
13
  Geburtstag.Monat = 3;
14
  Geburtstag.Jahr  = 1963;
15

16
  strcpy( Geburtstag.Wochentag, "Sonntag" );
17
}

Da verändert sich nichts, ausser dass die einzelnen Teile unter einem 
Überbegriff zusammengefasst sind, also in eine Art Container verpackt 
sind und dieser Container als ganzes an Funktionen übergeben werden kann 
oder in einem Rutsch kopiert werden kann.
#1680057
Lesenswert?

Ja, der Aufbau ist Variabel.

Was ich eigentlich wissen will ist wie man das mit dem Übergeben macht, 
also ich sag der Funktion die Länge des Logs und die Startposition und 
dann Kopiert die Byte1 aus dem 512-Byte_Array nach Struct.Byte1 ...

Also ohne zu wissen was da in dem Struct steht.

Hoffe es ist verständlich?!?


Gruß
Richi
#1680085
Lesenswert?

Richard W. schrieb:
> Ja, der Aufbau ist Variabel.
>
> Was ich eigentlich wissen will ist wie man das mit dem Übergeben macht,
> also ich sag der Funktion die Länge des Logs und die Startposition und
> dann Kopiert die Byte1 aus dem 512-Byte_Array nach Struct.Byte1 ...
>
> Also ohne zu wissen was da in dem Struct steht.

Das geht nicht.
Den Aufbau des Ziels musst du schon kennen. Zumindest in groben Zügen.

Aber dein LOG wird ja wahrscheinlich immer denselben Aufbau haben, oder? 
Zuerst Zeit, dann Ort, dann Logtext.
Man kann zb den Logtext variabel lang gestalten mittels dynamischer 
Allokierung. Aber eigentlich möchte man in einem µC gerade das 
vermeiden.
#1680106
Lesenswert?

Richard W. schrieb:
> Nein, vielleicht hast du mich falsch verstanden.

Das kann schon sein.

> Pro Mic eine Logart, da ich verschiedene Sachen loggen möchte und
> deshalb auch verschiedene Parameter brauche.

Dann würde ich mir als erstes Gedanken darüber machen, ein gemeinsames 
Log-Format zu bekommen, in dem alle möglichen Logs dargestellt werden 
können.

Das wird dann der Aufbau der struct.

Beim Einlesen der SD Karte wird festgestellt, welche Daten vorhanden 
sind, und die entsprechenden Member der globalen Log-Struktur befüllt.

Oder hab ich dich wieder missverstanden?

(In dem Fall würde ich dich bitten einfach mal konkret ein oder 2 Logs 
herzuzeigen und auch wie das Ergebnis aussehen soll)
#1680121
Lesenswert?

Der Aufbau der Logs is ja eigentlich egal.

Es geht mir nur darum den Log auf die SD-Karte zu schreiben, wobei auf 
einer Seite der Karte mehrere Logs abgespeichert sind.

Ich will also wiisen, wie man einen Struct Byteweise kopiert, also ohne 
dass man die interne Aufteilung des Structs kennen muss.
#1680131
Lesenswert?

Richard W. schrieb:

> Ich will also wiisen, wie man einen Struct Byteweise kopiert, also ohne
> dass man die interne Aufteilung des Structs kennen muss.

Irgendetwas von der struct musst du kennen und sei es nur die komplette 
Größe.

memcpy( ziel, quelle, sizeof(quelle) );

oder mit einer klassischen for Schleife

dazu castest du dir die Startadresse der struct um in einen Bytepointer 
und das wars dann schon.
1
void WriteToSD( uint8_t * Bytes, size_t length )
2
{
3
  size_t i;
4

5
  for( i = 0; i < length; ++i )
6
    WriteByte( Bytes[i] );
7
}
8

9
int main()
10
{
11
  struct irgendwas Daten;
12

13
  ....
14

15
  WriteToSD( (uint8_t*)&Daten, sizeof( Daten ) );
16
}

Oder reden wir jetzt immer noch aneinander vorbei?
#1684361
Lesenswert?

Hallo

melde mich nochmal.

Wie gesagt krieg ich ja ein 512-Byre-Array von der SD-Karte geliefert, 
oder muss ihr ein solches liefern.

Nun ist mir aufgefallen, dass, wie ich es bisher gemacht habe, nämlich 
den Teil aus dem Array in den Struct zu kopiere, dort zu bearbeiten, 
dann wieder zurückkopieren etwas aufwändig ist.

Könnte man es nicht so machen, dass man den Struct irgendwie als Zeiger 
deklariert, der dann auf die Startposition der Daten im Array zeigt, und 
dass ich dann somit die Daten nicht kopieren müsste?

Ich weiß nicht, was genau ich beim Struct dann alles als Zeiger 
deklarieren muss.


Gruß
Richi
#1686929
Lesenswert?

Richard W. schrieb:
> Könnte man es nicht so machen, dass man den Struct irgendwie als Zeiger
> deklariert, der dann auf die Startposition der Daten im Array zeigt, und
> dass ich dann somit die Daten nicht kopieren müsste?

Das geht auf PCs sowohl unter Windows als auch Unix-ähnlichen
Systemen (Stichwort "memory mapped file").
Dazu ist eine virtuelle Speicherverwaltung nötig.

Auf Controllern musst du darauf wohl verzichten.
#1687208
Lesenswert?

Richard W. schrieb:
> Könnte man es nicht so machen, dass man den Struct irgendwie als Zeiger
> deklariert, der dann auf die Startposition der Daten im Array zeigt, und
> dass ich dann somit die Daten nicht kopieren müsste?

Wenn du mit "Daten im Array" einen Buffer meinst, in den du den Sektor 
von der Karte gelesen hat, kein Problem.
1
uint8_t buffer[512];
2
struct log_entry *entry = (struct log_entry *)&buffer[42];

entry zeigt jetzt auf einen Logeintrag, der beim 43. Byte im Buffer 
anfängt.

Virtuelle Speicherverwaltung ist dafür natürlich nicht nötig.

Andreas
#1687209
Lesenswert?

Andreas Ferber schrieb:
> Virtuelle Speicherverwaltung ist dafür natürlich nicht nötig.


Meine Aussage bezog sich auf die Frage:

Richard W. schrieb:
> Könnte man es nicht so machen, dass man den Struct irgendwie als Zeiger
> deklariert, der dann auf die Startposition der Daten im Array zeigt, und
> dass ich dann somit die Daten nicht kopieren müsste?

Also ohne in einen Puffer und wieder zurück kopieren zu müssen.
#1687233
Lesenswert?

Klaus Wachtler schrieb:
> Also ohne in einen Puffer und wieder zurück kopieren zu müssen.

Ich habe dich schon verstanden, ich glaube nur, der OP meinte eben nicht 
das was du meinst ;-)

Da er offensichtlich mit C und Speicherverwaltung noch nicht soviel 
Erfahrung hat, wollte ich nochmal explizit darauf hinweisen, dass bei 
meiner Lösung kein virtueller Speicher nötig ist.

Andreas
#1688623
Lesenswert?

Hallo

am Wochenende hab ich jetzt den Code neu umgebaut, also nach dem 
Zeigerschema.
Jetzt kommt aber beim Kompilieren immer folgende Meldung:

error: request for member 'Minute' in something not a structure or union

Ich greife auf das Objekt Minute so zu:

Log.Minute = ...

Mit dem * davor gehts auch nicht.


Weiß jemand eine Lösung?


Gruß
Richi
#1688657
Lesenswert?

Richard W. schrieb:
> Danke, genau das wars.

Dann gewinnt eine Aussage von weiter oben noch mehr Gewicht:
Du brauchst Literatur!

Das ist ein Trivialfehler, den du nicht gemacht hättest, wenn du die 
Einführungskapitel in deinem nicht vorhandenen Buch über Strukturen und 
Pointer durchgearbeitet hättest. Hättest du ein C-Buch (egal welches) 
durchgearbeitet, dann wäre dir die Verwendung von * und -> im jeweiligen 
Kontext in Fleisch und Blut übergegangen.
#1688865
Lesenswert?

Richard W. schrieb:
> also woher kann ich dann ahnen,

Genau darum geht es.
Du musst das gar nicht ahnen. Das steht in JEDEM C-Buch drinnen.

Das und noch viel, viel mehr was du zur Zeit noch nicht weißt und 
'ahnen' musst. Wenn du lesen würdest, musst du nicht raten oder ahnen.

Du verhältst dich wie jemand, der in einer fremden Stadt Taxifahrer 
werden will, aber aus irgendwelchen Gründen den Ankauf eines Stadtplans 
verweigert. Statt dessen schlägst du dich durch, indem du an jeder 
Kreuzung Passanten nach dem Weg fragst.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren