Compartilhar via


Transações de Custom-Receive serCx2

Alguns hardwares do controlador serial podem implementar um mecanismo de transferência de dados diferente de PIO ou DMA do sistema para ler dados de um controlador serial. Um driver de controlador serial pode dar suporte a transações de recebimento personalizado para disponibilizar esse mecanismo de transferência de dados para ser usado pelo SerCx2.

Para iniciar uma transação de recebimento personalizado, o SerCx2 chama a função de retorno de chamada de evento EvtSerCx2CustomReceiveTransactionStart do driver e fornece como parâmetros a solicitação de leitura (IRP_MJ_READ) e uma descrição do buffer de leitura para a transação. Nessa chamada, a função inicia a transação e retorna. Em seguida, o driver é responsável por concluir a transação e concluir a solicitação de leitura.

Criando o objeto de recebimento personalizado

Antes que o SerCx2 possa chamar qualquer uma das funções EvtSerCx2CustomReceiveTransactionXxx** do driver serial, o driver deve chamar o método SerCx2CustomReceiveTransactionCreate para registrar essas funções com SerCx2. Esse método aceita, como parâmetro de entrada, um ponteiro para uma estrutura SERCX2_CUSTOM_RECEIVE_TRANSACTION_CONFIG que contém ponteiros para as funções EvtSerCx2CustomReceiveTransactionXxx** do driver.

O driver deve implementar as duas funções a seguir:

Como opção, o driver pode implementar qualquer uma ou todas as três funções a seguir:

O método SerCx2CustomReceiveTransactionCreate cria um objeto de recebimento personalizado e fornece ao driver de chamada um identificador SERCX2CUSTOMRECEIVETRANSACTION para esse objeto. As funções EvtSerCx2CustomReceiveTransactionXxx** do driver assumem esse identificador como seu primeiro parâmetro. Os seguintes métodos SerCx2 assumem esse identificador como seu primeiro parâmetro:

Inicialização de hardware e limpo-up

Alguns drivers de controlador serial podem precisar inicializar o hardware do controlador serial no início de uma transação de recebimento personalizado ou para limpo o estado de hardware do controlador serial no final da transação.

Se um driver implementar uma função de retorno de chamada de evento EvtSerCx2CustomReceiveTransactionInitialize , o SerCx2 chamará essa função para inicializar o controlador serial antes de iniciar a transação. Se implementada, a função EvtSerCx2CustomReceiveTransactionInitialize deverá chamar o método SerCx2CustomReceiveTransactionInitializeComplete para informar o SerCx2 quando o driver terminar de inicializar o controlador serial.

Se o driver implementar uma função de retorno de chamada de evento EvtSerCx2CustomReceiveTransactionCleanup, o SerCx2 chamará essa função para limpo o estado do hardware após o término da transação. Se implementada, a função EvtSerCx2CustomReceiveTransactionInitialize deverá chamar o método SerCx2CustomReceiveTransactionCleanupComplete para informar o SerCx2 quando o driver terminar de limpar o controlador serial.

Notificações de novos dados

Como opção, o driver do controlador serial pode implementar uma função de retorno de chamada de evento EvtSerCx2CustomReceiveTransactionEnableNewDataNotification . Se implementado, o SerCx2 usa essa função para gerenciar com eficiência os tempos limite de intervalo que ocorrem durante o tratamento de solicitações de leitura processadas como transações de recebimento personalizado.

Um intervalo de tempo limite ocorrerá se o intervalo entre dois bytes sucessivos recebidos pelo controlador serial exceder um tempo máximo especificado pelo cliente. Depois que um driver periférico envia uma solicitação de leitura para SerCx2, um tempo limite de intervalo não pode ocorrer até que pelo menos um byte de dados seja recebido do dispositivo periférico conectado serialmente. O tempo entre a chegada de uma solicitação de leitura e o recebimento do primeiro byte de dados do dispositivo periférico pode ser significativamente maior do que o tempo necessário para receber o restante dos dados para a solicitação de leitura após o recebimento do primeiro byte. Para obter mais informações, consulte SERIAL_TIMEOUTS.

