Ich benutze ein Raspberry Pi Zero im Gerätemodus und ein Raspberry Pi B im Host-Modus. Ich verbinde die beiden mit einem USB-Kabel. Mein Ziel ist gerade, einfache, willkürliche Daten zwischen den beiden Pi's hin und her zu schicken.Lesen von der seriellen Schnittstelle gibt immer zurück, was geschrieben wurde
Das Problem ist, welches Pi in den seriellen Port schreibt zuerst liest, was es geschrieben hat. Das Programm, das ich geschrieben habe, hat das Gerät senden d\n
und der Host senden h\n
. Wenn also das Gerät zuerst schreibt, liest der Host korrekt d\n
und schreibt h\n
an den seriellen Port. Aber das Gerät liest d\n
! Das Problem bleibt bestehen, wenn ich es so umschalte, dass der Host zuerst schreibt.
Ich habe versucht, verschiedene tcflush
Aufrufe an das Programm nach dem Schreiben, aber vor dem Lesen, aber es funktioniert nicht. Ich habe auch versucht, für verschiedene Zeitabschnitte zu schlafen. Ich habe für jeden geschriebenen Charakter 100 Mikrosekunden gelesen und habe mehrere Sekunden geschlafen.
Mein Setup erfordert, dass ich nicht gleichzeitig eine konstante Verbindung zwischen beiden Pi's habe, weil der einzelne Daten-fähige USB-Port von Pi Zero zur Verfügung steht. Also, um zu testen, stecke ich tatsächlich eine Tastatur ein und führe das Programm aus und stecke dann das richtige Kabel ein, um Daten zu übertragen. Ich kann Daten übertragen, aber nicht nach dem Schreiben, weil das Programm einfach zurückschreibt, was es geschrieben hat.
Ich fange an zu denken, dass ich in eine Noob Falle gefallen bin, die ich nicht ergründen kann. Hier ist der Code Ich verwende:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
/*
* gcc -o device_rw -DDEVICE serial_rw.c
* gcc -o host_rw serial_rw.c
*/
#define SERIAL_DEVICE "/dev/ttyGS0"
#define SERIAL_HOST "/dev/ttyACM0"
#ifdef DEVICE
#define _TTY SERIAL_DEVICE
#else
#define _TTY SERIAL_HOST
#endif
int
set_interface_attribs(int fd, int speed)
{
struct termios tty;
if (tcgetattr(fd, &tty) < 0) {
printf("Error from tcgetattr: %s\n", strerror(errno));
return -1;
}
cfsetospeed(&tty, (speed_t)speed);
cfsetispeed(&tty, (speed_t)speed);
tty.c_cflag &= ~PARENB; /* no parity bit */
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit characters */
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
tty.c_iflag |= IGNPAR | IGNCR;
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
tty.c_iflag |= ICANON;
tty.c_iflag &= ~OPOST;
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
printf("Error from tcsetattr: %s\n", strerror(errno));
return -1;
}
return 0;
}
void
write_serial (int fd, const char *buf, int len)
{
printf("WRITE: %s\n", buf);
write(fd, buf, len);
}
void
read_serial (int fd, char *buf, int len)
{
ssize_t nread = read(fd, buf, len);
if (nread > 0 && nread <= len) {
buf[nread] = 0;
printf(" READ: %s\n", buf);
}
}
int
main (int argc, char **argv)
{
char buf[80];
int fd = open(_TTY, O_RDWR | O_NOCTTY);
if (fd < 0) {
fprintf(stderr, "Can't open %s: %s\n", _TTY, strerror(errno));
goto exit;
}
if (set_interface_attribs(fd, B115200) < 0) {
goto exit;
}
#ifdef DEVICE
printf("device: %s\n", _TTY);
write_serial(fd, "d\n", 2);
usleep((2 + 25) * 100);
read_serial(fd, buf, 2);
#else
printf("host: %s\n", _TTY);
read_serial(fd, buf, 2);
//usleep((2 + 25) * 100);
write_serial(fd, "h\n", 2);
#endif
close(fd);
exit:
return 0;
}
Wo haben Sie '#define DEVICE' eingestellt, um Ihre Kompilierungsversionen zu erfüllen, die von' #ifdef DEVICE' gesteuert werden? –
Ich kompiliere mit '-DDEVICE', um es auszulösen. – Leroy
Oh ich sehe, wie im Code kommentiert. Aber ich mag es nicht - kann zu Fingerproblemen führen. Ich schlage vor, dass ein * spezifischer Wert * definiert sein muss, damit die Kompilierung ohne sie fehlschlägt. –