Бурение скважин на воду бурение скважины на воду под ключ.
Для организации повторов из-за занятости используется один из двух протоколов, который выбирает целевое (занятое) устройство: однофазный или двухфазный. Первая попытка посылки пакета (запроса или ответа) выполняется всегда одинаково: в заголовке пакета поле rt = 00. Если на этот пакет приходит квитанция с одним из кодов, означающим занятость — 4 (ack_busy_x), 5 (ack_busy_A) или 6 (ack_busy_B), то узел организует последующие попытки передачи этого пакета, устанавливая в поле rt значение: 01 (Retry_x), 10 (Retry_A) или 11 (Retry_B) соответственно. Попытки повторов выполняются с обычным (справедливым) арбитражем, «предел терпения» определяется в зависимости от используемого протокола повторов.
Протокол однофазных повторов (Single Phase Retry) использует только код квитирования 4 (ack_busy_x), в ответ на который повторные попытки передачи делаются с кодом rt = 01 (Retry_x). Максимальное число повторов одного пакета ограничено 4-битным полем retry_limit регистра BUSY_TIMEOUT (смещение 210h в пространстве регистров CSR, см. рисунок). По достижении этого лимита повторные попытки прекращаются, и уровень транзакций сообщает драйверу о невозможности посылки данного пакета из-за занятости адресуемого узла.
Протокол двухфазных повторов (Dual Phase Retry) позволяет несколько упорядочить обслуживание занятым (перегруженным) узлом пакетов разных транзакций. Для этого вводится чередование двух фаз — фазы A и фазы B. Если занятый узел получает пакет первой попытки (rt = 00), он на него отвечает кодом квитирования 5 (ack_busy_A) и ожидает его повторного прихода с кодом rt = 10 (Retry_A). Теперь этот узел находится в фазе A и будет пытаться обслуживать только пакеты с rt = 10. На все первые попытки других транзакций узел будет отвечать кодом квитирования 6 (ack_busy_B), что заставит узлы, их посылающие, делать попытки повторов с rt = 11 (Retry_B), в данной фазе не обслуживаемые. Только после того, как наш узел сумеет обслужить пакет с rt = 10 и в течение четырех подряд интервалов справедливости не будет получать другие пакеты с rt = 10 (Retry_A), он перейдет в фазу B и начнет обслуживать пакеты с rt = 11 (Retry_B). При этом на новые первичные пакеты он будет отвечать кодом квитирования 5 (ack_busy_A). После обслуживания пакетов фазы B узел снова перейдет в фазу A — получается подобие игры в пинг-понг. Предел «терпения» узла, посылающего повторные пакеты по двухфазному протоколу, определяется уже по времени: ограничивается время, отсчитываемое от момента первой попытки передачи. Это время не должно превышать значение, заданное полями seconds_limit и cycle_limit в том же регистре BUSY_TIMEOUT. 13-битный счетчик, соответствующий полю cycle_limit, считает по модулю 8000 (полный оборот за 1 секунду).
Для обеспечения надежных транзакций достоверность передачи заголовков и полей данных пакетов контролируются CRC-кодами. Пакеты запросов и ответов, принятые с обнаруженной ошибкой в заголовке, игнорируются (достоверной информации об их источнике и адресате назначения нет). Об остальных ошибках узел, которому адресован пакет запроса или ответа, сообщает его источнику указанием соответствующего кода в пакете квитирования. Пакеты-квитанции контролируются проще (по двоичному дополнению кода ответа), неверные квитанции игнорируются. Обработкой ошибок занимается прикладной драйвер, которому уровень транзакций сообщает результат выполнения. Канальный уровень принятые пакеты только проверяет на корректность формата и CRC; он передает уровню транзакций все пакеты, адресованные данному узлу, но с соответствующими признаками корректности или ошибки.
Типовая асинхронная транзакция состоит из двух субакций (запроса и ответа), каждая из которых выполняется с квитированием. Таким образом, транзакция состоит из четырех пакетов, каждый из которых при передаче может оказаться поврежденным. Рассмотрим поэтапно возможные ошибки передачи в типовой транзакции.
Пакет запроса пришел к адресованному узлу с ошибкой CRC данных:
Пакет запроса пришел нормально, но пакет квитирования «потерялся» (канальный уровень запросчика не дождался корректной квитанции):
Пакет ответа пришел к запросчику с ошибкой CRC данных:
Пакет ответа не пришел к запросчику до срабатывания тайм-аута ожидания ответа. Об этом информируется прикладной драйвер, который может решить повторить запрос. Однако этот повтор может иметь побочные эффекты, если, например, запрашивалось чтение регистра (или памяти), не допускающего предвыборки: одно чтение уже было сделано, правда, результаты потерялись.
Пакет ответа пришел нормально, но пакет квитированиия «потерялся». Об этом уведомляется драйвер ответчика, который обрабатывает эту ситуацию в зависимости от приложения. Дошел ли при этом ответ до запросчика — неизвестно.
Уровень транзакций взаимодействует с прикладным драйвером четырьмя примитивами сервисов:
Передавая запрос канальному уровню, уровень транзакций добавляет еще метку транзакции и код повтора.
Потоковые передачи могут быть изохронными и асинхронными. В обоих случаях используются пакеты одного и того же формата, но есть разница в организации:
Пакеты изохронных передач передаются широковещательно и физически адресуются по номеру канала (0–63), указанному в заголовке пакетов.
Получение номера канала и выделение полосы пропускания осуществляется обращениями узла к регистрам диспетчера изохронных ресурсов CHANNEL_AVAILABLE и BANDWIDTH_AVAILABLE. Если канал и полосу получить не удалось, узел может периодически повторять запросы. Когда изохронный обмен становится ненужным узлу, он должен освободить свою полосу и номер канала, чтобы этими ресурсами смогли воспользоваться другие устройства. Обмен управляющей информацией с диспетчером производится асинхронными транзакциями.
Для выполнения изохронных обменов прикладной драйвер пользуется сервисами LINK-уровня:
Потоковые передачи выполняются в широковещательной форме, в которой присутствует только пакет запроса и нет ни квитирования, ни ответов. Потоковые данные передаются пакетами с tcode = Ah. Этот код транзакции указывает на то, что пакет адресуется не по номеру узла, а по номеру канала channel. Формат данных в пакете определяется 2-битным полем tag: 00 — неформатированные данные, 01 — общий формат CIP (Common Isochronous Packet), 1x — резерв. Информацию о синхронизации, специфическую для приложений, может нести поле sy (4 бита). Длина блока данных data_length (в байтах) ограничивается. Пакет может иметь и нулевую длину данных, при этом размер пакета сокращается до двух квадлетов заголовка. Если длина данных не кратна квадлету, то последний квадлет данных дополняется до целого байтами-заполнителями.
Мастер циклов регулярно (с периодом 125 мкс) передает пакеты начала цикла (рис. б). В каждом таком пакете мастер циклов передает значение 32-битного счетчика времени (CYCLE_TIME), инкрементируемого с частотой 24,576 МГц. Метки времени нужны каждому узлу, поддерживающему изохронный обмен. Если к моменту подачи очередного пакета начала цикла шина оказывается занятой передачей, то пакет начала цикла задерживается до момента освобождения шины. В поле данных cycle_time_data передается значение регистра CYCLE_TIME мастера циклов на момент его фактической передачи, так что точная синхронизация узлов обеспечивается и при опозданиях пакета. Пакет передается во время асинхронной части цикла, но с коротким зазором арбитража, что обеспечивает приоритетность данных пакетов. Пакет передается широковещательно (destination_ID = 3Fh), его принимают все узлы, интересующиеся изохронными передачами. В поле destination_offset указывается адрес регистра CYCLE_TIME (смещение 200h в пространстве регистров CSR). Поле tl не используется (ответов не предусматривается), rt = = 00 (без квитирования). Поле source_ID содержит номер шины и идентификатор корневого узла, который и должен быть мастером циклов.