mikrocontroller.net

Forum: Compiler & IDEs Array kopieren / zuweisen


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe ein paar Codesequenzen vorgegeben und entscheide mich durch 
Eingabe verschiedener Tasten für einen der Codes. Dazu will ich das 
komplette Array in ein Arbeitsarray kopieren:

In Code:
static unsigned char code[] = {0,1,0,1};
static unsigned char arbeitsArray[4] = {};
if(codeNumber == 1)
{
arbeitsArray[] = code[]; // geht nicht: error: expected expression before ']' token

arbeitsArray = code; //geht leider auch nicht: error: incompatible types in assignment
}

wie schreibt man das richtig, oder kann man das so garnicht machen?

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
memcpy(arbeitsArray,  code, sizeof arbeitsArray);

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also prinzipiell gehts natürlich auch via:
unsigned int i;
for(i=0; i<sizeof(code);i++)
{
arbeitsArray[i] = code[i];
}

aber gehts auch einfacher, also dass das Programm das nicht immer mühsam 
machen muss?
Pointer?

Prinzipiell gehts einfach darum, später mit dem ausgewählten Code 
weiterzuarbeiten, dafür ist das arbeitsArray, worauf ich dann alle 
möglichen operationen loslasse, das ursprüngliche array möchte ich nicht 
verändern wenn möglich.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Uhu Uhuhu. Warst schneller mitm schreiben als ich mitm abschicken 
des Nachtrags.

Wo findet man denn den Code zu memcpy()? Den Header hab ich dazu 
gefunden im WinAVR Verzeichnis. Also string.h, aber wo ist denn string.c 
? bzw. die eigentliche Implementierung?

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In der Runtimelibrary, wenn sie nicht vom Compiler als Intrinsic direkt 
eingebaut wird.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wo findet man denn den Code zu memcpy()?

Wozu brauchst du den denn?

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hätt ihn mir mal angesehn, ob vielleicht die forschleife drinsteht 
=) oder eben wie sies schlau gelöst hätten.

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

Bewertung
0 lesenswert
nicht lesenswert
Thomas wrote:
> Ich hätt ihn mir mal angesehn, ob vielleicht die forschleife drinsteht
> =) oder eben wie sies schlau gelöst hätten.

for Schleife ist durchaus möglich.

oft wird aber beim Umkopieren auf grössere Einheiten gewechselt
(2 Byte, 4 Byte, ...) um den Schleifen Overhead gegenüber der
Kopierleistung in einem Schleifendurchlauf zu verringern.

Dein Stichwort im Web lautet: Duff's device

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gerade so Sachen wie memcpy profitieren oft stark von Optimierungen. 
Daher ist es immer je nach Prozessor sehr unterschiedlich implementiert. 
So hat z.B. der x86 Stream-Befehle, die ein Kopieren eines ganzen 
Speicherblocks mit einer einzigen Assembleranweisung (+ Setup davor 
natürlich) durchführen können, aber alternativ läßt sich auch die SSE 
dazu verwenden, die den Vorteil hat, daß ein Register 128 Bit breit ist. 
Beim ARM gibt es die Möglichkeit, einen kleinen Speicherblock in mehrere 
Register auf einmal mit einer einzigen Instruktion zu laden und mit 
einer weiteren wieder rauszuschreiben. Andere Systeme können vielleicht 
sogar DMA dazu verwenden.
Oft hängt es auch noch von den Parametern ab (z.B. wenn die Größe des zu 
kopierenden Blocks eine Compilezeit-Konstante ist). Deshalb wird - wie 
schon angedeutet von Uhu - die Funktion (zumindest bei gcc) schon im 
Compiler selbst fest eingebaut, was ihm die besten 
Optimierungsmöglichkeiten gibt.

