Транзакции Custom-Receive SerCx2
Некоторые устройства последовательного контроллера могут реализовать механизм передачи данных, отличный от PIO или системного DMA, для чтения данных из последовательного контроллера. Драйвер последовательного контроллера может поддерживать пользовательские транзакции приема, чтобы сделать этот механизм передачи данных доступным для использования SerCx2.
Чтобы запустить транзакцию пользовательского получения, SerCx2 вызывает функцию обратного вызова события EvtSerCx2CustomReceiveTransactionStart драйвера и предоставляет в качестве параметров запрос на чтение (IRP_MJ_READ) и описание буфера чтения для транзакции. В этом вызове функция инициирует транзакцию и возвращает . Затем драйвер отвечает за завершение транзакции и выполнение запроса на чтение.
Создание пользовательского объекта получения
Прежде чем SerCx2 сможет вызвать любую из функций EvtSerCx2CustomReceiveTransactionXxx** драйвера последовательного контроллера, драйвер должен вызвать метод SerCx2CustomReceiveTransactionCreate , чтобы зарегистрировать эти функции в SerCx2. Этот метод принимает в качестве входного параметра указатель на структуру SERCX2_CUSTOM_RECEIVE_TRANSACTION_CONFIG , содержащую указатели на функции Драйвера EvtSerCx2CustomReceiveTransactionXxx**.
Драйвер должен реализовывать следующие две функции:
В качестве варианта драйвер может реализовать любую или все из следующих трех функций:
- EvtSerCx2CustomReceiveTransactionEnableNewDataNotification
- EvtSerCx2CustomReceiveTransactionInitialize
- EvtSerCx2CustomReceiveTransactionCleanup
Метод SerCx2CustomReceiveTransactionCreate создает объект пользовательского приема и предоставляет вызывающей драйверу дескриптор SERCX2CUSTOMRECEIVETRANSACTION этому объекту. Функции EvtSerCx2CustomReceiveTransactionXxx** драйвера принимают этот дескриптор в качестве первого параметра. Следующие методы SerCx2 принимают этот дескриптор в качестве первого параметра:
- SerCx2CustomReceiveTransactionNewDataNotification
- SerCx2CustomReceiveTransactionReportProgress
- SerCx2CustomReceiveTransactionInitializeComplete
- SerCx2CustomReceiveTransactionCleanupComplete
Инициализация и очистка оборудования
Некоторым драйверам последовательного контроллера может потребоваться инициализировать оборудование последовательного контроллера в начале пользовательской транзакции приема или очистить состояние оборудования последовательного контроллера в конце транзакции.
Если драйвер реализует функцию обратного вызова события EvtSerCx2CustomReceiveTransactionInitialize , SerCx2 вызывает эту функцию для инициализации последовательного контроллера перед запуском транзакции. При реализации функция EvtSerCx2CustomReceiveTransactionInitialize должна вызвать метод SerCx2CustomReceiveTransactionInitializeComplete , чтобы сообщить SerCx2, когда драйвер завершит инициализацию последовательного контроллера.
Если драйвер реализует функцию обратного вызова события EvtSerCx2CustomReceiveTransactionCleanup , SerCx2 вызывает эту функцию для очистки состояния оборудования после завершения транзакции. При реализации функция EvtSerCx2CustomReceiveTransactionInitialize должна вызвать метод SerCx2CustomReceiveTransactionCleanupComplete , чтобы сообщить SerCx2, когда драйвер завершит очистку последовательного контроллера.
Уведомления о новых данных
Драйвер последовательного контроллера может реализовать функцию обратного вызова события EvtSerCx2CustomReceiveTransactionEnableNewDataNotification . Если эта функция реализована, SerCx2 использует эту функцию для эффективного управления интервалами времени ожидания, возникающими во время обработки запросов на чтение, обрабатываемых как пользовательские транзакции получения.
Интервал времени ожидания возникает, если интервал между двумя последовательными байтами, полученными последовательным контроллером, превышает максимальное время, указанное клиентом. После того как драйвер периферийного устройства отправляет запрос на чтение в SerCx2, интервал времени ожидания не может произойти до тех пор, пока не будет получен хотя бы один байт данных от последовательно подключенного периферийного устройства. Время между поступлением запроса на чтение и получением первого байта данных с периферийного устройства может значительно превышать время, необходимое для получения остальных данных для запроса на чтение после получения первого байта. Дополнительные сведения см. в разделе SERIAL_TIMEOUTS.
SerCx2 вызывает функцию EvtSerCx2CustomReceiveTransactionEnableNewDataNotification , если она реализована, чтобы включить уведомление о новых данных. Если это уведомление включено и последовательный контроллер получает один или несколько байтов новых данных с периферийного устройства или уже имеет данные в его приеме FIFO, драйвер последовательного контроллера должен вызвать метод SerCx2CustomReceiveTransactionNewDataNotification для уведомления SerCx2.
Чтобы определить возможный интервал времени ожидания, SerCx2 периодически вызывает функцию обратного вызова события EvtSerCx2CustomReceiveTransactionQueryProgress, чтобы проверка, были ли получены какие-либо данные в течение предыдущего интервала. То, как SerCx2 обнаруживает получение первого байта данных, зависит от того, реализует ли драйвер последовательного контроллера функцию EvtSerCx2CustomReceiveTransactionEnableNewDataNotification . Если эта функция реализована, SerCx2 вызывает функцию для включения уведомления о новых данных и получает уведомление от драйвера при получении первого байта данных. В противном случае SerCx2 периодически вызывает функцию EvtSerCx2CustomReceiveTransactionQueryProgress для обнаружения получения первого байта и может потребоваться периодические пробуждение процессора для выполнения этих вызовов. Таким образом, драйвер, реализующий функцию EvtSerCx2CustomReceiveTransactionEnableNewDataNotification , может снизить энергопотребление, не требуя, чтобы процессор запускался так часто.
SerCx2 не отменяет явным образом ожидающее уведомление о новых данных для пользовательской транзакции получения. Однако драйверу последовательного контроллера может потребоваться неявно отменить уведомление о новых данных, если уведомление включено и драйвер должен выполнить соответствующий запрос на чтение по одной из следующих причин:
- Время ожидания запроса на чтение истекает или отменяется.
- Последовательный контроллер выходит из состояния питания устройства D0, чтобы перейти в состояние с низким энергопотреблением.
Драйвер обычно вызывает метод , например WdfRequestComplete , для выполнения запроса. Драйвер никогда не должен вызывать SerCx2CustomReceiveTransactionNewDataNotification после завершения запроса.
Доступ к объекту запроса
Чтобы запустить транзакцию пользовательского получения, SerCx2 вызывает функцию EvtSerCx2CustomReceiveTransactionStart драйвера и передает соответствующий запрос на чтение (инкапсулированный в дескриптор объекта WDFREQUEST) в эту функцию в качестве параметра. Драйвер отвечает за вызов метода , например WdfRequestComplete , для выполнения этого запроса по завершении транзакции. Если запрос не может быть выполнен немедленно до возврата функции EvtSerCx2CustomReceiveTransactionStart , драйвер должен вызвать метод , например WdfRequestMarkCancelableEx , чтобы пометить запрос как отменяемый.
Драйвер последовательного контроллера не должен использовать метод, например WdfRequestRetrieveOutputBuffer , для доступа к буферу данных в запросе на чтение. Вместо этого драйвер должен использовать значения параметров Mdl, Offset и Length , передаваемые функции EvtSerCx2CustomReceiveTransactionStart для доступа к этому буферу.
Во время пользовательской транзакции получения драйверу может потребоваться хранить сведения о транзакции в контексте, присоединенном к объекту запроса. В этом случае функция обратного вызова события EvtDriverDeviceAdd драйвера может вызвать метод WdfDeviceInitSetRequestAttributes , чтобы задать атрибуты, используемые для объектов запроса. Эти атрибуты включают имя и размер выделения, используемые для контекстов запросов. Атрибуты запроса, указанные в этом вызове, должны соответствовать атрибутам запроса, указанным драйвером в вызове метода SerCx2InitializeDevice . Эти атрибуты указываются в элементе RequestAttributesструктуры SERCX2_CONFIG , которую драйвер передает в SerCx2InitializeDevice. Дополнительные сведения см. в разделе SERCX2_CONFIG.
Для запроса на чтение, который драйвер последовательного контроллера получает в начале транзакции пользовательского получения, контекст запроса, выделенный платформой драйвера, не инициализируется. Драйвер должен, как правило, вызвать подпрограмму RtlZeroMemory , чтобы инициализировать этот контекст запроса для всех нулей.