[Previo por Fecha] [Siguiente por Fecha] [Previo por Hilo] [Siguiente por Hilo]
[Hilos de Discusión] [Fecha] [Tema] [Autor]Holas!! Chavos (y chavas, por si si hay :) tengo un pequeño problema existencial con el manejo del signal SIGIO, a ver si alguien sabe que rollo o se le ocurre algo tal vez no tecnico pero alguna idea de que ocurre... Ya he trabajado con diferentes signals, tengo una clase en C++ para manejo de los mismos, de hecho el problema no es el manejo de los signals en si pues eso ya me funciona, sino la particularidad de SIGIO... Estoy haciendo una clase para acceso al puerto serial, esta incluye manejo asincrono de datos (E/S asincrona sin bloqueo), lo cual requiere el uso de SIGIO... todo esto lo hice basado en el 'man termios' y el howto... Basicamente tengo estos 3 problemas: 1. En el ejemplito muy sencillo del howto de SerialProgramming simplemente abre /dev/ttySn, instala el nuevo manejador de SIGIO y con fcntl() activa el modo asincrono (O_ASYNC)... esto funciona relativamente bien, pues mando un comando al modem externo (para probar) y este me responde "\nOK\n"... el problema es que cada que hay un SIGIO (sea o no del modem) se ejecuta el nuevo manejador de señal y realiza una lectura... Nota: siempre devuelve lo mismo el read() aunque no haya datos disponibles, si por ejemplo mando un "ATZ" el modem responde "\nOK\n" una y otra vez sin parar cada que hay SIGIO... notese que el read() no devuelve error, devuelve una lectura de lo que ya habia sido leido previamente con misma longitud, en vez de devolver -1 (error) o 0 bytes leidos... 2. En un libro que tengo viene algo sobre signals y E/S asincrona, trae un ejemplo, no serial pero tambien de un descriptor de archivo, solo que con procedimiento diferente al mencionado antes. segun este funciona con SIGPOLL en vez de SIGIO, por otro lado, primero bloquea la señal, instala el nuevo manejador y desbloquea... el libro no menciona nada sobre SIGIO, pero implemente lo de bloquear SIGIO, instalar manejador y desbloquear en el primero que decia, pero el resultado es el mismo, SIGIO se llama para todos los signals de I/O... 3. Segun para capturar un signal SIGIO en un dispositivo en particular, debes usar el fcntl() con F_SETOWN y el PID del proceso que maneja el file descriptor... ya hice eso, pero al parecer le vale sombrilla y se llama el manejador del signal sea del puerto serial o de cual quier otro dispositivo de I/O... El codigo que tengo para esto es muy simple: (verlo como pseudocodigo para no tener que ilustrar todas las funciones) RS232C::RS232C (char* dev,void(*handler)(int)) { ... if ((portFD=open(dev,O_RDWR|O_NOCTTY|O_NONBLOCK))>0) { // bloquea, guarda manejador actual, // instala nuevo manejador y desbloquea vsig.signalBlock(SIGIO); vsig.handler(SIGIO,&sa_rs232c_orig); vsig.handler(SIGIO,handler); vsig.signalUnblock(SIGIO); // asigna el PID al descriptor de archivo // correspondiente a /dev/ttySn y luego // lo hace funcionar en modo asincrono fcntl(portFD, F_SETOWN, getpid()); int fd_flags = fcntl(portFD,F_GETFL,0); fcntl(portFD, F_SETFL, fd_flags|O_ASYNC); portAvail = _TRUE_; // puerdo disponible } else { printf("ERROR: %s\n",sys_errlist[errno]); portAvail = _FALSE_; } y pues ya en el programa principal la cosa esta asi resumidamente: port = new RS232C(argv[1],handler); // check if port is opened and available if (!port->getAvail()) { /* error */ exit... } termios term; term.c_iflag = INPCK; term.c_oflag = 0; term.c_cflag = CS8 | CREAD | CRTSCTS; term.c_lflag = ECHO; term.c_cc[VMIN]=1; term.c_cc[VTIME]=0; port->ioFlush(); port->setAttr (&term); port->ioFlush(); // configurar velocidad... y... char* AT = "ATZ\n"; printf("%dbytes sent\n",port->ioWrite(AT,strlen(AT))); while(1) y ya tan tan.. el rollo es ke instalo el manejador de SIGIO, envio un simple "ATZ\n" y lo dejo esperando indefinidamente con while(1) a ver que pasa... y pues me regresa OK y OK y OK una y otra vez... como demonios el read() devuelve datos si segun ya fueron leidos? osea devuelve la longitud del string de respuesta y el dato, no devuelve cero ni -1... ya para terminar, mi manejador de signal es muy simplecito... RS232C* port; // declarado global mientras prueba void handler (int stat) { char RECV[256]; int len; //printf("BINGO\n"); fflush(stdout); if ( (len=port->ioRead(RECV,256)) > 0 ) { RECV[len] = 0x00; // agrega fin cadena printf("[%d] \"%s\"",len,RECV); } else printf("handler(): ERROR..."); } Osea yo creo que todo el problema esta en la intercepcion de SIGIO, en particular al especificar que se genere para portFD (el descriptor de archivo correspondiente del puerto serial)... Alguien tendra algo de info al respecto? tal vez no del puerto serie, pero algo de I/O asincrona o de como manejar en particular el SIGIO... Sale gracias... __________________________________ Do you Yahoo!? New and Improved Yahoo! Mail - 100MB free storage! http://promotions.yahoo.com/new_mail