2014-06-08 12 views
5

TłoPakiet Perla() na wiadomość?

Mam urządzenie podłączone do mojego komputera na port szeregowy, który jest zorientowany, gdzie każda przychodząca wiadomość polecenia jest dokładnie osiem 16-bitowe słowa wiadomość. Najbardziej znaczący bajt każdego słowa jest odbierany jako pierwszy, a najmniej znaczący bajt - jako drugi. Każde słowo nagłówka jest identyfikatorem polecenia (w zakresie od 0 do 255). Format jest zdefiniowane tak:

XXXX Header Word (Placeholder for 16-bit Hexadecimal value) 
XXXX Data Word 
XXXX Data Word 
XXXX Data Word 
XXXX Data Word 
XXXX Data Word 
XXXX Data Word 
XXXX Checksum Word (Result of Exclusive OR on header word and all six data words) 

Format komendy trzeba wysłać, header 0x5D, jest zdefiniowane tak:

Word 1: Header = 005Dh 
Word 2: Mode (values can be 2, 3, 6, 8, 9) 
Words 3-7: Not significant 
Word 8: 16 bit checksum 

pytania (wszystkie związane)

Mam ten przykład z innego kodu źródłowego, który najwyraźniej wysyła tę wiadomość poprawnie, ale nie jestem pewien, co się dzieje, nawet po przeczytaniu perldoc na opakowaniu.

pack("v"x8, 0x00, 0x5D, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x5D); 
  1. "v" oznacza mały endian, ale nie mogę znaleźć żadnego odniesienia na x8 poniższy go.
  2. I zgodnie z formatem wiadomości, czy wartość 0x5D nie powinna być zaraz po "v" x8, a nie po 0x00?
  3. Wiadomość powinna zawierać osiem 16-bitowych słów, dlaczego więc jest 16, a nie 8? Niektóre z nich to 0x00, a nie 0x0? Czy to robi różnicę?
+1

nie ' "v" x8' oznacza' vvvvvvvv'? – Fabricator

+0

Ah, racja. Ciąg powtarzający magię mnożnika. Nie związane z pakietem, ale z łańcuchami w ogóle. Więc to było po prostu zwięźle napisane zamiast pakietu ("vvvvvvvv", ....). Wciąż jednak przegrywałem w pytaniach 2 i 3. – rem45acp

+0

Jakiej "wartości 0x68" używasz w pytaniu 2? W podanej specyfikacji lub kodzie nie ma wartości 0x68. – jwodder

Odpowiedz

5

pack "v"x8 (co skutkuje pack "vvvvvvvv", który może być zapisany jako pack "v8" w skrócie) pakuje osiem liczb 16-bitowych, ale zdałeś szesnaście.

Jeśli masz już szesnaście bajtów, chcesz

pack 'C16', 0x00, 0x5D, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 
      0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x5D 

Jednak Spodziewam się, aby mieć osiem 16-bitowych słów zamiast, więc byłoby użyć

pack 'n8', 0x005D, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0009, 0x005D 

Uwaga Użycie n zamiast v, aby uzyskać żądaną kolejność bajtów.

pack 'v', 0x1234  => "\x34\x12" Most significant byte last 
pack 'n', 0x1234  => "\x12\x34" Most significant byte first 

Dowód, że obie metody są równoważne:

my $method1 = pack 'C16', 
    0x00, 0x5D, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x5D; 

my $method2 = pack 'n8', 
    0x005D, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0009, 0x005D; 

print($method1 eq $method2 ? "yes" : "no", "\n"); # yes 
+1

Ta odpowiedź ma wiele sensu."V8", który widziałem podobnie w dokumencie perla, ale nie "v" x8, nie zdawał sobie sprawy, że są one takie same. Jednak przekazanie szesnastu wartości lub 8 wartości jest w zasadzie tym samym wejściem, prawda? Tak długo jak każdy ma 16 bitów. Znajduję 8 wyraźniejszych, ponieważ wiadomość została zdefiniowana jako mająca osiem 16-bitowych słów i pokazuje, że pierwsze słowo rzeczywiście ma nagłówek wiadomości. Będę musiał eksperymentować z kolejnością bajtów. – rem45acp

+0

Re "Jednak przekazanie szesnastu wartości lub 8 wartości to w zasadzie to samo wejście, prawda?" Jak pokazałem, możesz skonstruować te same spakowane dane z 16 liczb lub 8 liczb, ale te liczby będą musiały być różne, podobnie jak instrukcje, jak je spakować. Dodałem dowód, że obie metody są równoważne. – ikegami