Die for-Schleife ist die einfachste Variante, die immer funktioniert, 
aber je nach Prozessor eben deutlich langsamer sein kann, als eine 
speziell zugeschnittene Version. Es kann aber umgekehrt sogar auch 
passieren, daß der Compiler den Zweck der Schleife erkennt und diese 
dann wieder durch einen memcpy-Aufruf ersetzt.

Autor: Icke Muster (Firma: my-solution) (hendi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hänge meine Frage mal hier an. Gibt es eine Möglichkeit einen Vektor 
anzulegen, bei dem man erst während der Laufzeit weiß wie groß er ist? 
Ich möchte die Daten meines Ethernetcontrollers auslesen, die sind aber 
natürlich immer unterschiedlich lang, je nach dem was ich sende. Oder 
muss ich mir dann während der Laufzeit Speicher allocieren?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Icke Muster (Firma my-solution) (hendi)

>Ich hänge meine Frage mal hier an. Gibt es eine Möglichkeit einen Vektor
>anzulegen, bei dem man erst während der Laufzeit weiß wie groß er ist?

Nein.

>muss ich mir dann während der Laufzeit Speicher allocieren?

Ja.

MfG
Falk

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da ein EthernetPaket maximal ~1,5kB groß sein kann, kannst du auch fest 
1,5kB statisch allokieren.

Autor: Icke Muster (Firma: my-solution) (hendi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay, ich hab mich falsch ausgedrückt, ich hätte gern die Nutzdaten, in 
dem Fall HTTP, zur weiteren Verwendung aneinanderhängend. Ich würde die 
also gern  aus den jeweiligen Päckchen extrahieren und dann weiter 
verwenden. vielleicht macht das auch keinen Sinn und ich sollte sie 
gleich parsen, aber ich hab halt Angst zwischendurch daten zu verlieren 
und würde gern alles, was gerade gesendet wurde erst mal speichern. Ich 
werd mir das einfach mal ansehen, irgendwann muss ich mich ja mal mit 
malloc beschäftigen, hätte es nur gern aufgeschoben...

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du C++ nimmst, kannst du eine Stringklasse verwenden, die die 
Speicherverwaltung im Hintergrund miterledigt.

Auf den üblichen µCs würde ich das aber nicht machen...

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Icke Muster wrote:
> Okay, ich hab mich falsch ausgedrückt, ich hätte gern die Nutzdaten, in
> dem Fall HTTP, zur weiteren Verwendung aneinanderhängend. Ich würde die
> also gern  aus den jeweiligen Päckchen extrahieren und dann weiter
> verwenden. vielleicht macht das auch keinen Sinn und ich sollte sie
> gleich parsen, aber ich hab halt Angst zwischendurch daten zu verlieren
> und würde gern alles, was gerade gesendet wurde erst mal speichern. Ich
> werd mir das einfach mal ansehen, irgendwann muss ich mich ja mal mit
> malloc beschäftigen, hätte es nur gern aufgeschoben...

Der HTTP Teil eines TCP Pakets beginnt doch nach einem definierten 
Speicher-Offset. Da brauchst du nicht extra den Teil in einen anderen 
Speicher extrahieren. Das wäre zuviel des guten. Du gibst deiner 
HTTP-Funktion einfach einen Zeiger, der einen bestimmten Offset von der 
Start-Adresse des Ethernet-Buffers hat. (Den Offset muss man natürlich 
berechnen).

Autor: Icke Muster (Firma: my-solution) (hendi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem ist, dass ich genau diesen Http Inhalt noch weiter verwenden 
möchte und wenn ich ein paar Daten mit POST z.B. übertrage, dann kommen 
die fragmentiert an und die würd ich gern zusammensetzen, oder ist das 
Quatsch? Ich dachte halt, das man danach einfacher damit arbeiten 
könnte, beim parsen.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, das macht Sinn :-) Allerdings nur auf Controllern mit relativ viel 
Speicher...

Auf nem kleinen AVR 8-Bit würde ich auf sowas verzichten.

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.