2012-10-22 20 views
13

समाशोधन यह मेरा समारोह सीरियल पोर्ट (Ubuntu 12.04 का उपयोग कर) खोलने के लिए कैसा दिखता है:,सीरियल पोर्ट के बफर

int open_port(void) 
{ 
    int fd; /* File descriptor for the port */ 

    fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); 

    if (fd == -1) 
    { 
    // Could not open the port.   
    perror("open_port: Unable to open /dev/ttyUSB0 - "); 
    } 
    else 
    fcntl(fd, F_SETFL, 0); 

    struct termios options; 

    tcgetattr(fd, &options); 
    //setting baud rates and stuff 
    cfsetispeed(&options, B19200); 
    cfsetospeed(&options, B19200); 
    options.c_cflag |= (CLOCAL | CREAD); 
    tcsetattr(fd, TCSANOW, &options); 

    tcsetattr(fd, TCSAFLUSH, &options); 

    options.c_cflag &= ~PARENB;//next 4 lines setting 8N1 
    options.c_cflag &= ~CSTOPB; 
    options.c_cflag &= ~CSIZE; 
    options.c_cflag |= CS8; 

    //options.c_cflag &= ~CNEW_RTSCTS; 

    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //raw input 

    options.c_iflag &= ~(IXON | IXOFF | IXANY); //disable software flow control 

    return (fd); 
} 

क्या समस्या है जाता है कि जब मैं इस कार्यक्रम चलाने के लिए और मेरे धारावाहिक डिवाइस है, तो पहले से ही प्लग इन किया गया था, बफर में सामग्री है। इससे पहले कि मैं इसे पढ़ना शुरू कर दूं, मुझे बफर को साफ़ करने का एक तरीका चाहिए। मैंने सोचा कि tcsetattr(fd, TCSAFLUSH, &options); का उपयोग बंदरगाह शुरू करने से पहले आईओ बफर को फ्लश करके इस समस्या को ठीक करेगा, लेकिन ऐसी कोई किस्मत नहीं। कोई अंतर्दृष्टि?

उत्तर

16

मुझे लगता है कि मैंने इसे समझ लिया। किसी कारण से, मुझे फ्लश करने से पहले देरी जोड़नी होगी। इन दो पंक्तियों को fdलौटने से पहले जोड़ा चाल किया है लगता है:

sleep(2); //required to make flush work, for some reason 
    tcflush(fd,TCIOFLUSH); 
+11

उम्मीद है कि कोई हमें बता सकता है कि यह क्यों काम करता है :-) –

+0

+1 मैं भी इससे थोड़ा सा स्टंप हूं। –

+1

मुझे लगता है कि यह लिनक्स कर्नेल में यह बग था: http://lkml.iu.edu//hypermail/linux/kernel/0707.3/1776.html –

2

इस समस्या के कारण एक यूएसबी सीरियल पोर्ट का उपयोग करने में निहित है। यदि आप नियमित सीरियल पोर्ट का उपयोग करते हैं, तो आपको यह समस्या नहीं होगी।

अधिकांश यूएसबी सीरियल पोर्ट ड्राइवर ठीक से फ्लशिंग का समर्थन नहीं करते हैं, शायद इसलिए यह जानने का कोई तरीका नहीं है कि आंतरिक शिफ्ट रजिस्टर, फीफो या यूएसबी सबसिस्टम में अभी भी डेटा है या नहीं।

ग्रेग के उत्तर में here की रिपोर्ट की गई एक समान समस्या का उत्तर भी देखें।

आपकी sleep समस्या का इलाज कर सकती है, लेकिन यह केवल एक काम है। दुर्भाग्य से नियमित सीरियल पोर्ट का उपयोग करने के अलावा कोई समाधान नहीं है।

1

मुझे एक Arduino Uno बोर्ड के साथ समान लक्षणों का सामना करना पड़ रहा है जो खुले() पर रीसेट करता है। मैं ओपन() कॉल के बाद डेटा प्राप्त कर रहा था जो Arduino बोर्ड रीसेट करने से पहले उत्पन्न हुआ था और इस प्रकार खुले() से पहले कहा गया था।

ioctl() कॉल के साथ समस्या को ट्रैक करना मैंने सीखा कि डेटा अभी तक इनपुट बफर में अभी तक नहीं आया था जब तक tcflush() को बुलाया गया था। तो tcflush() ने काम किया लेकिन फ्लश करने के लिए कोई डेटा नहीं था। खुले() कॉल के बाद 1000 की नींद इस मुद्दे को हल करने लगती थी। ऐसा इसलिए होता है क्योंकि देरी से टीसीफ्लश() को कॉल करने से पहले डेटा आने की इजाजत होती है और इसलिए टीसीएफएलयूश() वास्तव में इनपुट बफर को फ्लश करता है।

आपको एक ही समस्या का सामना करना पड़ सकता है।

संबंधित मुद्दे