2009-11-18 20 views
6

विफल रहता है मैं निम्नलिखित सी कार्यक्रम है:सीरियल पोर्ट से पढ़ना

#include <fcntl.h> 
#include <termios.h> 
#include <stdio.h> 

int main() 
{ 
    int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK); 
    if(fd < 0) 
    { 
     perror("Could not open device"); 
    } 
    printf("Device opened\n"); 

    struct termios options; 
    tcgetattr(fd, &options); 
    cfmakeraw(&options); 
    cfsetispeed(&options, B19200); 
    cfsetospeed(&options, B19200); 
    tcsetattr(fd, TCSANOW, &options); 

    char txpacket[] = {0x23, 0x06, 0x00, 0x00, 0xdd, 0xf9}; 
    ssize_t written = write(fd, txpacket, sizeof(txpacket)); 
    printf("Written %d bytes\n", written); 

    printf("Starting to wait for target to respond\n"); 
    while(1) 
    { 
     fd_set readset; 
     FD_ZERO(&readset); 
     FD_SET(fd, &readset); 
     int nCount = select(fd + 1, &readset, NULL, NULL, NULL); 
     if(nCount > 0) 
     { 
      if(FD_ISSET(fd, &readset)) 
      { 
       int i; 
       char buffer[128]; 
       ssize_t bytesread = read(fd, buffer, sizeof(buffer)); 
       printf("Received %d bytes\n", bytesread); 
       for(i = 0; i < bytesread; i++) 
       { 
        printf(" %02x", buffer[i]); 
       } 
      } 
     } 
    } 
} 

इस कार्यक्रम के धारावाहिक डिवाइस/dev/ttyS0, यह करने के लिए डेटा का एक अनुक्रम लिखते हैं और एक प्रतिक्रिया के लिए सुन शुरू होता है खोलता है। मुझे निम्न आउटपुट मिलता है:

Device opened 
Written 6 bytes 
Starting to wait for target to respond 
Received 0 bytes 
Received 0 bytes 
Received 0 bytes 
Received 0 bytes 
Received 0 bytes 
Received 0 bytes 
... 

और एप्लिकेशन 100% CPU का उपभोग करता है। मैं कोई डेटा प्राप्त करने में सक्षम नहीं हूं, भले ही लक्ष्य हार्डवेयर वास्तव में इसे प्रसारित करता है।

क्या गलत है?

उत्तर

7

read() लौटने वाला 0 अंत-ऑफ-फाइल स्थिति इंगित करता है। यदि आप ऐसा करते हैं तो आपको इसके लिए जांच करनी चाहिए और लूप से बाहर निकलना चाहिए।

इसके कारण क्या है - एक धारावाहिक बंदरगाह पर अंत-फ़ाइल से संकेत मिलता है कि यह एक हैंगअप का पता चला है, जिसका अर्थ है कि डीसीडी लाइन गिरा दी गई है।

यदि आप डिवाइस ठीक से सेट नहीं करते हैं तो आप मॉडेम नियंत्रण लाइनों को अनदेखा करने के लिए options.c_cflag में CLOCAL ध्वज सेट कर सकते हैं।

+0

धन्यवाद! वास्तव में समस्या का कारण क्या था। – anorm

+0

अरे, क्लॉकल चीज़ नहीं देखी! – shodanex

+0

एक ही समस्या थी, टिप के लिए धन्यवाद। Cfmakeraw उन दो स्पष्ट झंडे को नहीं देखते थे। – RishiD

1

आपको O_NONBLOCK ध्वज के बिना प्रयास करना चाहिए। कच्चे मोड में, अगर c_cc[VMIN] की सेटिंग और c_cc[VTIME] 0, है सीरियल पोर्ट (आदमी cfmakeraw के अनुसार) इस तरह व्यवहार करते हैं:

तो डेटा उपलब्ध है, रिटर्न तुरंत पढ़ संख्या के कम से बाइट्स उपलब्ध है, या अनुरोधित बाइट्स की संख्या। यदि कोई डेटा उपलब्ध है, रिटर्न 0

पढ़ा तो क्या आप का प्रयास करना चाहिए है:

options->c_cc[VMIN]=1; 
+0

एक अजीब कोने मामले पर वास्तव में अच्छा नोट। – Joe

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