Domanda

Sto scrivendo un'applicazione che utilizza OpenNetcf.io.serial (open source, Vedi il codice seriale qui) per la sua comunicazione seriale su un dispositivo Windows CE 6.0. Questa applicazione è codificata in C# nel Framework Compact 2.0. Non credo che il problema che sto per descrivere sia specificamente correlato a questi dettagli, ma potrei essere dimostrato di essere sbagliato in questo senso.

Il problema che sto riscontrando è quello, apparentemente Casuale (leggi come: questione intermittente Non posso ancora duplicare in modo affidabile), i dati non riescono a trasmettere o saranno ricevuti fino a quando il dispositivo stesso non sarà riavviato. Il dispositivo Windows CE comunica con un sistema che esegue un'applicazione completamente diversa. Il riavvio di questo altro sistema e la disconnessione/riconnessione dei cavi di comunicazione non sembra risolvere questo problema, riavvia solo il dispositivo Windows CE.

L'unico segno di questo problema che si verifica è la mancanza di un evento TxDone dall'accensione OpenNetCF (cerca "txdone ();" in OpenNetcf.io. Il sistema sta inviando dati.

Qualsiasi valore di carattere da 1 - 255 (0x01 - 0xFF) può essere inviato e ricevuto nella nostra comunicazione seriale. I valori nulli vengono scartati.

Le mie impostazioni seriali sono 38400 baud, 8 bit di dati, nessuna parità, 1 bit di arresto (38400, 8n1). Ho impostato le dimensioni del buffer di input e output su 256 byte. L'evento DataReceed si verifica ogni volta che riceviamo 1 o più caratteri e la trasmissione si verifica quando ci sono 1 o più byte nel buffer di output, poiché i messaggi sono di lunghezza variabile.

Non viene utilizzata alcuna hearthaking. Poiché questo è RS422, vengono utilizzati solo 4 segnali: Rx+, Rx-, TX+, TX-.

Ricevo un evento "DataReceived", leggo tutti i dati dal buffer di input e realizzo il mio buffer nel mio codice per analizzarlo a mio piacimento al di fuori dell'evento DateReceed. Quando ricevo un messaggio di comando, invio un messaggio di riconoscimento rapido. Quando l'altro sistema riceve un messaggio di comando dal dispositivo Windows CE, invierà indietro un messaggio di riconoscimento rapido. I messaggi di riconoscimento non ricevono ulteriori risposte poiché sono intesi come un semplice "sì, l'ha capito". Nel mio codice, ricevo/trasmetto tramite più thread, quindi utilizzo la parola chiave di blocco in modo da non trasmettere più messaggi contemporaneamente su più thread. Il doppio controllo del codice ha dimostrato che non mi sto bloccando su alcun serratura.

A questo punto, mi chiedo se mi manchi continuamente qualcosa di ovvio su come funziona la comunicazione seriale, come se avessi bisogno di impostare una variabile o una proprietà, piuttosto che leggere da un buffer di input quando non vuoto e scrivo a un buffer di trasmissione.

Qualsiasi intuizione, opzioni da controllare, suggerimenti, idee e così via sono benvenute. Questo è qualcosa con cui ho lottato da solo per mesi, spero che risposte o commenti che ricevo qui possano aiutare a capire questo problema. Grazie in anticipo.

EDIT, 24/02/2011:
(1) Posso solo ricreare l'errore all'avvio del sistema con cui il dispositivo Windows sta comunicando e non tutti gli avvio. Ho anche esaminato i segnali, la tensione in modalità comune fluttua, ma l'ampiezza del rumore che si verifica all'avvio del sistema sembra non correlata se il problema si verifica o no, ho visto 25 V Piccolo a picco non problemi, quando 5 V Picco -Percare il problema si è ripreso).
Il problema continua a sembrare sempre più correlato all'hardware, ma sto cercando di capire cosa può causare i sintomi che sto vedendo, poiché nessuno degli hardware sembra effettivamente fallire o chiudersi, almeno dove sono stato in grado di raggiungere misurare i segnali. Mi scuso, ma non sarò in grado di fornire alcun tipo di parte di parti hardware, quindi per favore non chiedere l'uso dei componenti.

(2) Secondo il suggerimento di @Ctacke, ho assicurato che tutte le trasmesse stavano attraversando la stessa posizione per manutenibilità, la sicurezza del filo che ho inserito è essenzialmente come segue:

lock(transmitLockObj)
{
    try
    {
        comPort.Output = data;
    }
    [various catches and error handling for each]
}

(3) Ottenere errori di superamento UART, in un test in cui sono stati inviati e ricevuti <10 byte su un intervallo di tempo di circa 300msc a 38400 baud. Una volta ricevuto un errore, va all'iterazione del loop successivo e non esegue ReadFile e non esegue eventi TxDone (o qualsiasi altra procedura di controllo della riga). Inoltre, non solo la chiusura e la riapertura della porta non fa nulla per risolverlo, riavviando il software mentre il dispositivo è ancora in esecuzione non fa neanche nulla. Solo un riavvio hardware.

Il mio evento DataReceived è il seguente:

try
{
    byte[] input = comPort.Input; //set so Input gets FULL RX buffer

    lock(bufferLockObj)
    {
        for (int i = 0; i < input.Length; i++)
        {
            _rxRawBuffer.Enqueue(input[i]);
            //timer regularly checks this buffer and parses data elsewhere
            //there, it is "lock(bufferLockObj){dataByte = _rxRawBuffer.Dequeue();}"
            //so wait is kept short in DataReceived, while remaining safe
        }
    }
}
catch (Exception exc)
{
    //[exception logging and handling]
    //hasn't gotten here, so no point in showing
}

Tuttavia, istantaneamente dopo che la chiamata Writefile è stata scaduta la prima volta nel test è stato quando ho iniziato a ottenere errori di superamento UART. Onestamente non riesco a vedere il mio codice causare una condizione di sovraccarico UART.

Pensieri? Hardware o software correlato, sto controllando tutto ciò che posso pensare di controllare.

Nessuna soluzione corretta

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