Перейти к содержанию

СОМ порты в Линукс. Чтение и запись.


Гость

Рекомендуемые сообщения

Вот такой возник вопрос.

Надо под Линуксов читать из СОМ порта и записывать в СОМ порт сырые данные (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);

}

Ссылка на комментарий
Поделиться на другие сайты

  • 3 месяца спустя...

А не пробовал использовать inb outb для портов 0x3f8, 0x2f8 из io.h у меня во всяком случае только таким образом удалось из одного порта в другой на локальной машине данные погонять.

Ссылка на комментарий
Поделиться на другие сайты

Может просто выложить куда нибудь исходники моей программы, там все и посмотрите. У меня в принципе все заработало, только мне нужен был один СОМ-порт, но думаю принципиальной разницы при использовании обоих нет.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
×
×
  • Создать...