Гость Опубликовано 26 февраля, 2004 Жалоба Поделиться Опубликовано 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); } Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 24 марта, 2004 Жалоба Поделиться Опубликовано 24 марта, 2004 Добрый день Юрий!! Через ttySx не работал Писал прямо в порты в/в - ioperm - inb/outb Работало ) Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 8 июня, 2004 Жалоба Поделиться Опубликовано 8 июня, 2004 Если можно, поподробнее, пожалуйста! Так как это как раз то, чем я сейчас озабочен. Вы делали это из пользовательского режима, затем iopl(3)? Вы пользовались прерываниями? Если "да", то это ф-ия request_irq? Правильно ли я понимаю, что сделав "#include ? (получаются повторные описания одних типов), и, например, эхо на экран остаётся делать только kernel-версией printf? Какие #includes вообще нужны. Ежели выложите код, хотя бы часть буду безмерно благодарен. Спасибо. Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.