2013-02-27 195 views
7

में सीरियल पोर्ट बाधा सेटिंग IUuntu (सी में लिखे प्रोग्राम में) में एक सीरियल पोर्ट के लिए बाधा सेट करने की कोशिश कर रहा हूं, लेकिन यह काम नहीं करता है। मैंने जांच की है कि सीरियल संचार बिना रुकावट के सही तरीके से काम करता है, इसलिए मैं कुछ गलत सेट कर रहा हूं।लिनक्स

#include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    #include <unistd.h> 
    #include <sys/types.h> 
    #include <sys/socket.h> 
    #include <netinet/in.h> 
    #include <fcntl.h> 
    #include <sys/signal.h> 
    #include <errno.h> 
    #include <termios.h> 

    void signal_handler_IO (int status); /* definition of signal handler */ 

    int n; 
    int fd; 
    int connected; 
    struct termios termAttr; 
    struct sigaction saio; 

    int main(int argc, char *argv[]) 
    { 
     fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); 
     if (fd == -1) 
     { 
      perror("open_port: Unable to open /dev/ttyO1\n"); 
      exit(1); 
     } 

     saio.sa_handler = signal_handler_IO; 
     saio.sa_flags = 0; 
     saio.sa_restorer = NULL; 
     sigaction(SIGIO,&saio,NULL); 

     fcntl(fd, F_SETFL, FNDELAY); 
     fcntl(fd, F_SETOWN, getpid()); 

     tcgetattr(fd,&termAttr); 
     baudRate = B115200; 
     cfsetispeed(&termAttr,B115200); 
     cfsetospeed(&termAttr,B115200); 
     termAttr.c_cflag &= ~PARENB; 
     termAttr.c_cflag &= ~CSTOPB; 
     termAttr.c_cflag &= ~CSIZE; 
     termAttr.c_cflag |= CS8; 
     termAttr.c_cflag |= (CLOCAL | CREAD); 
     termAttr.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 
     termAttr.c_iflag &= ~(IXON | IXOFF | IXANY); 
     termAttr.c_oflag &= ~OPOST; 
     tcsetattr(fd,TCSANOW,&termAttr); 
     printf("UART1 configured....\n"); 

     connected = 1; 
     while(connected == 1){ 
       // some code 
     } 

     close(fd); 
     exit(0);    
    } 

    void signal_handler_IO (int status) 
    { 
     printf("received data from UART.\n"); 
    } 

तो कभी भी समय एक और डिवाइस के लिए कॉन्फ़िगर पोर्ट के माध्यम से एक संदेश भेजने, संदेश "UART से डेटा प्राप्त किया।": कोड पीछा कर रहा है कभी प्रदर्शित नहीं होता है।

इस समस्या को हल करने के लिए कोई सुझाव? साथ ही, सिस्टम धारावाहिक बंदरगाह के साथ बाधा से कैसे संबंधित है ?, मैंने सिग्नल.h के बारे में पढ़ा है लेकिन मुझे इसके लिए कोई जवाब नहीं मिला है। मुझे इस पृष्ठ से बाधा विचार मिला: http://www.faqs.org/docs/Linux-HOWTO/Serial-Programming-HOWTO.html

किसी भी मदद के लिए अग्रिम धन्यवाद। अग्रिम धन्यवाद।

+0

1) मैं ttyS के प्रारंभिक होने से पहले सिग्नल हैंडलर स्थापित नहीं करूंगा।2) आपको सिग्नल हैंडलर से printf() को कॉल नहीं करना चाहिए; printf() गैर-पुनर्वित्तक है। – wildplasser

+0

उत्तर देने के लिए धन्यवाद, लेकिन आपकी टिप्पणियों के बाद "बाधा" अभी भी काम नहीं करती है। कोई और विचार? – gus

उत्तर

4

समस्या यह है कि आप ध्वज F_SETFL के साथ ध्वज को साफ़ करके फ़ाइल डिस्क्रिप्टर से सिग्नल अक्षम कर रहे हैं। ,

fcntl(fd, F_SETFL, FNDELAY|FASYNC); 

इसके अलावा, आप इन झंडे (O_NDELAY और O_ASYNC) के बजाय अधिक पोर्टेबिलिटी के लिए बीएसडी नाम के लिए POSIX नाम का उपयोग करना चाह सकते हैं, हालांकि या तो काम करेंगे: आप स्थापित करने के लिए है कि आप संकेत प्राप्त करना चाहते हैं, तो जरूरत है लिनक्स पर

1

इस समस्या को हल करने के लिए कोई सुझाव? साथ ही, सिस्टम धारावाहिक बंदरगाह के साथ बाधा से कैसे संबंधित है?

