2016-08-10 3 views
0

Ich möchte zwei serielle Ports in C verbinden/überbrücken. Ich habe 2 Threads, die die Ports lesen und auf den anderen Port schreiben. Hier ist ein Beispiel:Verbinden von zwei seriellen Ports in C

void *rfid_to_uart_thread(void *) { 
char rfid_read_buffer[100]; 
int writeCounter; 
do { 
    writeCounter = read(rfidCom, rfid_read_buffer, sizeof(rfid_read_buffer)-1); 
    if (writeCounter > 0) { 
     write(uartCom, rfid_read_buffer, writeCounter); 
    } else 
     usleep(25); 



} while (!bKillBridgeThreads); 

return NULL;} 

Das Problem ist, scheint es, dass die Schreibvorgänge zu langsam sind. Ich empfange oft nur die Hälfte der Saite auf der anderen Seite. Es scheint, als wäre der Schreibvorgang asynchron und der Puffer wird in der nächsten Schleife wieder überschrieben und überschreibt das letzte 'Schreiben', so dass die Daten verkrüppelt sind ?! Ist das richtig?

Die Ports werden geöffnet NON_BLOCKING und RW, Baudrate und hat 9600.

+0

Also, Sie haben zwei COM-Ports mit 2 Fäden, 1 Anschluss für Gewinde. Der Thread schreibt an seinen COM-Port oder an einen gemeinsamen? – Raskayu

+0

Der angegebene Code ist ein einzelner Thread, in dem Sie versuchen, von einem Port (rfidcom) zu lesen und in einen anderen Port (uartCom) zu schreiben. Also im Code ist der Code sequenziell. also ist kein Weg asynchron. Der Schreibvorgang wird ausgeführt, sobald das Lesen vom rfid-Gerät gelesen wurde (100 Byte oder weniger). Ist es so, dass die Puffergröße, die zum Lesen gegeben wird, klein ist? –

+0

Sorry, vielleicht war die Frage irreführend. Es ist in Ordnung für "schreiben", nur das zu schreiben, was beim Lesen empfangen wurde. Auf der UART-Seite habe ich einen TeraTerm-Lauf, der nach der Ausgabe des RFID-Moduls Ausschau hält, die an den UART gesendet werden muss. Manchmal erhalte ich über UART "2FEF0000" und das nächste Mal bekomme ich "2FEF00001000 \ r".Also vielleicht ist das Problem mehr wie schreiben nicht alles schreibt, es ist gepuffert? Gibt es eine Möglichkeit, alle noch im Puffer befindlichen Zeichen zu erzwingen? – Tobi

Antwort

0

Mit Blick auf die man sein:

read()Versuche bis Zählwert zu lesen Bytes vom Dateideskriptor fd in den Puffer beginnend bei buf.

Mit anderen Worten read Zuschüsse nicht alle Bytes senden durch andere Aufgabe zurückkehren, können Sie zu sizeof(rfid_read_buffer)-1

ein einziges Byte up geben, was Sie tun können, ist:

  1. Schleife Lesen von rfidCom bis die Anzahl der Zeichen mit der Anzahl der gesendeten Zeichen übereinstimmt.
  2. Sie können einen bestimmten Terminator von Nachrichten verwenden und prüfen, ob es empfangene Nachricht mit einem Header
  3. Zeichen in eine Protokollnachricht zu validieren einkapseln, die die Nachrichtenlänge einbetten, so kann der Empfänger die empfangenen Zeichen zählen und aufhören zu lesen, wenn letzte Char wird empfangen.

Zum Beispiel:

void *rfid_to_uart_thread(void *) 
{ 
    char rfid_read_buffer[100] = {0}; 

    int writeCounter; 
    char RXchar; 
    ssize_t retVal; 
    bool send = false; 

    do 
    { 
     memset(rfid_read_buffer, 0x00, sizeof(rfid_read_buffer)); 
     send = true; 

     do 
     { 
      retVal = read(rfidCom, &RXchar, 1); 

      if (retVal > 0) 
      { 
       rfid_read_buffer[writeCounter] = RXchar; 

       writeCounter++; 
      } 
      else if (retVal < 0) 
      { 
       send = false; 
       RXchar = '\r' 
       break; 
      } 
      else 
      { 
       usleep(25); 
      } 
     } 
     while(RXchar != '\r'); 


     if (send) 
     { 
      write(uartCom, rfid_read_buffer, writeCounter); 
     } 
    } 
    while (!bKillBridgeThreads); 

    return NULL; 
} 
+0

@sawdust wahr. Es ist nur ein Beispiel, um das Konzept besser zu erklären. Übrigens kannst du deinen effizienten Code als Antwort posten ...;) – LPs

0

OK, habe ich eine Lösung für mein Problem gefunden, denke ich.

void *rfid_to_uart_thread(void *) { 
char rfid_read_buffer[10]; 
ssize_t writeCounter = -1; 

do { 
    writeCounter = read(rfidCom, &rfid_read_buffer, sizeof(rfid_read_buffer)-1); 
    if (writeCounter>0){ 
     rfid_read_buffer[writeCounter] = 0; 
     LOGE("RFID -> UART: %s", rfid_read_buffer); 
     write(uartCom, rfid_read_buffer, writeCounter); 
    }else{ 
     usleep(25); 
    } 
    tcdrain(uartCom); 
} while (!bKillBridgeThreads); 

return NULL;} 

Ich habe meine eigene erstellt für eine tcdrain definieren, weil das Android NDK Ich verwende nicht in termios.h bietet nun alle Werte scheinen an den UART-Port übertragen werden.

tcdrain ist nun definiert als:

#define tcdrain(fd) ioctl(fd, TCSBRK, 1) 
+0

Ich würde wirklich gerne wissen, wie das ioctl zum Senden eines Breakcharacters das ioctl warten soll, bis der Sendepuffer geleert ist. – rjp

Verwandte Themen