Reputation: 1558
I'm writing a program for serial port data transmission on Linux, but find that every time the sender opens the port, the receiver gets an extra null byte '\x00'
.
Here's the code of sender:
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
int main(int argc, char* argv[]) {
int fd_com_ = open("/dev/ttyAM0", O_RDWR | O_NOCTTY | O_NONBLOCK);
struct termios attrs_;
attrs_.c_iflag = IGNBRK;
attrs_.c_oflag = 0;
attrs_.c_cflag = (CLOCAL | CREAD);
attrs_.c_cflag |= CS8;
attrs_.c_lflag = 0;
attrs_.c_cc[VMIN] = 0;
attrs_.c_cc[VTIME] = 0;
cfsetspeed(&attrs_, B115200);
tcsetattr(fd_com_, TCSANOW, &attrs_);
const char *s = "abcd";
write(fd_com_, s, 4);
sleep(1);
write(fd_com_, s, 4);
sleep(1);
close(fd_com_);
fd_com_ = open("/dev/ttyAM0", O_RDWR | O_NOCTTY | O_NONBLOCK);
write(fd_com_, s, 4);
return 0;
}
The receiver has the same configuration, but receives "\x00abcdabcd\x00abcd"
. How to fix this problem so the receiver could get "abcdabcdabcd"
?
Update:
The code of receiver:
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
int main(int argc, char* argv[]) {
int fd_com_ = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NONBLOCK);
struct termios attrs_;
attrs_.c_iflag = IGNBRK;
attrs_.c_oflag = 0;
attrs_.c_cflag = (CLOCAL | CREAD);
attrs_.c_cflag |= CS8;
attrs_.c_lflag = 0;
attrs_.c_cc[VMIN] = 0;
attrs_.c_cc[VTIME] = 0;
cfsetspeed(&attrs_, B115200);
tcsetattr(fd_com_, TCSANOW, &attrs_);
char buf[100];
ssize_t sz;
while(1) {
sz = read(fd_com_, buf, 100);
if (sz > 0) {
for (ssize_t i=0; i<sz; i++) {
printf("%02hhx\n", buf[i]);
}
}
sleep(1);
}
return 0;
}
Upvotes: 1
Views: 2900
Reputation: 16540
the initial \x0
is the indication that a parity or framing error occurred.
this error occurs because the termios fields are not being setup properly.
so the initial line high/low status and number of start/stop bits and parity
are not being setup properly.
you might read: http://man7.org/linux/man-pages/man3/termios.3.html which discusses each of the fields and their contents and meaning.
(The linked page is way too long to post here)
Upvotes: 1
Reputation: 1878
Please check in your ARM board's documentation how the ARM's UART is hooked up and how it is configured in hardware and by your platform driver.
From what you describe, I would suppose that when opening the UART port on the ARM, the physical UART (i.e., the hardware peripheral module within the ARM or maybe an externally wired UART chip) is enabled or restored from some unknown idle state to the proper -12 Volt idle state of RS232. This transistion may be enough for your PC's UART to recognize a start bit and receive a bogus character.
You may want to check the serial line using an oscilloscope to see what happens when actually opening the port.
Upvotes: 3