सीरियल पोर्ट इंटरप्ट लिनक्स कर्नेल में सीरियल ड्राइवर के डिवाइस हिस्से के अंदर लिखा गया है। हस्तक्षेप को चालक द्वारा ही नियंत्रित किया जाता है, ताकि आप इसका नियंत्रण नहीं कर सकें।

उपरोक्त प्रोग्राम क्या कर रहा है, सिग्नल के माध्यम से आपको सूचित करता है, जब धारावाहिक भाग डिवाइस के को बाधित किया जाता है।

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

मुझे लगता है कि संकेत अपने कार्यक्रम में हैंडलिंग, ठीक तरह से लागू नहीं किया गया है बस अपने कार्यक्रम के संकेत भागों

sigset_t mskvar_1     //Variable of signal bitfieldtype 
struct sigaction sigio_action  //Structure which describes signal handler 
void sio_handler(void);    //Signal handler function 

int main() 
{ 
    sigfillset(&mskvar_1);     //set all mask bits of maskbit variable 
    sigprocmask(SIG_SETMASK,&mskvar_1,NULL); //write the mask info present in mskvar_1 to the pd 
    sigdelset(&mskvar_1,SIGIO);    //Unmask SIGIO , to register for IO Interrupt Events 

    sigio_action.sa_handler = sio_handler; //Configure Signal Handler 
    sigio_action.sa_flags = 0; 
    sigfillset(&sigio_action.sa_mask); 
    sigaction(SIGIO,&sigio_action,NULL);  //Install Signal handler 

    // Serial port initializtion here 
    // Set Serial port parameters , Baud Rate and flags 


while(1); 
return 0; 
} 


void sio_handler() 
{ 
    printf("\nSIGIO RECEIVED , I/O interrupt signalled?\n"); 
    return; 
} 
+0

आपके उत्तर के लिए धन्यवाद, लेकिन सिग्नल ("बाधा") अभी भी काम नहीं करता है, और मैंने पहले से ही जांच कर ली है कि प्रोग्राम पोर्ट के माध्यम से डेटा को सही तरीके से प्राप्त/प्रसारित करता है। क्या इस मुद्दे को हल करने के लिए आपके पास एक और दृष्टिकोण है? – gus

6

मैं ने पाया है कि कोड का एक टुकड़ा मूल कोड के रूप में काम करने के लिए याद आ रही है को सही अपेक्षित होना। नीचे दिया गया कोड जीसीसी के साथ संकलित लिनक्स पर काम कर रहा है। कोड की अतिरिक्त पंक्ति /**<<<<<<------This line made it work.**/
के साथ चिह्नित एक है, एक पंक्ति भी टिप्पणी की गई: //baudRate = B115200;

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <fcntl.h> 
#include <sys/signal.h> 
#include <errno.h> 
#include <termios.h> 

void signal_handler_IO (int status); /* definition of signal handler */ 

int n; 
int fd; 
int connected; 
struct termios termAttr; 
struct sigaction saio; 

int main(int argc, char *argv[]) 
{ 
    fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); 
    if (fd == -1) 
    { 
     perror("open_port: Unable to open /dev/ttyO1\n"); 
     exit(1); 
    } 

    saio.sa_handler = signal_handler_IO; 
    saio.sa_flags = 0; 
    saio.sa_restorer = NULL; 
    sigaction(SIGIO,&saio,NULL); 

    fcntl(fd, F_SETFL, FNDELAY); 
    fcntl(fd, F_SETOWN, getpid()); 
    fcntl(fd, F_SETFL, O_ASYNC); /**<<<<<<------This line made it work.**/ 

    tcgetattr(fd,&termAttr); 
    //baudRate = B115200;   /* Not needed */ 
    cfsetispeed(&termAttr,B115200); 
    cfsetospeed(&termAttr,B115200); 
    termAttr.c_cflag &= ~PARENB; 
    termAttr.c_cflag &= ~CSTOPB; 
    termAttr.c_cflag &= ~CSIZE; 
    termAttr.c_cflag |= CS8; 
    termAttr.c_cflag |= (CLOCAL | CREAD); 
    termAttr.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 
    termAttr.c_iflag &= ~(IXON | IXOFF | IXANY); 
    termAttr.c_oflag &= ~OPOST; 
    tcsetattr(fd,TCSANOW,&termAttr); 
    printf("UART1 configured....\n"); 

    connected = 1; 
    while(connected == 1){ 
      // some code 
    } 

    close(fd); 
    exit(0);    
} 

void signal_handler_IO (int status) 
{ 
    printf("received data from UART.\n"); 
} 

कार्यक्रम से उत्पादन किया गया था:

./a.out 
UART1 configured.... 
received data from UART. 
received data from UART. 
received data from UART. 
^C 

मुझे लगता है कि आप के लिए काम करता है भी उम्मीद है।

+0

उत्तर के लिए बहुत बहुत धन्यवाद, यह अब समझ में आता है। – gus