Arduino - 32 bitu promenna ze 4 byte

Miroslav Mraz mrazik na volny.cz
Středa Prosinec 18 14:09:00 CET 2024


Už dlouho s AVR nedělám, ale pořád mám nástroje, tak jsem trochu 
experimentoval.
Mějme nějaká data v RAM (const je zde nepodstatné) např.
static const uint8_t RX_Data[] = { 0x90, 0xab, 0xcd, 0xef, 0xab, 0xcd, 
0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef,};
a funkci
static void test_swap () {
   const uint32_t PowerIO = __builtin_bswap32 (((uint32_t *)(RX_Data + 
7))[0]);
   printf("0x%08lX\n", PowerIO);
}
Funguje to správně, ale na 8-bitu to není příliš efektivní. Funkce
static void test_shift () {
   uint32_t PowerIO = 0ul;
   const unsigned b = 7u, e = b + sizeof(PowerIO);
   for (unsigned n=b; n<e; n++) {
     PowerIO <<= 8;
     PowerIO  |= RX_Data [n];
   }
   printf("0x%08lX\n", PowerIO);
}
funguje stejně a při optimalizaci -Os a pokud jsou data opravdu 
konstantní a překladač vidí jejich hodnoty už v době překladu, je to 
daleko efektivnější. Smyčka se rozbalí do jednotlivých kroků, posun o 8 
bitů chápe překladač jako přechod na jiný byte, takže to jednotlivé byty 
ze vstupu nasype přesně tam, kam je potřeba a nic víc vlastně nedělá, 
není to potřeba. Lokální proměnné b,e,n se vůbec neprojeví takže na typu 
nezáleží.

Mrazík


On 18. 12. 24 13:26, Pavel Hudeček wrote:
> Nedávno jsem potřeboval posílat ven SN procesoru, udělal jsem to takhle:
>                  u64=0ULL;
>                  u64 <<= 8; u64 |= SIGROW.SERNUM5;
>                  u64 <<= 8; u64 |= SIGROW.SERNUM4;
>                  u64 <<= 8; u64 |= SIGROW.SERNUM3;
>                  u64 <<= 8; u64 |= SIGROW.SERNUM2;
>                  u64 <<= 8; u64 |= SIGROW.SERNUM1;
>                  u64 <<= 8; u64 |= SIGROW.SERNUM0;
> 
> Ale vlastně nevím jak je to tam s těma indiánama, možná to má bejt 
> obráceně, tady mi to naštěstí nevadí:-)
> 
> PH
> 


Další informace o konferenci Hw-list