SerCx2 chama a função EvtSerCx2CustomReceiveTransactionEnableNewDataNotification , se ela for implementada, para habilitar uma notificação de novos dados. Se essa notificação estiver habilitada e o controlador serial receber um ou mais bytes de novos dados do dispositivo periférico ou já tiver dados em seu FIFO de recebimento, o driver do controlador serial deverá chamar o método SerCx2CustomReceiveTransactionNewDataNotification para notificar o SerCx2.

Para detectar um possível tempo limite de intervalo, o SerCx2 chama periodicamente a função de retorno de chamada de evento EvtSerCx2CustomReceiveTransactionQueryProgress para marcar se algum dado foi recebido durante o intervalo anterior. Como o SerCx2 detecta o recebimento do primeiro byte de dados depende se o driver do controlador serial implementa uma função EvtSerCx2CustomReceiveTransactionEnableNewDataNotification . Se essa função for implementada, o SerCx2 chamará a função para habilitar uma notificação de novos dados e será notificado pelo driver quando o primeiro byte de dados for recebido. Caso contrário, o SerCx2 chama periodicamente a função EvtSerCx2CustomReceiveTransactionQueryProgress para detectar o recebimento do primeiro byte e pode precisar ativar periodicamente o processador para fazer essas chamadas. Assim, um driver que implementa uma função EvtSerCx2CustomReceiveTransactionEnableNewDataNotification pode reduzir o consumo de energia não exigindo que o processador ative com frequência.

O SerCx2 não cancela explicitamente uma notificação pendente de novos dados para uma transação de recebimento personalizado. No entanto, talvez o driver do controlador serial precise cancelar implicitamente uma notificação de novos dados se a notificação estiver habilitada e o driver precisar concluir a solicitação de leitura associada por um dos seguintes motivos:

  • A solicitação de leitura atinge o tempo limite ou é cancelada.
  • O controlador serial está prestes a sair do estado de energia do dispositivo D0 para entrar em um estado de baixa potência.

O driver normalmente chama um método como WdfRequestComplete para concluir a solicitação. O driver nunca deve chamar SerCx2CustomReceiveTransactionNewDataNotification após a conclusão da solicitação.

Acessando o objeto de solicitação

Para iniciar uma transação de recebimento personalizado, o SerCx2 chama a função EvtSerCx2CustomReceiveTransactionStart do driver e passa a solicitação de leitura associada (encapsulada em um identificador de objeto WDFREQUEST) para essa função como um parâmetro. O driver é responsável por chamar um método como WdfRequestComplete para concluir essa solicitação quando a transação for concluída. A menos que a solicitação possa ser concluída imediatamente, antes que a função EvtSerCx2CustomReceiveTransactionStart retorne, o driver deve chamar um método como WdfRequestMarkCancelableEx para marcar a solicitação como cancelável.

O driver do controlador serial não deve usar um método como WdfRequestRetrieveOutputBuffer para acessar o buffer de dados na solicitação de leitura. Em vez disso, o driver deve usar os valores de parâmetro Mdl, Offset e Length passados para a função EvtSerCx2CustomReceiveTransactionStart para acessar esse buffer.

Durante uma transação de recebimento personalizado, talvez o driver precise armazenar informações sobre a transação em um contexto anexado ao objeto de solicitação. Nesse caso, a função de retorno de chamada de evento EvtDriverDeviceAdd do driver pode chamar o método WdfDeviceInitSetRequestAttributes para definir os atributos a serem usados para objetos de solicitação. Esses atributos incluem o nome e o tamanho da alocação a serem usados para contextos de solicitação. Os atributos de solicitação especificados nessa chamada devem corresponder aos atributos de solicitação especificados pelo driver na chamada para o método SerCx2InitializeDevice . Esses atributos são especificados no membro RequestAttributes da estrutura SERCX2_CONFIG que o driver passa para SerCx2InitializeDevice. Para obter mais informações, consulte SERCX2_CONFIG.

Para uma solicitação de leitura que o driver do controlador serial recebe no início de uma transação de recebimento personalizado, o contexto de solicitação alocado pela estrutura do driver não é inicializado. O driver deve, como prática recomendada, chamar a rotina RtlZeroMemory para inicializar esse contexto de solicitação para todos os zeros.