Доступ к устройствам FireWire в основанном на Intel Macintosh

Эта глава обеспечивает обзор некоторых проблем, связанных с разработкой универсальной версии двоичных файлов приложения, получающего доступ к устройству FireWire. Перед чтением этой главы, убедиться считать Универсальные Двоичные Инструкции по Программированию. Тот документ касается архитектурных различий, и порядок байтов форматирует и обеспечивает всесторонние инструкции для модификации кода и создания универсальных двоичных файлов. Инструкции в том документе применяются ко всем типам приложений, включая тех который аппаратные средства доступа.

Прежде чем Вы создадите свое приложение как универсальный двоичный файл, удостоверьтесь что:

Порядок байтов на шине FireWire

Шина FireWire является шиной с обратным порядком байтов. Структурированные данные (такие как адрес FireWire или конфигурация ROM) появляются на шине в формате с обратным порядком байтов, независимо от собственного формата порядка байтов компьютера, в котором работает приложение. Данные, не имеющие никакой FireWire-специфичной структуры, такой как дисковый блок (или сектор) данные, появляются на шине в ее исходном формате, независимо от собственного формата порядка байтов компьютерной отправки или получения тех данных.

Несмотря на то, что семья IOFireWire не должна подкачивать буферы данных для передачи на шине FireWire, Ваше приложение должно быть тщательным с параметрами, переданными и полученный от FireWire APIs и служб. Это вызвано тем, что те параметры, возможно, должны быть байтом, подкачанным, если они выражают данные полезной нагрузки числовыми способами, такой как с UInt32 значения. Например, если приложение использует Write функция IOFireWireDeviceInterface, это должно передать следующие параметры (среди других):

Целевой адрес передается в a FWAddress структура. Поскольку семья IOFireWire знает, как интерпретировать a FWAddress структура как числовые значения, семья ожидает, что те значения будут в собственном формате узла. Это означает, что Вы не должны делать никакого свопинга байта при заполнении структуры с, например, целевой адрес. Продолжение Write функциональный пример, Перечисление 4-1 показывает пример того, как создать целевой адрес, который приведет к корректным результатам, работает ли приложение в основанном на PowerPC или основанном на Intel Macintosh.

Перечисление 4-1  Universal способ создать FireWire предназначается для адреса

FWAddress a;
a.nodeID = 0xffc0;
a.addressHi = 0xffff;
a.addressLo = 0xf000040c;

Внутренне, семья IOFireWire, возможно, должна подкачать эти значения, когда она программирует аппаратные средства, но она не изменит содержание структуры, которую Вы подготавливаете.

Точно так же Write аргументы функции для количества байта и генерации шины должны также быть в собственном формате узла, как должен указатель на буфер. Семья IOFireWire не интерпретирует данные в буфере, таким образом, это отправляется на неизмененной шине.

Поскольку данные в буфере не изменяются семьей IOFireWire, Ваше приложение должно использовать безопасные от порядка байтов способы выразить данные при заполнении буфера для передачи. Для наблюдения, почему это так предположите, что приложение помещает адрес FireWire в буфер, который будет отправлен как полезная нагрузка (как Вы были бы в ORB SBP-2). Если бы Ваше использование приложения кодирует подобный, который, как показывают в Перечислении 4-2, заполнил буфер, приложение работало бы только в основанном на PowerPC Macintosh, не основанном на Intel Macintosh:

Перечисление 4-2  способ только для PowerPC заполнить буфер для передачи на шине FireWire

// Fill a buffer with the FireWire address 0xffc2ee33.00f01234
// to send as payload (works only in a PowerPC-based Macintosh).
UInt32 myBuffer[2];
myBuffer[0] = 0xffc2ee33;
myBuffer[1] = 0x00f01234;

Если Вы передаете версию myBuffer определенный в Перечислении 4-2 к Write функция в приложении, работающем в основанном на Intel Macintosh, адрес будет получен как 0x33eec2ff.3412f000. Это вызвано тем, что основанный на Intel Macintosh хранит численные значения такой как 0xffc2ee33 в формате с прямым порядком байтов и IOFireWire семья отправляет неизмененный буфер. Для предотвращения этой проблемы используйте нейтральный порядком байтов код, который произведет правильно упорядоченные байты на обоих типах компьютера, как показано в Перечислении 4-3.

