Forum: Mikrocontroller und Digitale Elektronik Mapping von uint32_t auf atmega328


von Gustav G. (gustavgggg)


Lesenswert?

Ich kämpfe gerade auf einem atmega328 um jedes bisschen 
Laufzeitverkürzung beim übertragen von 32bit werten über SPI. Bisher 
mache ich es so, dass immer geschoben wird. Ich würde etwas gewinnen 
einfach nur bytes eines uin32_t in ein uint8_t array kopieren zu können. 
Meine Frage zielt darauf ab wie sicher das ist und ob garantiert ist, 
dass &wert immer auf das erste byte des uint32_t Speichers zeigt? Also 
kann ich mich darauf verlassen, dass ich bei memcpy immer richtig liege 
und nur endianess beim senden beachten muss?

von Falk B. (falk)


Lesenswert?

Gustav G. schrieb:
> Meine Frage zielt darauf ab wie sicher das ist und ob garantiert ist,
> dass &wert immer auf das erste byte des uint32_t Speichers zeigt?

Wenn du mit "erste" das niederwertigste meinst, dann ja. Denn die 
meisten (alle?) C Compiler für den AVR arbeiten mit little endian.

> Also
> kann ich mich darauf verlassen, dass ich bei memcpy immer richtig liege
> und nur endianess beim senden beachten muss?

Ja.

von Gustav G. (gustavgggg)


Lesenswert?

Falk B. schrieb:
> Wenn du mit "erste" das niederwertigste meinst, dann ja. Denn die
> meisten (alle?) C Compiler für den AVR arbeiten mit little endian.

Das meine ich aber das ist am Ende nur eine Frage aus Welcher Richtung 
ich das Zielarray beim senden iteriere.

von Harald K. (kirnbichler)


Lesenswert?

Gustav G. schrieb:
> und ob garantiert ist, dass &wert immer auf das
> erste byte des uint32_t Speichers zeigt?

Was für ein Wirkmechanismus sollte dafür sorgen können, daß das nicht 
der Fall ist (wenn man sich der Bedeutung von "endianness" bewusst ist)?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Gustav G. schrieb:
> Ich kämpfe gerade auf einem atmega328 um jedes bisschen
> Laufzeitverkürzung beim übertragen von 32bit werten über SPI.

Wenn es hardware-SPI ist. würd ich garnicht über die Bytes "iterieren", 
sondern die Schleife über die 4 Bytes von Hand abrollen.

Außerdem sieht man oft Code wie folgenden:
1
void spi_send (uint8_t data)
2
{
3
    SPDR = data;
4
    loop_until_bit_is_set (SPSR, SPIF);
5
}
wo tot gewartet wird (und SPI ist oft so fix, dass sich IRQs nicht 
lohnen).

Stattdessen kann man:
1
void spi_send (uint8_t data)
2
{
3
    loop_until_bit_is_set (SPSR, SPIF);
4
    SPDR = data;
5
}
so dass Code, der auf spi_send() folgt, parallel zum SPI läuft und schon 
damit anfangen kann, das nächste Byte zu berechnen.

Allerding muss man dann auch das Empfangen anpassen:
1
uint8_t spi_send_and_receive (uint8_t data)
2
{
3
    loop_until_bit_is_set (SPSR, SPIF);
4
    SPDR = data;
5
    loop_until_bit_is_set (SPSR, SPIF);
6
    return SPDR;
7
}

Und was auch gut ist, diese Funktionen inline zu haben um die 
Call-Overheads zu sparen.

von Bruno V. (bruno_v)


Lesenswert?

Gustav G. schrieb:
> &wert

Liefert immer die erste Adresse. Memcpy and Co verlassen sich darauf, 
dass & die untere Adresse eines Objekts liefert.

Mit endianes hat das nicht zu tun.

Kopieren eines u32 in ein Byte Array ist auch nicht notwendig.

Und selbst die schiebereien (die unabhängig von der endianes sind, also 
portabel also gut!) dürften bei einem C-compiler nur dann die Laufzeit 
verlängern, wenn man sich abgefahrene Tricks überlegt, die der Compiler 
nicht erkennen kann.

Vielleicht daher deinen ursprungscode zeigen.

: Bearbeitet durch User
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.