के लिए चुनिंदा() का उपयोग करना मैं एक ऐसे प्रोजेक्ट पर काम कर रहा हूं जिसमें मुझे सीरियल पोर्ट से डेटा पढ़ने और लिखने की ज़रूरत है, और इसके कारणों में गैर-अवरुद्ध होने की आवश्यकता है क्योंकि मैं नहीं जाऊंगा। चयन() फ़ंक्शन ऐसा लगता है जो मैं उपयोग करना चाहता हूं, लेकिन मैं कामकाजी कार्यान्वयन के साथ संघर्ष कर रहा हूं।नॉनब्लॉकिंग सीरियल
open_port() में मैं बंदरगाह के लिए सेटिंग्स को परिभाषित करता हूं और यह गैर-अवरुद्ध है। अन्य चयन में() मैं descriptor को open_port() में पढ़ता हूं और पढ़ने का प्रयास करता हूं। हार्डवेयर के लिए पढ़ने के लिए तेजी से पढ़ने से बचने के प्रयास में मेरे पास फ़ंक्शन के अंत में 1 सेकंड की नींद कॉल भी है।
चलते समय मुझे संदेश भेजने से पहले "कोई डेटा उपलब्ध नहीं" के लिए प्रत्येक सेकेंड में एक संदेश प्रिंटिंग मिलता है, और जब मैं एक संदेश भेजता हूं तो यह प्रिंट करता है, लेकिन आमतौर पर इसके साथ बाइनरी वर्णों के टुकड़े होते हैं। उदाहरण के लिए, "बफर" शब्द भेजते समय यह एक बाइनरी चरित्र के बाद "फेफर" प्रिंट करेगा।
मुझे टर्मियो या चयन के साथ लगभग कोई अनुभव नहीं है, इसलिए किसी भी सुझाव की सराहना की जाएगी।
#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();
}
}
क्योंकि यह सी ++ है, क्या आपने इसके लिए boost :: asio का उपयोग करने पर विचार किया है? – moooeeeep
क्या आपको अपने ओपन() कॉल में 'O_NONBLOCK' की आवश्यकता नहीं होगी, वास्तव में इसे गैर-अवरुद्ध करने के लिए? संपादित करें: आईआईआरसी, 'O_NDELAY' बस डीसीडी के लिए इंतजार कर रहा है, जबकि' O_NONBLOCK' वास्तव में किसी भी इनपुट के इंतजार किए बिना चला जाता है। – favoretti
O_NDELAY को fcntl.h में O_NONBLOCK के बराबर सेट किया गया है, वे बराबर हैं। मैंने अभी तक बूस्ट :: एएसओओ में नहीं देखा है, और मैं अब यह करूँगा, लेकिन मुझे वास्तव में विकल्प चुनने की इच्छा है कि चयन करने के लिए डेटा है() –