Come posso inviare caratteri nulli alla porta seriale utilizzando l'API di Windows?

StackOverflow https://stackoverflow.com/questions/387322

  •  23-08-2019
  •  | 
  •  

Domanda

Sto lavorando su un programma di utilità di Windows che comunica con un po 'di hardware personalizzato utilizzando una porta COM standard. Il protocollo di comunicazione (che è fuori dal mio controllo) mi impone di trasmettere e ricevere prime byte di dati a 8 bit.

Attualmente sto usando la seguente funzione API di Windows per inviare i dati alla porta COM:

WriteFile(hFile, lpBuffer, numberOfBytesToWrite, ...)

dove hFile è un riferimento alla porta COM aperto correttamente, e lpBuffer è un array di byte che ho memorizzati nella memoria. Il codice funziona perfettamente finché un carattere nullo (ASCII zero) deve essere inviato al dispositivo. WriteFile smette di inviare non appena rileva il carattere nullo perché presuppone che essa ha raggiunto la fine della stringa. Questo accade anche se ho impostato numberOfBytesToWrite correttamente.

Come posso inviare i dati grezzi alla porta COM utilizzando l'API di Windows? Io preferirei usare una chiamata API standard simile a WriteFile, ma sono aperto a suggerimenti.

Attualmente sto usando RapidQ per costruire il programma di utilità, ma non fa altro che chiamare la funzione API di Windows direttamente.

Modifica La mia configurazione è costituito da un PC Windows collegato via porta seriale per il modulo hardware personalizzato. Il modulo è dotato di un piccolo schermo sul quale sono in grado di visualizzare i caratteri trasmessi. Ho testato questa configurazione con un altro programma di utilità di terze parti. Sono in grado di comunicare con il modulo di utilizzare questo programma di terze parti, e caratteri null mostrare correttamente. Nel mio programma, quando uso WriteFile, un carattere null in qualsiasi parte del flusso di trasmissione arresta i resti del flusso di essere inviato.

È stato utile?

Soluzione

Ho fatto la programmazione della porta seriale di Windows prima, e sono certo che sono stato in grado di inviare caratteri nulli attraverso le porte seriali (vari protocolli di trasferimento file non avrebbe funzionato in altro modo). Mi vengono in mente due possibili spiegazioni:

  1. ricevente dispositivo sta stampando i dati ricevuti utilizzando un metodo che si ferma al primo carattere nullo. Come stai determinando che il dispositivo che trasmette sta terminando al primo nullo? Il problema potrebbe essere da qualche parte più in basso la linea?
  2. Il driver seriale è rotto. Questo è piuttosto improbabile, ma è una possibile spiegazione. Se si utilizza qualche porto malfamata di proprietà di terzi di serie ed i suoi piloti, allora potrebbe essere sospetto. Se si utilizza uno standard built-in porta seriale con i driver normali di Windows, allora questo non è probabilmente un problema.

Ho appena avuto un rapido sguardo a RapidQ e c'è una terza spiegazione possibile:

  1. Il marshalling che RapidQ può fare nel processo di chiamata funzioni API Win32 possono avere problemi con caratteri nulli incorporati nei dati da inviare. Io non so nulla di RapidQ, ma questo è un altro anello della catena che deve essere considerato.

Altri suggerimenti

Greg è probabilmente corretto, ma vorrei anche controllare le impostazioni della porta COM. Assicurarsi che le impostazioni DCB sono impostati correttamente. Look up SetCommState, e GetCommState per informazioni.

In genere, Seriale è 8N1, ma il dispositivo potrebbe essere utilizzando qualche altro parità, o smettere di configurazione di bit, ecc.

Come Greg, ho fatto un sacco di lavoro su seriale me stesso, e questo spesso può essere la fonte di problemi ... Prova a parlare con RS485 ed una struttura DCB non corretta ... eh ..

Larry

PS: se non ne hai già uno, mi consiglia di ottenere una buona scatola break-out di serie da soli. Ho una qualche parte intorno alla casa, e vi mostrerà quello che tutti i segnali sono, su tutte le linee durante tutte le comunicazioni, ed è un potente strumento di debug.

Ho usato WriteFile in passato ed ha funzionato benissimo con byte nulli. Vorrei scavare RapidQ, potrebbe essere il problema.

Se tutto questo non aiuta, si può sempre fare quello che faccio. Usa il codice COMM di Greg per testare il dispositivo con. Ricorda Qmodem? :) Molto bello strumento per le routine di serie di test / debug. Si ccould anche utilizzare Qmodem e un semplice script Qmodem per leggere la porta COM su un'altra scatola (o un'altra porta nella stessa scatola), e stampare il valore esadecimale di ogni char inviato. Oh aspetta. Qmodem è quello costruito in. :) Utilizzare l'emulazione di debug ASCII e mostrerà i valori esadecimali di ogni carattere che viene attraverso la porta seriale. Quindi, si potrebbe almeno verificare se il codice funziona correttamente o meno.

Ora, domanda. Fa WriteFile ritorno quando colpisce il NULL, o ha semplicemente sedersi e aspettare, e non tornare mai più?

Se non ritorna, allora potrebbe non essere il vostro codice. WriteFile restituisce solo quando le ha comunicato tutte dwBytesToWrite, o se si verifica un errore. Tutto il resto, e sta cercando di scrivere, ma v'è un fallimento all'altro capo del filo.

Per inviare un carattere NULL attraverso seriale è possibile utilizzare la funzione di SetEndOfFile (), dando il gestore porta come file.

Se si dispone di troppi dati NULL da inviare è probabilmente non è l'ideale, ma è una soluzione.

dettagli funzione

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top