gpt4 book ai didi

c++ - 使用 select() 进行非阻塞串行

转载 作者:IT王子 更新时间:2023-10-29 00:15:11 27 4
gpt4 key购买 nike

我正在做一个项目,我需要从串行端口读取和写入数据,这需要是非阻塞的,原因我不会深入探讨。 select() 函数看起来像我想要使用的函数,但我正在努力获得一个有效的实现。

在 open_port() 中,我定义了端口的设置并且它是非阻塞的。在 otherselect() 中,我将描述符分配给 open_port() 并尝试读取。我在函数末尾还有一个 1 秒的 sleep 调用,试图避免硬件读取速度过快。

运行时,在发送消息之前,我每秒打印一条消息“无可用数据”,在发送消息之后,它打印出来,但它通常是带有二进制字符的片段。例如,当发送单词“buffer”时,它将打印“ffer”,后跟一个二进制字符。

我几乎没有使用 termios 或 select 的经验,所以任何建议将不胜感激。

#include <iostream>
#include "stdio.h"
#include "termios.h"
#include "errno.h"
#include "fcntl.h"
#include "string.h"
#include "time.h"
#include "sys/select.h"

using namespace std;

int open_port(){
struct termios oldtio,newtio;
int serial_fd;
if ((serial_fd = open("/dev/ttyS0", O_RDWR | O_EXCL | O_NDELAY)) == -1) {
cout << "unable to open" << endl;
return -1;
}
if (tcgetattr(serial_fd, &oldtio) == -1) {
cout << "tcgetattr failed" << endl;
return -1;
}
cfmakeraw(&newtio); // Clean all settings
newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS8 | B115200; // 8 databits
newtio.c_cflag |= (CLOCAL | CREAD);
newtio.c_cflag &= ~(PARENB | PARODD); // No parity
newtio.c_cflag &= ~CRTSCTS; // No hardware handshake
newtio.c_cflag &= ~CSTOPB; // 1 stopbit
newtio.c_iflag = IGNBRK;
newtio.c_iflag &= ~(IXON | IXOFF | IXANY); // No software handshake
newtio.c_lflag = 0;
newtio.c_oflag = 0;
newtio.c_cc[VTIME] = 1;
newtio.c_cc[VMIN] = 60;
if (tcsetattr(serial_fd, TCSANOW, &newtio) == -1) {
cout << "tcsetattr failed" << endl;
return -1;
}
tcflush(serial_fd, TCIOFLUSH); // Clear IO buffer
return serial_fd;
}

void otherselect(){
fd_set readfs;
timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
char * buffer = new char[15];
int _fd = open_port();
FD_ZERO(&readfs);
FD_SET(_fd, &readfs);
select(_fd+1, &readfs, NULL, NULL, &tv /* no timeout */);
if (FD_ISSET(_fd, &readfs))
{
int r = read(_fd, buffer, 15);
if(r == -1){
cout << strerror(errno) << endl;
}
cout << buffer << endl;
}
else{
cout << "data not available" << endl;
}
close(_fd);
sleep(1);
}

int main() {
while(1){
otherselect();
}
}

最佳答案

当你使用 read() 时,你不会得到一个以 null 结尾的字符串,所以

cout<<buffer<<endl

显然是个坏主意。做一个,

buffer[r]='\0'  #(provided r<15)

在打印出来之前。

关于c++ - 使用 select() 进行非阻塞串行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11749048/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com