2014-12-19 19 views
5

Czytam poprzez biblioteki (github.com/adduc/phpmodbus) i jest to funkcja konwersji całkowitą do little-endian lub big-endian ciąg bajtów:Czy ta konwersja endianizmu jest poprawna?

private static function endianness($value, $endianness = 0) { 
    if ($endianness == 0) 
     return 
       self::iecBYTE(($value >> 8) & 0x000000FF) . 
       self::iecBYTE(($value & 0x000000FF)) . 
       self::iecBYTE(($value >> 24) & 0x000000FF) . 
       self::iecBYTE(($value >> 16) & 0x000000FF); 
    else 
     return 
       self::iecBYTE(($value >> 24) & 0x000000FF) . 
       self::iecBYTE(($value >> 16) & 0x000000FF) . 
       self::iecBYTE(($value >> 8) & 0x000000FF) . 
       self::iecBYTE(($value & 0x000000FF)); 
} 

Funkcja iecBYTE tylko chr($value & 0xFF).

Teraz może jestem gruby, ale sznur drobno-endyjski wygląda źle.
Na przykład z 0xAABBCCDD otrzymasz {CC}{DD}{AA}{BB}.

Sprawdziłem nawet to na Wikipedii. Czy nie powinien to być {DD}{CC}{BB}{AA}?

Kod działa jednak, co bardzo mnie wprawia w zakłopotanie. Czy to prawda i rozumiem to niepoprawnie?

+1

Co masz na myśli, mówiąc, że działa? Czy to może być "działa", ale po prostu nie działa poprawnie? – imtheman

+0

Może źle zrozumiałem, co robi metoda, nie jestem pewien. Ta metoda jest dość często używana w bibliotece i działa poprawnie. – MightyPork

Odpowiedz

0

Po obejrzeniu IECType.php, zauważyłem, że konwertuje typy PHP na typy IEC 1131. Little endian najpierw zapisuje najmniej znaczące bajty. To, co opisałem, sprawiłoby, że system używa 16-bitowych adresów.

Jeśli spojrzysz na wiki dla Endianess wymienionych w komentarzach powyżej funkcji bezdomności, zobaczysz sekcję pod Little-endian o nazwie Atomic size size 16-bit. Jeden adres zawiera dwa bajty (CCDD) i (AABB). Adres, w którym znajduje się CCDD, jest najmniej znaczący, więc powinien być wymieniony jako pierwszy.

Jeśli pracowałeś w systemie 8-bitowym, każdy bajt byłby zamawiany (DDCCBBAA), ponieważ byłby jeden bajt na adres.

Wiki opisuje to, co widzisz w funkcji endianess.

 
address1| address2 
16-bits | 16-bits 
CCDD | AABB 
0

Masz rację. Ta funkcja nie jest właściwa, chociaż jest blisko. Wygląda na to, że musisz zamienić kilka konwersji. Z logicznego punktu widzenia konwersja małego endianizmu ($ endianness == 0) jest tylko odwrotnością wielkiej endianizacji ($ endianness! = 0).

private static function endianness($value, $endianness = 0) { 
    if ($endianness == 0) //little-endian 
     return 
       self::iecBYTE($value & 0x000000FF) . 
       self::iecBYTE(($value >> 8) & 0x000000FF) . 
       self::iecBYTE(($value >> 16) & 0x000000FF) . 
       self::iecBYTE(($value >> 24) & 0x000000FF); 
    else //big-endian 
     return 
       self::iecBYTE(($value >> 24) & 0x000000FF) . 
       self::iecBYTE(($value >> 16) & 0x000000FF) . 
       self::iecBYTE(($value >> 8) & 0x000000FF) . 
       self::iecBYTE(($value & 0x000000FF)); 
} 
Powiązane problemy