2017-06-29 6 views
0

Ich habe eine Klasse geschrieben, um Daten von einem Modul an die serielle Schnittstelle zu übertragen. Das Ziel ist es, den Port immer zu hören und wenn es nötig ist, einige Nachrichten zu übertragen. Das Modul kommuniziert mit hexadezimalen Token. Hier ist mein Code für das Aufnahmeteil:Lesen von HEX-Werten von einer seriellen Schnittstelle (Posix)

int serial::serial_receive (string &s_buffer, int &rcp) 
{ 
    struct pollfd fds[1]; 
    fds[0].fd = ptr; 
    fds[0].events = POLLIN ; 
    int pollrc = poll(fds, 1, 1000); 
    if (pollrc < 0) 
    { 
    perror("poll"); 
    } 
    else if(pollrc > 0) 
    { 
    if(fds[0].revents & POLLIN) 
    { 
     char buff[1024]; 
     ssize_t rc = read(ptr, buff, sizeof(buff)); 
     if (rc > 0) 
     { 
     s_buffer = buff; 
     rcp = rc; 
     } 
     else {cout << "error reading fd";} 
    } 

} 
return pollrc; 
} 

In meinem Test: ca.

using namespace std; 
char test[] = {0xAA,0x34,0x00,0x22}; 

int main(void) { 
    stringstream ss; 
    const char* mybuff; 
    string serial_buffer; 
    int rcl; 

    serial mymodule ("/dev/ttymxc5",115200, 0); //port configuration 

    ss << std::hex << setfill('0'); 
    mymodule.serial_send(test,4);    //send method 
    usleep(2000); 

    mymodule.serial_receive(serial_buffer,rcl); //receive method 

    mybuff = serial_buffer.c_str(); 
     for (int i = 0; i < 8; ++i) 
     { 
      ss << std::setw(2) << static_cast<unsigned>(mybuff[i]); 
     } 
    cout << ss.str() << endl; 

return 0; 
} 

Meine serielle Port-Konfiguration ist:

int serial::serial_set() 
{ 
    struct termios options; 
    if (tcgetattr (ptr, &options) != 0) 
       { 
         return EXIT_FAILURE; 
       } 
    cfsetospeed (&options, B115200); 
    cfsetispeed (&options, B115200); 
    options.c_cflag = (options.c_cflag & ~CSIZE) | CS8; 
    options.c_iflag &= ~IGNBRK; 
    options.c_lflag = 0; 
    options.c_oflag = 0; 
    options.c_cc[VMIN] = 0; 
    options.c_cc[VTIME] = 5; 
    options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); 
    options.c_cflag |= (CLOCAL | CREAD); 
    options.c_cflag &= ~(PARENB | PARODD); 
    options.c_cflag |= serial_parity; 
    options.c_cflag &= ~CSTOPB; 
    options.c_cflag &= ~CRTSCTS; 
    if (tcsetattr (ptr, TCSANOW, &options) != 0) 
     { 
     return EXIT_FAILURE; 
     } 
return EXIT_SUCCESS; 
} 

Bitte beachten Sie, dass istrip Bit als gesetzt 0, nicht das 8. Bit zu verlieren.

Das Ergebnis ist "fast" korrekt. Ich spreche eine AA B4 04 01 00 00 00 94 Sequenz, aber stattdessen bekomme ich eine AA B4 04 01 00 A8 4A F0 Sequenz. Dieser Fehler ist wiederholbar, jedes Mal, wenn ich den Befehl an das Modul sende.

Haben Sie vielleicht ein paar Vorschläge?

+1

Hier 's_buffer = buff;' Haben Sie irgendeine Garantie, dass 'buff' null-terminiert ist? –

+0

Ich habe Buff [rc] = '/ 0' angehängt, aber es sieht nicht so aus, als ob es die Ergebnisse ändert. Aber du hast wirklich Recht, ich sollte es tun. – Podarce

Antwort

0

Nach einigem Nachdenken fand ich heraus, dass ich nicht einfach string = char * schreiben kann.

I verwenden stattdessen eine String-Methode meine Zeichenfolge zu bauen:

std::string check(reinterpret_cast<char*>(buff), 8); 

Wo Buff der char-Array ist die Anzahl der Elemente zu konvertieren und 8 ist.

Dank Neil Butterworth, die auf die unsichere Besetzung hingewiesen.

Verwandte Themen