rem*_*acp 5 perl message cpu-word 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)
Run Code Online (Sandbox Code Playgroud)
我需要发送的命令的格式,标头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
Run Code Online (Sandbox Code Playgroud)
问题(全部相关)
我从其他源代码中得到了这个示例,显然正确地发送了这条消息,但我不确定发生了什么,即使在读取包上的perldoc之后也是如此.
pack("v"x8, 0x00, 0x5D, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x5D);
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
但我希望你有8个16位字,所以你可以使用
pack 'n8', 0x005D, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0009, 0x005D
Run Code Online (Sandbox Code Playgroud)
注意使用n而不是v获得所需的字节顺序.
pack 'v', 0x1234 => "\x34\x12" Most significant byte last
pack 'n', 0x1234 => "\x12\x34" Most significant byte first
Run Code Online (Sandbox Code Playgroud)
证明两种方法都是等价的:
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
Run Code Online (Sandbox Code Playgroud)