Как мне преобразовать маленький Endian в Big Endian, используя Perl Script? - PullRequest
0 голосов
/ 22 июля 2011

Я использую модуль Perl Win32::SerialPort.В этом патентованном модуле я отправил данные, используя команду ввода.Данные, которые я отправлял во встроенную систему, были скалярными данными (числами) с использованием функции transmit_char (если бы это было C, это были бы целые числа, но, поскольку это язык сценариев, я не уверен, какой внутренний формат в perl.Я предполагаю, что Perl всегда хранит все числа как 32-битные числа с плавающей запятой, которые корректируются модулем при передаче).

Затем после отправки данных я получаю данные с помощью команды ввода.Данные, которые я получаю, вероятно, в двоичном виде, но Perl не знает, как их интерпретировать.Я использую функцию unpack следующим образом:

my $binData = $PortObj->input;
my $hexData = unpack("H*",$binData);

Предположим, я передаю 0x4294 по последовательному кабелю, который является командой во встроенной системе, с которой я обмениваюсь информацией, и я ожидаю ответ 0x5245.Теперь проблема с порядком байтов: когда я распаковываю, я получаю 0x4552, что неправильно.Есть ли способ исправить это путем корректировки двоичных данных.Я также попробовал h*, что дает мне 0x5425, что тоже не правильно.

Примечание: данные, которые я получаю, отправляются по байту за раз, а младший бит отправляется первым

Ответы [ 2 ]

7 голосов
/ 22 июля 2011

Endianess применяется к порядку байтов целого числа (прежде всего). Вам нужно знать размер целого числа.

Пример для 32-разрядного без знака:

my $bytes = pack('H*', '1122334455667788');
my @n = unpack('N*', $bytes);
# @n = ( 0x11223344, 0x55667788 );

my $bytes = pack('H*', '4433221188776655');
my @n = unpack('V*', $bytes);
# @n = ( 0x11223344, 0x55667788 );

См. pack. Обратите внимание на модификаторы "<" и ">", чтобы управлять порядком байтов в тех местах, где порядок байтов по умолчанию не тот, который вам нужен.

Примечание: если вы читаете из файла, у вас уже есть байты. Не создавайте байты, используя pack 'H*'.

Примечание: если вы читаете из файла, не забудьте binmode ручку.


Что касается примера, который ОП добавил в свой пост:

Чтобы получить 0x5245 из "\x45\x52", используйте unpack("v", $two_bytes).

2 голосов
/ 23 июля 2011

Что это за типы данных?Пакет Perl содержит спецификаторы формата N и V для целых чисел, а в Perl 5.10 добавлены модификаторы > и <, так что вы можете читать шорты, числа с плавающей запятой и двойные (и некоторые другие типы) в нужной вам последовательности.

С их помощью вы читаете данные в порядке байтов, который он использует во входных данных.После того, как вы это сделаете, у вас есть данные, представленные внутри, и вы можете упаковать их так, как вам нравится.

Я пишу об этом в Используйте модификаторы> и .

...