Domanda

Abbiamo un sistema con XP incorporato, con COM2 come porta RS485 hardware.

Nel mio codice, sto configurando il DCB con RTS_CONTROL_TOGGLE . Suppongo che farebbe quello che dice ... disattivare RTS in modalità kernel una volta che si verifica l'interrupt di scrittura vuoto. Dovrebbe essere praticamente istantaneo.

Invece, vediamo su un ambito che il PC sta guidando il bus da 1-8 millisecondi in più rispetto alla fine del messaggio. Il dispositivo con cui stiamo parlando sta rispondendo in circa 1-5 millisecondi. Quindi ... corruzione delle comunicazioni a bizzeffe. No, non c'è modo di cambiare il tempo di risposta del target.

Ora abbiamo collegato alla porta RS232 e collegato l'oscilloscopio alle linee TX e RTS, e stiamo vedendo la stessa cosa. La linea RTS rimane alta 1-8 millisecondi dopo l'invio del messaggio.

Abbiamo anche provato a spegnere FIFO o impostare le profondità FIFO su 1, senza alcun effetto.

Qualche idea? Sto per provare a controllare manualmente la linea RTS dalla modalità utente con priorità REALTIME durante il "SendFile, cancella RTS" ciclo. Non ho molte speranze che funzioni anche questo. Questo non dovrebbe essere fatto in modalità utente.

È stato utile?

Soluzione

RTS_CONTROL_TOGGLE non funziona (ha un ritardo variabile di 1-15 millisecondi prima di spegnerlo dopo la trasmissione) sulla nostra piattaforma XP integrata. È possibile che riesca a farlo scendere se ho modificato il tempo quantico a 1 ms usando timeBeginPeriod (1), ecc., Ma dubito che sarebbe affidabile o abbastanza importante. (Il dispositivo risponde @ 1 millisecondo a volte)

La soluzione finale è davvero brutta ma funziona su questo hardware. Non lo userei su nulla in cui l'hardware non è fissato in pietra.

In sostanza:

1) impostare gli FIFO nella pagina di gestione dei dispositivi della porta seriale su off o su 1 carattere in profondità

2) invia il tuo messaggio + 2 byte extra utilizzando questo codice:

int WriteFile485(HANDLE hPort, void* pvBuffer, DWORD iLength, DWORD* pdwWritten, LPOVERLAPPED lpOverlapped)
{
  int iOldClass = GetPriorityClass(GetCurrentProcess());
  int iOldPriority = GetThreadPriority(GetCurrentThread());
  SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
  SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

  EscapeCommFunction(hPort, SETRTS);

  BOOL bRet = WriteFile(hPort, pvBuffer, iLength, pdwWritten, lpOverlapped);

  EscapeCommFunction(hPort, CLRRTS);

  SetPriorityClass(GetCurrentProcess(), iOldClass);
  SetThreadPriority(GetCurrentThread(), iOldPriority);

  return bRet;
}

WriteFile () restituisce quando l'ultimo o due byte sono stati scritti sulla porta seriale. NON sono ancora usciti dalla porta, quindi è necessario inviare 2 byte extra. Uno o entrambi verranno spazzati via quando fai CLRRTS.

Come ho detto ... è brutto.

Altri suggerimenti

  

Qualche idea?

Potresti scoprire che c'è un codice sorgente per il driver della porta seriale nel DDK, che ti farebbe vedere come dovrebbe essere implementata quell'opzione: cioè se è a livello di interruzione, a livello di DPC o peggio.

Altre possibilità includono la riscrittura del driver; usando un driver RS485 di terze parti se ne trovi uno; o utilizzando hardware RS485 di terze parti con il proprio driver (ad es. almeno in passato terze parti utilizzavano "schede di porte seriali intelligenti" con 32 porte, buffer profondi e un proprio microprocessore; mi aspetto che RS485 sia un problema che è stato risolto da qualcuno).

8 millisecondi sembra un tempo deludentemente lungo; So che XP non è un RTOS ma mi aspetto che (di solito) faccia meglio di così. Un'altra cosa da vedere è se ci sono altri thread ad alta priorità in esecuzione che potrebbero interferire. Se hai migliorato le priorità di alcuni thread nella tua applicazione, forse invece dovresti ridurre le priorità di altri thread.

  

Sto per provare a controllare manualmente la linea RTS dalla modalità utente con priorità REALTIME durante il "SendFile, cancella RTS" Ciclo.

Non lasciare che quel thread esca dal controllo: IME un thread del genere può farlo se è difettoso che impedisce per sempre ogni altro thread in modalità utente.

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