2014-12-19 3 views
5

Я читаю через библиотеку (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}?

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

+1

Что вы подразумеваете под этим работает? Может быть, это «работает», но просто неправильно работает? – imtheman

+0

Возможно, я неправильно понял, что делает этот метод, не уверен. Метод используется довольно много в библиотеке, и он работает правильно. – MightyPork

ответ

0

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

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

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

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

 
address1| address2 
16-bits | 16-bits 
CCDD | AABB 
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)); 
} 
Смежные вопросы