Guest Posted February 26, 2004 Report Posted February 26, 2004 Вот такой возник вопрос. Надо под Линуксов читать из СОМ порта и записывать в СОМ порт сырые данные (raw mode). Никакой приличной документации, кроме serial programming how-to не нашел. Пришлось работать с ней. Вот написал следующий код (см ниже). Проверял так. На машине соединял 2 СОМ порта, что нуль модемным кабелем, что кабелем (2-3, 3-2, 5-5) и запускал на одной консоли запись, на другой чтение. Писать записывает, читать не читает. Подскажите пожайлуста, что я делаю не так. Пример запуска: ./my_serial 1 R - чтение 1 СОМ порта ./my_serial 2 W - запись во 2 СОМ порт без параметров - запись во 1 СОМ порт На всякий случай ссылочка на zip-архив с исходным текстом. http://www.raskat.ru/3.zip #include #include #include #include #include #include #include #include #include //#include //#include #define BAUDRATE B9600 #define READ 1 #define WRITE 2 /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ int MAX (int vol1, int vol2) { if(vol1 > vol2) return (vol1); else return (vol2); } /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ int open_com_port(char *str) { int local_fd; struct termios oldtio, newtio; local_fd = open(str, O_RDWR | O_NOCTTY | O_NDELAY); if (local_fd < 0) { perror(str); return(-1); } fcntl(local_fd, F_SETFL, FNDELAY); tcgetattr(local_fd,&oldtio); oldtio.c_cflag |= ( BAUDRATE | CLOCAL | CREAD | CRTSCTS | CS8 ); oldtio.c_lflag &= ~(ICANON | ECHO | ECHOE); oldtio.c_oflag &= ~(OPOST); oldtio.c_iflag = ( IXON | IXOFF | IXANY ); // newtio.c_cc[VMIN] = 1; // newtio.c_cc[VTIME] = 0; tcflush(local_fd, TCIFLUSH); tcsetattr(local_fd,TCSANOW,&oldtio); return (local_fd); } /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ main(int argc, char **argv) { int i; int counter=0; int fd; int read_write, com_port; fd_set readfs, writefs; int ret_val; int maxfd; // (maximum file desciptor used) int loop=1; char string[10]={"123456789"}; char buf[255]; if(argc!=3) { read_write=WRITE; com_port=1; } else { com_port=atoi(argv[1]); if(argv[2][0]=='R') read_write=READ; if(argv[2][0]=='W') read_write=WRITE; } if(com_port==1) { fd = open_com_port("/dev/ttyS0"); /* COM1 */ if (fd<0) { printf("Error open COM-1\n"); exit(0); } } if(com_port==2) { fd = open_com_port("/dev/ttyS1"); /* COM2 */ if (fd<0) { printf("Error open COM-2\n"); exit(0); } } struct timeval tv; tv.tv_sec = 3; tv.tv_usec = 0; if(read_write==READ) { for(; { FD_SET(fd, &readfs); ret_val = select(fd, &readfs, NULL, NULL, &tv); // printf("READ counter=%d loop=%d\n", counter, loop); if( ret_val) { if (i=FD_ISSET(fd, &readfs)) { ret_val=read(fd,buf,sizeof(buf)); printf("%d read from COM-%d %d byte: %s\n", i, com_port, ret_val, buf); } sleep(1); counter++; // if(counter >= 5) loop=0; } else { printf("No data at 3 sec\n"); tv.tv_sec = 3; tv.tv_usec = 0; counter++; if(counter >= 5) loop=0; } } } else if(read_write==WRITE) { for(; { FD_SET(fd, &writefs); ret_val = select(fd+1, NULL, &writefs, NULL, &tv); // printf("WRITE counter=%d loop=%d ret_val=%d\n", counter, loop, ret_val); if( ret_val) { i=FD_ISSET(fd, &writefs); printf("FD_ISSET=%d\n",i); if (i) { printf("write to COM-%d %s\n", com_port, string); if( (ret_val=write(fd,string,strlen(string))) < 0 ) { printf("Error writing to COM-%d\n", com_port); } else { printf("write COM-%d %d - %d\n", com_port, i, ret_val); } } sleep(1); counter++; // if(counter >= 5) loop=0; } else { printf("No data at 3 sec\n"); tv.tv_sec = 3; tv.tv_usec = 0; counter++; // if(counter >= 5) loop=0; } // if(loop == 0) // { // FD_CLR(fd1, &readfs); // FD_CLR(fd2, &readfs); // FD_CLR(fd1, &writefs); // FD_CLR(fd2, &writefs); // break; // } } } close(fd); printf("close all ports\n"); exit(1); } Quote
Guest Posted June 22, 2004 Report Posted June 22, 2004 См. исходники mgetty, ppp, etc. P.S. За конструкции вида if(com_port==1) убивать надо =)) Quote
Guest Posted June 28, 2004 Report Posted June 28, 2004 А можно узнать почему? Switch что ли использовать? Quote
Guest Posted June 28, 2004 Report Posted June 28, 2004 А не пробовал использовать inb outb для портов 0x3f8, 0x2f8 из io.h у меня во всяком случае только таким образом удалось из одного порта в другой на локальной машине данные погонять. Quote
Guest Posted June 29, 2004 Report Posted June 29, 2004 Может просто выложить куда нибудь исходники моей программы, там все и посмотрите. У меня в принципе все заработало, только мне нужен был один СОМ-порт, но думаю принципиальной разницы при использовании обоих нет. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.