Perl pack()发送消息?

时间:2014-06-08 01:20:08

标签: perl word message pack

背景

我在一台面向消息的串口上连接了我的机器,每个传入的命令消息正好是8个16位字。首先接收每​​个字的最高有效字节,然后接收最低有效字节。每个标题字是命令标识符(范围从0到255)。格式定义如下:

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)

我需要发送的命令格式,标题0x5D,定义如下:

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 

问题(全部相关)

我从其他源代码中得到了这个示例,显然正确地发送了此消息,但我不确定发生了什么,即使在读取包上的perldoc后也是如此。

pack("v"x8, 0x00, 0x5D, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x5D);
  1. “v”表示小端,但我找不到跟随它的x8的任何引用。
  2. 根据消息的格式,0x5D值不应该在“v”x8之后,而不是在0x00之后?
  3. 该消息应该有8个16位字,那么为什么有16而不是8?有些是0x00,而不是0x0?这会有所作为吗?

1 个答案:

答案 0 :(得分:5)

pack "v"x8(结果为pack "vvvvvvvv",可以写成pack "v8"),包含8个16位数字,但是你通过了16个。

如果您已经有16个字节,则需要

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

但我希望你有8个16位字,所以你要使用

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

请注意,使用n代替v来获取所需的字节顺序。

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

证明两种方法都是等效的:

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