J'essaie de définir l'interruption d'un port série à Ubuntu (dans le programme écrit en C), mais cela ne fonctionne pas. J'ai vérifié que la communication série fonctionne correctement sans interruption, je peux donc créer quelque chose de mal. Le code est le suivant:
#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"); }
3 Réponses :
Toute suggestion pour résoudre ce problème? En outre, comment le système raconte-t-il l'interruption avec le port série? P>
L'interruption de port série est écrite à l'intérieur de la partie de périphérique du pilote série du noyau Linux. L'interruption est traitée par le conducteur lui-même, de sorte que vous ne pouvez pas le contrôler. P>
Quel est le programme ci-dessus, vous notifiez-vous à travers un signal, lors d'une interruption de réception du dispositif de partie série est déclenché. P>
Le traitement du signal ci-dessus n'est pas lié aux interruptions, il est plus difficile de manipuler. Tout d'abord, vous vous inscrivez, votre programme, pour obtenir un signal lorsqu'une interruption d'Io est terminée, le gestionnaire de signal de votre programme affichera ensuite le message Printf. P>
Je pense que la manipulation du signal de votre programme n'est pas mise en œuvre correctement. Juste corriger les parties du signal de votre programme p>
xxx pré> blockQquote>
Merci de votre réponse, mais le signal ("interruption") ne fonctionne toujours pas et j'ai déjà vérifié que le programme reçoit / transmet des données via le port correctement. Avez-vous une autre approche pour résoudre ce problème?
J'ai trouvé qu'un morceau de code est manquant pour que le code d'origine fonctionne comme prévu. Le code ci-dessous fonctionne sur Linux compilé avec GCC. La ligne de code ajoutée est celle marquée avec La sortie du programme était la suivante: p> / **
Une ligne a également été commentée: // baudred = b115200; code>.
./a.out
UART1 configured....
received data from UART.
received data from UART.
received data from UART.
^C
Merci beaucoup pour la réponse, cela a du sens maintenant.
Pourquoi votre sortie est-elle affichée 3 fois?
Y a-t-il un moyen d'afficher une fois?
Le problème est que vous désactivez les signaux du descripteur de fichier en nettoyant le drapeau FASYNC code> avec
f_setfl code>. Vous devez définir que si vous souhaitez obtenir des signaux:
fcntl(fd, F_SETFL, FNDELAY|FASYNC);
1) Je n'installerais pas le gestionnaire de signal avant que l'initialisation des TTYS soit terminée. 2) Vous ne devez pas appeler printf () à partir d'un gestionnaire de signal; printf () est non reentrant.
Merci d'avoir répondu, mais à la suite de vos commentaires, "l'interruption" ne fonctionne toujours pas. Plus d'idées?