Jump to content

Recommended Posts

Posted

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

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

См. исходники mgetty, ppp, etc.

P.S.

За конструкции вида

if(com_port==1)

убивать надо =))

Posted

А можно узнать почему? Switch что ли использовать?

Posted

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

Posted

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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...