Mapping von uint32_t auf atmega328

OP #7492030

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?

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

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.

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

Eine eigene Frage? Dieser Thread ist über 3 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.