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.
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.
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)?
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.
:
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.