Invece di utilizzare la porta parallela, avete pensato di utilizzare un dispositivo seriale? Dato che hai un segnale TTL, avrai probabilmente bisogno di un convertitore di livello per convertire i livelli da TTL a RS232 +/- 12V. Una volta che si utilizza un dispositivo seriale, è possibile utilizzare le chiamate standard di serie ioctl()
per rilevare una modifica dello stato del segnale di controllo.
In particolare, è possibile utilizzare l'ioctl TIOCMIWAIT
sul dispositivo seriale collegato per attendere una modifica sulla linea DCD, che si connetterà alla sorgente dell'orologio.
tua applicazione utente sarebbe stato bloccato in attesa della chiamata di sistema ioctl TIOCMIWAIT
finché non ci sarà un cambiamento di status sulla linea di clock, a quel punto la vostra applicazione sarebbe diventato eseguibile e tornare dal ioctl. Potrebbe essere necessario assicurarsi di gestire il caso in cui si ottiene un cambiamento di interrupt di stato sui fronti di salita e di discesa dei segnali di controllo seriale. Su alcuni hardware UART (es. TL16C554A UART) è possibile che si ottenga un interrupt solo per un segnale che passa in una singola direzione. Ad esempio, per il modello TL16C554A, lo TIOCMIWAIT
si sovrapporrà solo sul fronte di salita di qualsiasi variazione del segnale di Indicazione dell'anello.
Usando i ioctl seriali in questo modo ha anche il vantaggio che è possibile utilizzare un adattatore USB-seriale che supporta TIOCMIWAIT
se necessario (ad es PL2303), e mantenere ancora utente compatibilità software livello, sia pure a scapito di una maggiore latenza dovuta su USB.
Se è necessaria una latenza inferiore a quella che può essere raggiunta attraverso lo spazio utente, è preferibile scrivere un modulo del driver del kernel in grado di gestire i tempi e il campionamento, ma non suggerirei questo percorso a meno che non sia assolutamente necessario. È più facile sviluppare il codice spaziale dell'utente.
Ecco alcuni snippet di codice C di esempio incompleto per l'utilizzo dell'ioctl TIOCMIWAIT
.
int serial_fd = open(cmdline.device_name, O_RDWR | O_NONBLOCK | O_NOCTTY);
static const unsigned int ri_flag = TIOCM_RNG;
/* Set up serial port here using tcsetattr. Set CRTSCTS | CLOCAL to ensure status interrupts
* are generated.
*/
while (1) {
/* Wait for positive RI transition. TIOCMIWAIT takes a mask
* as argument, only returning when the appropriate signal has changed.
*/
if (ioctl(serial_fd, TIOCMIWAIT, ri_flag)) {
fprintf(stderr, "ioctl() failed waiting for RI edge [%s]\n", strerror(errno));
break;
}
/* Do sensor sampling here. You could use TIOCMGET to first verify that
* the clock line is in the expected state, eg high, before continuing.
*/
}
Questo è esattamente quello che mi piacerebbe fare. Non ero a conoscenza del fatto che potessi ancora utilizzare gli interrupt RS232 su un adattatore USB. Questo sicuramente semplifica le cose. Sembra che posso facilmente implementarlo in Python usando la domanda http://stackoverflow.com/questions/5904895/python-monitor-serial-port-rs-232-handshake-signals – Mike
L'esempio di ioctl Python ha funzionato perfettamente con un vero serial porta! ioctl ha restituito un "errore di argomento" ogni volta che ho provato questo con un adattatore USB Keyspan, ma meglio non avere comunque la latenza e usare una vera porta com. Ora è sufficiente costruire il TTL su un cambio di livello +/- 12V. – Mike
@Mike Ho dato un'occhiata all'origine, il driver keyspan non supporta 'TIOCMIWAIT'. Solo alcuni driver USB-seria supportano questo, cercare '.tiocmiwait' nei file del driver nella directory di origine Linux' drivers/usb/serial'. Il PL2303 è un adattatore seriale USB molto comune. Potrebbe essere in grado di trovare uno di questi e modificare la parte anteriore +/- 12V del dongle. In alternativa, Maxim produce una serie di circuiti integrati di conversione di livello. –