Mapping von uint32_t auf atmega328

OP #7492030
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?

#7492038
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.

Persönliche Seite #7497455
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.

#7497466
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.

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