Перечисление 4-3  Universal способ заполнить буфер для передачи на шине FireWire

// Fill a buffer with the FireWire address 0xffc2ee33.00f01234
// to send as payload (works in both PowerPC-based and Intel-based
// Macintosh computers).
UInt32 myBuffer[2];
myBuffer[0] = OSSwapHostToBigInt32 (0xffc2ee33);
myBuffer[1] = OSSwapHostToBigInt32 (0x00f01234);

В целом, везде, где Вы используете многобайтовую константу (такой как 0xffc2ee33) для представления байтов в буфере вместо этого с помощью числового значения необходимо будет, вероятно, подкачать ту константу, гарантирование байтов появляется в правильном порядке в памяти и на шине FireWire.

Для нескольких определенных типов данных семья IOFireWire действительно выполняет автоматический свопинг байта к собственному формату порядка байтов главного компьютера. Эти исключения упоминаются ниже.

Подсказки модификации кода

Этот раздел перечисляет некоторые определенные подсказки, чтобы помочь Вам подготовить свое приложение для выполнения в основанном на Intel Macintosh. Когда Вы решили, что условный свопинг байта необходим, используйте функции и макросы, определенные в libkern/OSByteOrder.h заголовочный файл в платформе Ядра. Для инструкций по различным подкачивающим байт стратегиям см. “Байты Свопинга” в Универсальных Двоичных Инструкциях по Программированию.

В целом при разработке приложения на основанном на PowerPC Macintosh Вы, возможно, использовали в своих интересах факт, что процессор PowerPC и FireWire соединяют шиной оба, используют формат с обратным порядком байтов. Необходимо искать места, где Вы предполагаете, что Ваши данные находятся автоматически в корректном порядке байтов, и введите условный подкачивающий байт код при необходимости.

Формулировка структур

Обратите особое внимание на то, как Вы формулируете структуры, такой как FWAddress структура, когда Вы планируете передать их как указатели на блоки данных в буферах. В зависимости от того, как Вы заполняете такие структуры, Вам, вероятно, придется выполнить свопинг байта. Например, семья IOFireWire определяет FWAddress структура как:

typedef struct FWAddressStruct
{
    UInt16  nodeID;     // bus/node
    UInt16  addressHi;  // Top 16 bits of node address.
    UInt32  addressLo;  // Bottom 32 bits of node address
} FWAddress, *FWAddressPtr;

Вы могли бы принять решение создать эту структуру путем формулировки сингла UInt64 значение или два UInt32 значения. Если Ваше приложение работает в основанном на Intel Macintosh, необходимо будет выполнить надлежащую подкачку байта на этих значениях перед размещением их в буфер для передачи на шине FireWire.

Доступ к Значениям в Реестре I/O

Поскольку основанный на Intel Macintosh не использует, Открывать Firmware, некоторая информация, предоставленная, Открывают, Firmware на основанном на PowerPC Macintosh (таком как полное дерево устройств) не доступен в Реестре I/O основанного на Intel Macintosh. Однако много частей Реестра I/O присутствуют, включая информацию, предоставленную семьей IOFireWire.

Если Ваши доступы к приложениям оценивают в Реестре I/O, необходимо знать, что значения числа типа, такие как значение ключа GUID, находятся в формате порядка байтов узла. Значения данных типа, однако, находятся в формате с обратным порядком байтов. Как описано в Порядке байтов на Шине FireWire, семья IOFireWire помещает непроанализированные байты конфигурации устройства ROM в значение Устройства FireWire ключ ROM в формате с обратным порядком байтов.

Байт, подкачивающий в буферах

Иногда, буферы, которые Вы используете в своем приложении, создаются некоторым другим объектом, таким как элемент семьи IOFireWire. Если Вы подкачка байта значения в таком буфере самом, можно найти, что эти те же значения подкачиваются снова в некоторой более поздней точке. Поэтому лучше создавать Вашу собственную копию буфера, таким образом, можно подкачать его значения, не влияя на исходный буфер.