Является ли это преобразование порядка байтов правильным?

Читаю через библиотеку (github.com/adduc/phpmodbus) и есть эта функция для преобразования целых чисел в последовательность байтов с прямым порядком байтов или с прямым порядком байтов:

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));
}

iecBYTE функция просто chr($value & 0xFF),

Теперь, может быть, я толстая, но строка с прямым порядком байтов выглядит неправильно.
Например, с 0xAABBCCDD, вы получите {CC}{DD}{AA}{BB},

Я даже посмотрел это в Википедии. Не должно ли это быть {DD}{CC}{BB}{AA}?

Код работает хотя, что действительно смущает меня. Это правильно, и я неправильно понимаю?

5

Решение

Посмотрев на IECType.php, Я заметил, что это преобразование типов PHP в типы IEC 1131.
Little endian сначала хранит младшие байты. То, что вы описали, заставит меня думать, что система использует 16-битные адреса.

Если вы посмотрите на вики для Endianess, на который ссылаются в комментариях над функцией endianess, вы увидите раздел под Little-endian, называемый размером элемента Atomic 16-bit. Один адрес содержит два байта (CCDD) и (AABB). Адрес, содержащий (CCDD), является наименее значимым, поэтому он будет указан первым.

Если бы вы работали в 8-битной системе, то каждый байт был бы упорядочен (DDCCBBAA), потому что на адрес приходился один байт.

Вики описывает то, что вы видите в функции endianess.

address1 | Адрес 2
16 бит | 16 бит
CCDD | ААББ
0

Другие решения

Ты прав. Функция не правильная, хотя и близкая. Похоже, вам просто нужно поменять несколько конверсий. Логически преобразование с прямым порядком байтов ($ endianness == 0) является просто инверсией преобразования с прямым порядком байтов ($ 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));
}
0

По вопросам рекламы [email protected]