我正在使用一个运行Linux内核的ARM9处理器(i.mx28),通过RS232与一个BLDC控制器进行通信(高层协议是基于CANOpen协议)。发送给控制器的信息一般都会有一个回应。
控制器侧的连接器有RX、TX以及GND,所以没有流控线或其他。控制器手册指出,必须使用无软件流量控制来设置连接。因此,我将端口配置为忽略DCD(使用CLOCAL)以及RTS/CTS(使用~CRTSCTS)和软件流控制(使用~IXON、~IXOFF和~IXANY)。
我的问题如下:在设置了串口之后,写入工作很好,例如软复位的命令可以立即执行。然而,试图读取提到的响应,结果是 "Errno 11: Resource momentarily unavailable"。当我试图在运行终端的计算机上监视这些信息时,read()返回0而不是-1,因此errno没有被设置。反过来说,我试着把BLDC控制器连接到上述终端,并手动重启它,以看到启动时发送的启动信息。这也很好。
在过去的3天里,我一直在滥用谷歌寻找类似的问题,但无济于事。在非阻塞性IO的几种不同的设置组合中,我也尝试了几种阻塞行为的方式,然而这导致了永远的阻塞,而且还是根本读不到任何东西。
我怀疑,虽然termios的配置中没有说明,但串口仍在期待握手/流量控制,因为将系统连接到提供RTS/CTS线的计算机上,工作正常。
int configureSerialPort() {
//Open Serial Port--------------------------------------------
int fileDescr = open("/dev/ttyS3", O_RDWR | O_NDELAY);
if (fileDescr < 0){
std::cout << "Unable to open Serial Port." << std::endl;
exit(1);
else std::cout << "Serial Port opened." << std::endl;
fcntl(fdSerial, F_SETFL, O_NONBLOCK);
//Configure Serial Port for B115200, 8N1---------
struct termios PortParams;
if (tcgetattr(fileDescr, &PortParams) < 0) {
std::cout << "Could not get Attributes." << std::endl;
exit(1);
else std::cout << "Got Attributes." << std::endl;
cfsetispeed(&PortParams, 115200);
cfsetospeed(&PortParams, 115200);
PortParams.c_cflag |= (CLOCAL | CREAD);
PortParams.c_cflag &= ~PARENB;
PortParams.c_cflag &= ~CSTOPB;
PortParams.c_cflag &= ~CSIZE;
PortParams.c_cflag |= CS8;
PortParams.c_cflag &= ~CRTSCTS;
PortParams.c_lflag &= ~(ICANON | ECHO | ECHONL | IEXTEN | ISIG);
PortParams.c_iflag &= ~(INPCK | ISTRIP | IGNPAR | PARMRK | IXON | IXOFF | IXANY);
PortParams.c_oflag &= ~OPOST;
PortParams.c_cc[VMIN] = 0;
PortParams.c_cc[VTIME] = 0;
if (tcsetattr(fileDescr, TCSANOW, &PortParams) != 0) {
std::cout << "Could not set Attributes." << std::endl;
exit(1);
else std::cout << "Port configured." << std::endl;
usleep(1000000);
tcflush(fdSerial, TCIFLUSH);
return fileDescr;
这是我到现在为止的配置,我的理解应该是没有问题的。
写入和读取是由它们各自的系统调用完成的。
wrLenSerial = write(fdSerial, &resetNode, sizeof(resetNode));
if (wrLenSerial < sizeof(resetNode)) {
std::cout << "Could not send Write Command." << std::endl;
else std::cout << "Reset Command sent." << std::endl;
usleep(60000);
memset(inBufSerial, '\0', sizeof(inBufSerial));
rdlenSerial = read(fdSerial, inBufSerial, (sizeof(inBufSerial) - 1));
if (rdlenSerial < 0) {
std::cout << "Read Error. " << errno << std::strerror(errno) << std::endl;
else if (rdlenSerial == 0) {
std::cout << "Nothing read." << std::endl;
else {
std::cout << "Node Response: ";
for (int i = 0; i < rdlenSerial; i++) {
int r = inBufSerial[i];
std::cout << std::hex << r << std::dec << " " << std::endl;
我真的希望这个帖子不要读得太长,任何想法都值得赞赏!