Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Un controller seriale (o UART) include in genere un FIFO di ricezione. Questo FIFO fornisce un buffering, controllato dall'hardware, dei dati ricevuti dalla periferica connessa alla porta seriale. Per leggere i dati dalla ricezione FIFO, il driver di periferica per questo dispositivo invia richieste di lettura (IRP_MJ_READ) alla porta seriale.
Se la porta seriale continua a ricevere dati più velocemente di quanto il driver della periferica riesca a leggere, si può verificare un overflow della FIFO di ricezione. Per evitare la perdita di dati a causa dell'overflow, il driver periferico deve in genere configurare la porta seriale per l'uso del controllo del flusso hardware. Con il controllo del flusso, l'hardware del controller seriale segnala automaticamente al dispositivo periferico di interrompere l'invio dei dati quando la ricezione FIFO è quasi piena. Come regola, le porte seriali gestite da SerCx2 devono usare il controllo del flusso hardware. Per altre informazioni, vedere Dettagli del controllo del flusso.
Tuttavia, il controllo del flusso non deve essere usato per impedire al dispositivo periferico di inviare dati per troppo tempo o il dispositivo potrebbe non continuare a funzionare correttamente. Ad esempio, il dispositivo periferico potrebbe avere un buffer di dati interno che può traboccare se al dispositivo è impedito per troppo tempo l'invio di dati da questo buffer alla porta seriale.
In questa pagina
- Uso delle richieste di lettura asincrone
- Dettagli dell'intervallo di timeout
- Dettagli del controllo del flusso
Uso delle richieste di lettura asincrone
Per evitare un'operazione errata e una possibile perdita di dati, il driver periferico è responsabile della lettura tempestiva dei dati dalla ricezione FIFO del controller seriale. In genere, prima della ricezione dei dati, il driver periferico invia una richiesta di lettura asincrona alla porta seriale in previsione dell'arrivo futuro dei dati dal dispositivo periferico. Questa richiesta di lettura rimane in sospeso nella coda di I/O SerCx2 fino a quando i dati non sono disponibili per la lettura dalla FIFO di ricezione.
Nella maggior parte delle piattaforme hardware, un driver periferico non deve avere più di una richiesta di lettura in sospeso alla volta. In rari casi, un driver potrebbe aver bisogno di avere più richieste di lettura in sospeso se, dopo la ricezione dei dati, una richiesta di lettura impiega così tanto tempo per essere completata da far sì che l'accumulo di dati risultante causi la perdita dei dati nel dispositivo periferico o altrimenti un comportamento errato.
Supponendo che il driver periferico abbia una sola richiesta di lettura in sospeso alla volta, le dimensioni necessarie del buffer di dati in questa richiesta dipendono in gran parte dal comportamento noto del dispositivo periferico. Ad esempio, se il driver conosce in anticipo il numero di byte di dati previsti dal dispositivo, il driver imposta le dimensioni del buffer nella richiesta su questo numero di byte. La richiesta di lettura viene completata non appena il buffer viene riempito di dati dalla ricezione FIFO. In risposta, il driver può inviare in modo asincrono una nuova richiesta di lettura per attendere il blocco di dati successivo.
Tuttavia, il driver di periferica potrebbe non sapere in anticipo quanto dati aspettarsi dal dispositivo periferico. In questo caso, il driver imposta una dimensione appropriata per il buffer di dati nella richiesta di lettura, e quindi si basa su un timer di intervallo per identificare la fine dei dati dal dispositivo periferico. La scelta di una dimensione appropriata per il buffer di lettura potrebbe richiedere informazioni dettagliate sul funzionamento del dispositivo periferico. Se il buffer di lettura è troppo piccolo, il driver dovrà inviare una o più richieste di lettura aggiuntive per completare la lettura dei dati.
Dettagli timeout intervallo
Per impostare i parametri di timeout per le richieste di lettura e scrittura, un driver periferico può inviare una richiesta IOCTL_SERIAL_SET_TIMEOUTS alla porta seriale. I timeout per le letture sono controllati dai valori dei parametri ReadIntervalTimeout, ReadTotalTimeoutMultiplier e ReadTotalTimeoutConstant in questa richiesta. ReadIntervalTimeout specifica l'intervallo di tempo massimo consentito tra due byte consecutivi in una transazione di ricezione. Se ReadTotalTimeoutMultiplier e ReadTotalTimeoutConstant sono entrambi zero e la ricezione FIFO del controller seriale è vuota quando viene inviata una richiesta di lettura alla porta seriale, questa richiesta non scade (e quindi rimane in sospeso nella coda di I/O SerCx2) fino a quando la porta riceve almeno un byte di nuovi dati. Per altre informazioni, vedere SERIAL_TIMEOUTS.
Una porta seriale su un circuito integrato SoC (System on a Chip) potrebbe essere in grado di ricevere dati da un dispositivo periferico a velocità di picco di diversi megabit al secondo o superiore. Lo sviluppatore del driver periferico per questo dispositivo potrebbe essere tentato di impostare il valore di timeout dell'intervallo (come specificato dal parametro ReadIntervalTimeout) su un millisecondo o meno, ma è improbabile che questo valore abbia l'effetto desiderato. Ciò è dovuto al fatto che l'accuratezza del timer usato per rilevare i timeout dell'intervallo è limitata dalla granularità dell'orologio di sistema.
Ad esempio, se il periodo di clock di sistema è di 15 millisecondi e il driver imposta il valore ReadIntervalTimeout su 1 millisecondo, un intervallo da byte a byte in qualsiasi punto dell'intervallo compreso tra 0 e poco più di 15 millisecondi potrebbe attivare un timeout. In alcuni casi, questa impostazione potrebbe causare un timeout durante una trasmissione di dati dal dispositivo periferico. Per assicurarsi che un timeout possa verificarsi solo al termine della trasmissione, il driver può impostare ReadIntervalTimeout su un valore leggermente maggiore di 15 millisecondi. Ad esempio, se ReadIntervalTimeout è impostato su 20 millisecondi, un intervallo da byte a byte di 30 millisecondi attiva in modo affidabile un timeout e un intervallo di 15 millisecondi o meno non attiva un timeout.
Per altre informazioni sul modo in cui l'accuratezza del timer dipende dall'orologio di sistema, vedere Accuratezza timer.
Dettagli del controllo del flusso
Come buona pratica, i driver periferici che utilizzano porte seriali gestite da SerCx2 devono configurare queste porte per utilizzare il controllo del flusso hardware per impedire il sovraccarico della FIFO di ricezione. In assenza di una richiesta di lettura in sospeso, SerCx2 non fornisce alcun buffering software per i dati ricevuti che superano la capacità del FIFO di ricezione. Se l'overflow di fifo è consentito, i dati andranno persi.
Per abilitare il controllo del flusso hardware, un driver periferico potrebbe inviare una richiesta di IOCTL_SERIAL_SET_HANDFLOW per impostare le impostazioni di handshake e controllo del flusso per la porta seriale. In alternativa, il driver potrebbe inviare una richiesta di IOCTL_SERIAL_APPLY_DEFAULT_CONFIGURATION per configurare la porta seriale per l'uso di un set di impostazioni hardware predefinite che includono il controllo del flusso hardware. La richiesta di IOCTL_SERIAL_SET_HANDFLOW usa la struttura SERIAL_HANDFLOW per descrivere le impostazioni del controllo del flusso. Una richiesta di IOCTL_SERIAL_APPLY_DEFAULT_CONFIGURATION potrebbe contenere informazioni simili in un formato di dati specificato dal fornitore.
Se il driver periferico usa una richiesta di IOCTL_SERIAL_SET_HANDFLOW per abilitare il controllo del flusso hardware, il driver deve impostare i flag seguenti nella struttura SERIAL_HANDFLOW in questa richiesta:
- Flag SERIAL_CTS_HANDSHAKE nel membro ControlHandShake della struttura. Questo flag consente alla porta seriale di usare il controllo del flusso per le operazioni di ricezione.
- I flag SERIAL_RTS_CONTROL e SERIAL_RTS_HANDSHAKE nel membro FlowReplace. Questi flag consentono alla porta seriale di usare il controllo del flusso per le operazioni di trasmissione.