デバイスモードではラズベリーPiゼロを使用し、ホストモードではラズベリーパイBを使用しています。私は2つをUSBケーブルで接続しています。今私の目標は、単純な任意のデータを2つのPiの間で行き来させることです。シリアルポートからの読み込みは常に書き込まれた内容を返します
問題は、シリアルポートに書き込んだPiが最初に書き込んだ内容を読み終えてしまうことです。私が書いたプログラムは、デバイスにd\n
を送り、ホストはh\n
を送ります。したがって、デバイスが最初に書き込む場合、ホストはd\n
を正しく読み込み、次にh\n
をシリアルポートに書き込みます。しかし、デバイスは、d\n
を読み終えます!ホストが最初に書き込むように切り替えると、問題は解決しません。
私は、書き込み後、読み込み前に、さまざまなtcflush
呼び出しをプログラムに追加しようとしましたが、動作しません。私はまた、さまざまな時間の睡眠を試みました。私は書かれた文字ごとに100マイクロ秒間待って読んだので、数秒間寝ました。
私のセットアップでは、Pi Zeroの単一のデータ対応USBポートのために、両方のPiの間に一定の接続がないようにする必要があります。テストするために、実際にキーボードを差し込んでプログラムを実行してから、適切なケーブルを差し込んでデータを転送しています。私はデータを転送することはできますが、書き込み後はデータを転送することはできません。
私は私が推測することのできないノブトラップに陥ったと思っています。
#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;
}
'#define DEVICE'を入れて、' #ifdef DEVICE'によって制御されるコンパイルバージョンを満たすことができましたか? –
'-DDEVICE'でコンパイルして起動します。 – Leroy
ああ、コードにコメントされています。しかし、私はそれが好きではない - 指のトラブルにつながる可能性があります。コンパイルに失敗するとコンパイルが失敗するように、*特定の値*を定義する必要があります。 –