Come posso ottenere un programma progettato per funzionare continuamente (conversione di dati su una porta COM seriale) per uscire?

1

Dichiarazione del problema

Sto scrivendo un programma di console C # che preleva i dati binari provenienti dalla COM1 seriale, convertendo ogni byte in esadecimale ASCII e poi emettendo i caratteri HEX attraverso la COM2 seriale.

Vorrei che questo programma si avvii continuamente nella shell dei comandi ma esca anche con garbo (in modo che le risorse di sistema come le porte COM vengano liberate). Il problema è che non esiste alcun timeout sul flusso di dati seriali in entrata / in uscita (mi piacerebbe che il programma funzioni per settimane-mesi alla volta). Quindi, come potrebbe uscire un programma di questo tipo quando l'utente vuole smettere?

La possibilità di connettersi a e disconnettere da una sessione di comunicazione seriale è una funzionalità standard della maggior parte degli emulatori di terminali e volevo sapere in che modo gli sviluppatori implementano tale soluzione.

Soluzioni iniziali

  1. Fai leggere il programma da un file di testo e riconosci i comandi come "smettere" da esso. L'utente crea semplicemente un file di testo, scrive "esci" e la prossima volta che l'applicazione si appresta a leggere il file, sa di uscire! Non mi piace questa soluzione perché sarò rimproverato per la creazione di un'interfaccia utente arcaica.
  2. Fai leggere l'applicazione da una terza porta COM ed elaborare i dati flusso come comandi. Si chiude quando vede "uscire" in ReadBuffer .
  3. Crea un secondo programma (processo) che richiama il programma precedente come un processo. Quindi, fare in modo che il secondo processo gestisca l'I / O dell'utente stdin in un'altra finestra della console. Quando l'utente inserisce "esci", il secondo processo dovrebbe terminare il primo processo. (Non ho mai lavorato con più processi quindi non so quale funzione chiama o librerie da guardare.
  4. Rendi il programma multi-threaded. Avere un filo di esecuzione per leggendo in byte, un altro per fare la conversione, un altro da scrivere il convertito e un altro per gestire l'input da stdin .

Commenti

Non sono sicuro di quale soluzione investire in tempo. Attualmente sto esaminando (4).

    
posta Minh Tran 22.11.2017 - 16:22
fonte

2 risposte

2

Nella dichiarazione del problema non c'è nulla che suggerisca di richiedere il multithreading esplicito . Quello che non so della tua applicazione C # è se stai scrivendo un'app Net Core progettata per essere cross-platform o meno. Ciò può limitare le opzioni disponibili.

Solo Windows

Utilizzando l'articolo qui usi PInvoke per registrarti alla call call SetConsoleCtrlHandler(...) Win32. Quella richiamata ti consente di sapere se la tua app ha ricevuto uno degli eventi che avrebbero chiuso la tua tipica app per console (Ctrl + C, Break, Chiudi la console, disconnessione, spegnimento). Ciò ti consente di gestire la chiusura inaspettata in modo più agevole.

Puoi creare un Servizio Windows per consentire l'esecuzione della tua applicazione anche se qualcuno non ha effettuato l'accesso. Ciò ha il vantaggio di poter utilizzare il pannello di controllo Servizi per avviare / interrompere la tua app.

Cross Platform

Se hai bisogno di gestire Linux / Mac e Windows, usare PInvoke è inutile dato che è specifico per la piattaforma. Tuttavia puoi adottare un approccio ibrido ispirato agli sviluppatori di Apache Tomcat.

Hanno creato un'interfaccia di controllo su una porta TCP separata che consentirebbe a uno strumento esterno di inviare un messaggio di controllo come shutdown, restart, ecc. Per Windows, avevano un servizio Windows che gestiva l'avvio dell'app console (Tomcat è un server Web basato su Java che è possibile eseguire dalla console) e inviare i messaggi di controllo appropriati quando era il momento di spegnersi. Per Linux / Mac, hanno appena avuto uno script che ha fatto essenzialmente la stessa cosa legata al daemon / sistema di servizio.

Esperienza personale

Ho creato un'app di elaborazione dati della console separata controllata da un servizio di Windows. Questa particolare app di elaborazione dati è stata utilizzata per monitorare i sensori ed eseguire alcuni calcoli fantasiosi in modo da poter individuare i problemi. L'app di elaborazione dati ha inviato i risultati a un'interfaccia utente di monitoraggio semi-in tempo reale. L'app ha dovuto funzionare senza sosta per tutto il tempo che la macchina ha fatto. Creando un servizio di Windows che fosse semplicemente lì per controllare l'app di elaborazione dei dati, potremmo facilmente creare una nuova istanza se la vecchia istanza è morta per un motivo inaspettato. Potremmo anche monitorare l'utilizzo della memoria dell'app e altri criteri di salute.

Una delle cose che abbiamo fatto nell'app della console era assicurarsi che non ci fossero risorse rimanenti consumate da un'istanza che non si chiudeva in modo pulito. Non è mai successo nella vita reale, ma l'importanza di questo processo ci ha fatto progettare per quel caso.

Protocollo di controllo

È possibile utilizzare un semplice protocollo di controllo basato su UDP. L'API socket di C # è dotata di lettura / scrittura asincrona, motivo per cui non è necessario il multithreading esplicito. Molto di questo è gestito per te.

Devi solo decidere il formato del messaggio. Se si utilizza un programma di controllo, è possibile mantenere un riferimento al processo in esecuzione per monitorarne l'integrità e determinare se è in esecuzione. Comandi utili:

  • Riagganciare: puoi spegnerlo ora
  • Ripristina: torna alle condizioni di avvio (ad esempio, chiudi le porte e riapale)
  • Heartbeat: se devi gestire un processo da remoto
risposta data 24.11.2017 - 14:32
fonte
1

Cerca semplicemente la piattaforma SIGTERM equivalente e gestiscila

Sotto Linux le cose sono piuttosto semplici, dato che la porta COM è solo un altro descrittore di file e puoi fare ogni sorta di cose strane con esso come passarlo a un altro processo o chiuderlo quando il programma si chiude (lo fa comunque)

Su altre piattaforme le risorse potrebbero non essere liberate quando il programma termina bruscamente, ma è possibile testare un approccio consolidato alla gestione della RS-232 , in C #

In diverse impostazioni c'è un processo di gestione degli arresti anomali che monitora il processo principale e può riavviarlo o inviare un log degli errori, ecc., ma questo non aiuta in questo modo

Oltre a questo,

  • Opzioni 1 e 3: la porta COM può veramente inviare una sequenza di 'smettere' per essere registrata
  • L'opzione 2 è solitamente FTP (connessioni dati / controllo separate)
  • L'opzione 4 (come con l'opzione 2) è MT e in realtà non aiuta

Tutto sommato, sembra che tu stia scrivendo un driver di porta seriale virtuale

    
risposta data 22.11.2017 - 23:07
fonte

Leggi altre domande sui tag