LINUX.ORG.RU

Проблема установок параметров СОМ порта.


0

0

Есть проблема.

Есть свой софт для работы с СОМ потом. Проблема в том, что не устанавливаются параметры СОМ порта. Т.е. когда звёзды на небе хорошо стоят софт работает, когда плохо софт не работает. Помогите изгнать чертей и всё бесовское что порожает эти глюки. Правильно ли я открываю и инициализирую СОМ порт?

int set_up_comms( char *device, int baud_i, char *parity, int stopb )

{

int ttyfd;

struct termios settings;

int char_interval_timeout;

speed_t baud_rate;

#if QNX4 | QNX6

if(( ttyfd = open( device,(O_RDWR | O_NOCTTY | O_NONBLOCK | O_BINARY) ) ) < 0 )

{

printf("ERROR: set_up_comms: %s\n",strerror(errno));

return(-1);

}

#else

if(( ttyfd = open( device,(O_RDWR | O_NOCTTY | O_NONBLOCK) ) ) < 0 )

{

printf("ERROR: set_up_comms: %s\n",strerror(errno));

return(-1);

}

#endif

tcgetattr(ttyfd,&settings);

// cfmakeraw(&settings);

#if DEBUG

fprintf( stderr, "opening %s\n", device );

#endif

switch( baud_i )

{

case 110:

baud_rate = 110;

char_interval_timeout = TO_B110;

break;

case 300:

baud_rate = 300;

char_interval_timeout = TO_B300;

break;

case 600:

baud_rate = 600;

char_interval_timeout = TO_B600;

break;

case 1200:

baud_rate = 1200;

char_interval_timeout = TO_B1200;

break;

case 2400:

baud_rate = 2400;

char_interval_timeout = TO_B2400;

break;

case 4800:

baud_rate = 4800;

char_interval_timeout = TO_B4800;

break;

case 9600: case 0:

baud_rate = 9600; //baud_rate = B9600;

char_interval_timeout = TO_B9600;

//char_interval_timeout = 9600;

break;

case 19200:

baud_rate = 19200;

char_interval_timeout = TO_B19200;

break;

case 38400:

baud_rate = 38400;

char_interval_timeout = TO_B38400;

break;

case 57600:

baud_rate = 57600;

char_interval_timeout = TO_B57600;

break;

case 115200:

baud_rate = 115200;

char_interval_timeout = TO_B115200;

break;

default:

baud_rate = 9600;

char_interval_timeout = TO_B9600;

fprintf(stderr, "Unknown baud rate %d for %s.", baud_i, device);

}

#if DEBUG

fprintf( stderr, "%s open\n", device );

#endif

cfsetispeed( &settings, baud_rate );/* Set the baud rate */

cfsetospeed( &settings, baud_rate );

settings.c_cflag &= ~HUPCL;

settings.c_cflag &= ~CLOCAL;

#if QNX4 | QNX6

settings.c_cflag &= ~IHFLOW;

settings.c_cflag &= ~OHFLOW;

//---Off Flow Control Flags

settings.c_qflag &= ~(TC_PROTECT_HFLOW|TC_PROTECT_SFLOW|TC_WAIT_SFLOW|TC_ECHOI); //---Set Flag -ohpaged

tcflow(ttyfd, TCOONHW);

#endif

settings.c_cc[VMIN] = 1;

settings.c_cc[VTIME] = 0;

settings.c_cflag &=~ CSIZE;

settings.c_cflag |= CS8;

if(stopb==1)

settings.c_cflag &=~ CSTOPB;//one STOP BIT

else

settings.c_cflag |= CSTOPB;//two STOP BIT

if( strncmp( parity, "none", 4 ) == 0 )

{

settings.c_cflag &=~ PARENB;

settings.c_cflag &=~ PARODD;

} else

if( strncmp( parity, "even", 4 ) == 0 )

{

settings.c_cflag |= PARENB;

settings.c_cflag &=~ PARODD;

} else {

settings.c_cflag |= PARENB;

settings.c_cflag |= PARODD;

}

if( tcsetattr( ttyfd, TCSANOW, &settings ) < 0 )

{

fprintf( stderr, "tcsetattr failed: %s\n",strerror(errno));

exit( 1 );

} tcflush(ttyfd, TCIOFLUSH); dtr_off(ttyfd);

return( ttyfd );

}

★★

1. Зачем трогаеш dtr???/

2. ты слишком много оставляеш на самотёк

3. ОЧЕНЬ избыточный код.

cvv ★★★★★
()
Ответ на: комментарий от cvv

1. dtr дёргаю чтобы перевести 485 интерфейс в состояние чтения

2. что именно я оставляю на самотёк?

3. в чём заключается избыточность кола? Что лишнее?

binr ★★
() автор топика
Ответ на: комментарий от binr

>1. dtr дёргаю чтобы перевести 485 интерфейс в состояние чтения

в смысле твой порт автоматом не переключается????

>2. что именно я оставляю на самотёк?

по минимуму ты дожен установить ВСЕ флаги устанавливаемые закомментированой тобой функцией cfmakeraw в нужное тебе состояние

>3. в чём заключается избыточность кола? Что лишнее?

эт тебе другие раскажут если заглянут в твой тред. а не то переспроси в толках

cvv ★★★★★
()
Ответ на: комментарий от cvv

>в смысле твой порт автоматом не переключается???? не переключается, начальство слышать не хочет про moxa, денег жалко

> эт тебе другие раскажут если заглянут в твой тред. а не то переспроси в толках

что есть толки?

binr ★★
() автор топика
Ответ на: комментарий от cvv

Почему этот исходник не меняет скорость СОМ порта?

Ктонибудь, откомпилите, у себя попробуйте, посмотрите пожалуйста поменялалсь ли скорость СОМ порта, что бя ыя мог хотя бы исключить софтовую ошибку...

Извиниляюсь за тупые претупые вопросы, но блин не могу ни чего понять...

#include <termios.h> #include <errno.h> #include <fcntl.h> #include <errno.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <stdlib.h>

#define TO_B110 3200000 /* These values are the timeout delays */ #define TO_B300 1600000 /* at the end of packets of data. */ #define TO_B600 800000 /* At this stage a true calculation */ #define TO_B1200 400000 /* has not been worked out. So these */ #define TO_B2400 200000 /* values are just a guess. */ #define TO_B4800 100000 /* */ #define TO_B9600 50000 /* The spec says that a message frame */ #define TO_B19200 25000 /* starts after a silent interval of */ #define TO_B38400 12500 /* at least 3.5 character times. */ #define TO_B57600 8333 /* These are uS times. */ #define TO_B115200 4167

int set_up_comms( char *device, int baud_i, char *parity, int stopb ) { int ttyfd; struct termios settings; int char_interval_timeout; speed_t baud_rate;

#if QNX4 | QNX6 if(( ttyfd = open( device,(O_RDWR | O_NOCTTY | O_NONBLOCK | O_BINARY) ) ) < 0 ) { printf("ERROR: set_up_comms: %s\n",strerror(errno)); return(-1); } #else if(( ttyfd = open( device,(O_RDWR | O_NOCTTY | O_NONBLOCK) ) ) < 0 ) { printf("ERROR: set_up_comms: %s\n",strerror(errno)); return(-1); } #endif

tcgetattr(ttyfd,&settings);

#if DEBUG fprintf( stderr, "opening %s\n", device ); #endif

switch( baud_i ) { case 110: baud_rate = 110; char_interval_timeout = TO_B110; break; case 300: baud_rate = 300; char_interval_timeout = TO_B300; break; case 600: baud_rate = 600; char_interval_timeout = TO_B600; break; case 1200: baud_rate = 1200; char_interval_timeout = TO_B1200; break; case 2400: baud_rate = 2400; char_interval_timeout = TO_B2400; break; case 4800: baud_rate = 4800; char_interval_timeout = TO_B4800; break; case 9600: case 0: baud_rate = 9600; //baud_rate = B9600; char_interval_timeout = TO_B9600; //char_interval_timeout = 9600; break; case 19200: baud_rate = 19200; char_interval_timeout = TO_B19200; break; case 38400: baud_rate = 38400; char_interval_timeout = TO_B38400; break; case 57600: baud_rate = 57600; char_interval_timeout = TO_B57600; break; case 115200: baud_rate = 115200; char_interval_timeout = TO_B115200; break; default: baud_rate = 9600; char_interval_timeout = TO_B9600; fprintf(stderr, "Unknown baud rate %d for %s.", baud_i, device); }

#if DEBUG fprintf( stderr, "%s open\n", device ); #endif

cfsetispeed( &settings, baud_rate );/* Set the baud rate */ cfsetospeed( &settings, baud_rate );

settings.c_cflag &= ~HUPCL; settings.c_cflag &= ~CLOCAL;

#if QNX4 | QNX6 settings.c_cflag &= ~IHFLOW; settings.c_cflag &= ~OHFLOW; //---Off Flow Control Flags settings.c_qflag &= ~(TC_PROTECT_HFLOW|TC_PROTECT_SFLOW|TC_WAIT_SFLOW|TC_ECHOI); //---Set Flag -ohpaged tcflow(ttyfd, TCOONHW); #endif

settings.c_cc[VMIN] = 1; settings.c_cc[VTIME] = 0;

settings.c_cflag &=~ CSIZE; settings.c_cflag |= CS8;

cfmakeraw(&settings);

if(stopb==1) settings.c_cflag &=~ CSTOPB;//one STOP BIT else settings.c_cflag |= CSTOPB;//two STOP BIT

if( strncmp( parity, "none", 4 ) == 0 ) { settings.c_cflag &=~ PARENB; settings.c_cflag &=~ PARODD; } else if( strncmp( parity, "even", 4 ) == 0 ) { settings.c_cflag |= PARENB; settings.c_cflag &=~ PARODD; } else { settings.c_cflag |= PARENB; settings.c_cflag |= PARODD; }

if( tcsetattr( ttyfd, TCSANOW, &settings ) < 0 ) { fprintf( stderr, "tcsetattr failed: %s\n",strerror(errno)); exit( 1 ); } tcflush(ttyfd, TCIOFLUSH); // dtr_off(ttyfd);

return( ttyfd ); }

int StrParityInt(unsigned char *parity) { int result=0; if( strncmp( parity, "none", 4 ) == 0 ) { result=0; } else if( strncmp( parity, "even", 4 ) == 0 ) { result=1; } else { result=2; } return(result); } int StrComInt(unsigned char *name) { int result=0; #if QNX result=atoi(&name[8]); #endif

#if LINUX result=atoi(&name[9]); #endif return(result); }

int main(void) { int fd=0; fd=set_up_comms("/dev/ttyS0",115200,"even",2); printf("test_com: set_up_comms=%d\n", fd); close(fd); return(0); }

binr ★★
() автор топика
Ответ на: комментарий от cvv

Почему этот исходник не меняет скорость СОМ порта?

Ктонибудь, откомпилите, у себя попробуйте, посмотрите пожалуйста поменялалсь ли скорость СОМ порта, что бя ыя мог хотя бы исключить софтовую ошибку...

Извиниляюсь за тупые претупые вопросы, но блин не могу ни чего понять...

#include <termios.h>

#include <errno.h>

#include <fcntl.h>

#include <errno.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#define TO_B110 3200000 /* These values are the timeout delays */

#define TO_B300 1600000 /* at the end of packets of data. */

#define TO_B600 800000 /* At this stage a true calculation */

#define TO_B1200 400000 /* has not been worked out. So these */

#define TO_B2400 200000 /* values are just a guess. */

#define TO_B4800 100000 /* */

#define TO_B9600 50000 /* The spec says that a message frame */

#define TO_B19200 25000 /* starts after a silent interval of */

#define TO_B38400 12500 /* at least 3.5 character times. */

#define TO_B57600 8333 /* These are uS times. */ #define TO_B115200 4167

int set_up_comms( char *device, int baud_i, char *parity, int stopb )

{ int ttyfd;

struct termios settings;

int char_interval_timeout;

speed_t baud_rate;

#if QNX4 | QNX6

if(( ttyfd = open( device,(O_RDWR | O_NOCTTY | O_NONBLOCK | O_BINARY) ) ) < 0 )

{

printf("ERROR: set_up_comms: %s\n",strerror(errno));

return(-1);

} #else

if(( ttyfd = open( device,(O_RDWR | O_NOCTTY | O_NONBLOCK) ) ) < 0 )

{

printf("ERROR: set_up_comms: %s\n",strerror(errno));

return(-1);

}

#endif

tcgetattr(ttyfd,&settings);

#if DEBUG

fprintf( stderr, "opening %s\n", device );

#endif

switch( baud_i )

{

case 110:

baud_rate = 110;

char_interval_timeout = TO_B110;

break;

case 300:

baud_rate = 300;

char_interval_timeout = TO_B300;

break;

case 600:

baud_rate = 600;

char_interval_timeout = TO_B600;

break;

case 1200:

baud_rate = 1200;

char_interval_timeout = TO_B1200;

break;

case 2400:

baud_rate = 2400;

char_interval_timeout = TO_B2400;

break;

case 4800:

baud_rate = 4800;

char_interval_timeout = TO_B4800;

break;

case 9600: case 0:

baud_rate = 9600; //baud_rate = B9600;

char_interval_timeout = TO_B9600;

//char_interval_timeout = 9600;

break;

case 19200:

baud_rate = 19200;

char_interval_timeout = TO_B19200;

break;

case 38400:

baud_rate = 38400;

char_interval_timeout = TO_B38400;

break;

case 57600:

baud_rate = 57600;

char_interval_timeout = TO_B57600;

break;

case 115200:

baud_rate = 115200;

char_interval_timeout = TO_B115200;

break;

default:

baud_rate = 9600;

char_interval_timeout = TO_B9600;

fprintf(stderr, "Unknown baud rate %d for %s.", baud_i, device);

}

#if DEBUG

fprintf( stderr, "%s open\n", device );

#endif

cfsetispeed( &settings, baud_rate );/* Set the baud rate */

cfsetospeed( &settings, baud_rate );

settings.c_cflag &= ~HUPCL;

settings.c_cflag &= ~CLOCAL;

#if QNX4 | QNX6

settings.c_cflag &= ~IHFLOW;

settings.c_cflag &= ~OHFLOW;

//---Off Flow Control Flags

settings.c_qflag &= ~(TC_PROTECT_HFLOW|TC_PROTECT_SFLOW|TC_WAIT_SFLOW|TC_ECHOI); //---Set Flag -ohpaged

tcflow(ttyfd, TCOONHW);

#endif

settings.c_cc[VMIN] = 1;

settings.c_cc[VTIME] = 0;

settings.c_cflag &=~ CSIZE;

settings.c_cflag |= CS8;

cfmakeraw(&settings);

if(stopb==1)

settings.c_cflag &=~ CSTOPB;//one STOP BIT

else

settings.c_cflag |= CSTOPB;//two STOP BIT

if( strncmp( parity, "none", 4 ) == 0 )

{

settings.c_cflag &=~ PARENB;

settings.c_cflag &=~ PARODD;

} else

if( strncmp( parity, "even", 4 ) == 0 )

{

settings.c_cflag |= PARENB;

settings.c_cflag &=~ PARODD;

}

else

{

settings.c_cflag |= PARENB;

settings.c_cflag |= PARODD;

}

if( tcsetattr( ttyfd, TCSANOW, &settings ) < 0 )

{

fprintf( stderr, "tcsetattr failed: %s\n",strerror(errno));

exit( 1 );

} tcflush(ttyfd, TCIOFLUSH); // dtr_off(ttyfd);

return( ttyfd );

}

int StrParityInt(unsigned char *parity)

{

int result=0; if( strncmp( parity, "none", 4 ) == 0 )

{

result=0;

}

else

if( strncmp( parity, "even", 4 ) == 0 )

{

result=1;

}

else

{

result=2;

} return(result);

} int StrComInt(unsigned char *name)

{

int result=0;

#if QNX

result=atoi(&name[8]);

#endif

#if LINUX

result=atoi(&name[9]);

#endif return(result);

}

int main(void)

{

int fd=0; fd=set_up_comms("/dev/ttyS0",115200,"even",2);

printf("test_com: set_up_comms=%d\n", fd);

close(fd); return(0);

}

binr ★★
() автор топика
Ответ на: комментарий от anonymous2

Разобрался с этим Г.

В общем в ядрах 2.4.20, 2.4.27, 2.4.30, 2.6.8 не работают функции cfsetispeed() и cfsetospeed(), зато работает cfsetspeed()

При этом "man cfsetispeed" и "man cfsetospeed" печатают доки, а "man cfsetspeed" не печатает доку.

Использую Debian Sarge + обновления Sarge с dvd диска журнала linuxformat

Предлагаю занести это в FAQ, что бы другие программёры не заморачиавались, особенно начинающие.

Мои поздравления.

binr ★★
() автор топика
Ответ на: комментарий от binr

>В общем в ядрах 2.4.20, 2.4.27, 2.4.30, 2.6.8 не работают функции cfsetispeed() и cfsetospeed(), зато работает cfsetspeed()

Эти ф-и не имеют никакого отношения к ядру. то что они не работают - это специфика твоей glibc

cvv ★★★★★
()
Ответ на: комментарий от cvv

Мало этого.

Выяснилось следущее, как надо работать с СОМ пртом:
1. open()
2. настройка СОМ порта
3. close();//после этого изменения вступают в силу!
4. open()
5. работа приложения
6. завершения приложения, close()

супер?

Что делать с glibc? как  её поменять на нормальную?
 

binr ★★
() автор топика
Ответ на: комментарий от binr

2binr:

> Разобрался с этим Г.

Нет, не разобрался.

Посмотрим на твой код:

...
speed_t baud_rate;
...
switch( baud_i ) {
...
baud_rate = 110;
...
/* ну и так далее */
...
baud_rate = 115200;
}
...
cfsetospeed( &settings, baud_rate );


Теперь _вдумчиво_ фтыкаем в man cfsetospeed:

int cfsetospeed(struct termios *termios_p, speed_t speed);

cfsetospeed() sets the output baud rate stored in the termios
structure pointed to by termios_p to speed, which must be one
of these constants:
B0
B50
B75
B110
B134
B150
B200
B300
B600
B1200
B1800
B2400
B4800
B9600
B19200
B38400
B57600
B115200
B230400


Асалил?
Надо не cfsetospeed(&settings, 2400) а cfsetospeed( &settings, B2400);
Функция хочет не скорость в виде числа, а фиксированное значение,
макрос, соотвествующий этой скорости.

И если бы удосужился _проверять_ коды возврата, ты бы AFAIK понял,
что cfsetospeed() выругалась на твои аргументы (вернула -1), и ты
бы распечатал текст при помощи perror(). Но ты конечно выше
этого.

Быстро читать http://www.tldp.org/HOWTO/Serial-Programming-HOWTO/ и
http://www.easysw.com/~mike/serial/serial.html

> Мои поздравления.

Мои соболезнования :-(

HTH

Onanim
()
Ответ на: комментарий от Onanim

Ужас какой... За такие программы надо кастрировать...

anonymous
()
Ответ на: комментарий от Onanim

ок по поводу макросов виноват... Странно что всё это раньше работало... но ладно... софт переносится с одной операционки в другую...

1. Но проблема к установками СОМ порта осталась, всё равно надо открывать и закрывать, что бы установки СОМ порта активизировались...
2. Функция cfsetspeed() в отличии от cfsetispeed() и cfsetospeed() ловко проглатывает ЗНАЧЕНИЕ скорости и макроса похоже не требует, видимо дань совместимости с BSD 4.4

binr ★★
() автор топика
Ответ на: комментарий от binr


> 1. Но проблема к установками СОМ порта осталась, всё равно надо
> открывать и закрывать, что бы установки СОМ порта активизировались.

Ты сделал по-человечески, с cfsetospeed() и макросами?
Кстати, как ты определяешь, что "установки СОМ порта не активизировались"?
Если хочешь, запости минимальный рабочий пример, я попробую.

> это всё надо в faq...

Что "это"? Все "это" есть в документации. И литературе.

> на одной debian sarge man cfsetspeed работает на другом debian sarge
> не работает...
>

cfsetspeed() присутствует для compatibility. Она не специфицирована
SUS (AFAIK). Зачем ее использовать? Искать трудностей и преодолевать
их?

Onanim
()
Ответ на: комментарий от Onanim

>Ты сделал по-человечески, с cfsetospeed() и макросами? да, с макросами

>Кстати, как ты определяешь, что "установки СОМ порта не активизировались"?

Есть калабашка, к которой достукиваемся по СОМ порту. Если выполяем цикл open()/tcgetattr()/tcsetattr()/close() то после следующего open() обмен данными с калабашкой идёт нормально. Если выполняем просто цикл сopen()/tcgetattr()/tcsetattr()/обмен данными/close(), то обмена данными нет. Я понимаю что кривой способ и раньше всё было по другому, но сейчас почемуто нужен первый цикл открытия/настройк/закрытия порта...

>cfsetspeed() присутствует для compatibility. Она не специфицирована SUS (AFAIK). Зачем ее использовать? Искать трудностей и преодолевать их?

cfsetspeed() по всей видимости использует скорость, т.к. значение скорость отличается от значения макроса. Вроде работает, но рагьше у меня с cfsetispeed(), cfsetospeed() всё было ок.

binr ★★
() автор топика
Ответ на: комментарий от binr

>> Кстати, как ты определяешь, что "установки СОМ порта не 
>> активизировались"?

> Есть калабашка, к которой достукиваемся по СОМ порту...

Калабашка - это пять :-) Очень технический термин :-)

Проведем все-таки эксперимент:

# cat spt.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>

#define _POSIX_SOURCE 1

void die(char* msg) { perror(msg); exit(1); }
 
int main()
{
    int fd;
    struct termios oldtio, newtio;
 
    system("stty -a </dev/ttyS0");
 
    if ( (fd = open("/dev/ttyS0", O_RDWR|O_NOCTTY)) < 0 )  die("open");
    if ( tcgetattr(fd, &oldtio) == -1 )                    die("tcgetattr");
    newtio = oldtio;
    if ( cfsetospeed(&newtio, B38400) == -1 )              die("cfsetospeed");
    if ( tcsetattr(fd, TCSANOW, &newtio) == -1 )           die("tcsetattr");
 
    puts("\n-----------------------------\n");
     
    system("stty -a </dev/ttyS0");
     
    if ( tcsetattr(fd, TCSANOW, &oldtio) == -1 )           die("restoring old tcsetattr");
}

# make spt
cc     spt.c   -o spt
#
#
# ./spt
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; start = ^Q; stop = ^S;
susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
 
-----------------------------
 
speed 38400 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; start = ^Q; stop = ^S;
susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
#

Ну что, вроде скорость меняется, не так ли?

Onanim
()
Ответ на: комментарий от Onanim

Визуально "видно" что твоя программа работает, т.е. визуально видно  что скорость СОМ порта меняется, но на самом деле она не меняется.
Это выясняется при попытке передачи данных.

1. замыкаю кабелем /dev/ttyS0 и /dev/ttyS1
2. проверяю соединение кабеля
2.1 stty -F /dev/ttyS0 38400 raw
2.2 stty -F /dev/ttyS1 38400 raw
2.3 в одной консоли cat /dev/ttyS0
2.4 в другой консоли ls / >> /dev/ttyS1
2.5 всё замечательно, кабель целый

3 твою программу немного модернизировал, исходник ниже
3.1 stty -F /dev/ttyS0 110 raw
3.2 stty -F /dev/ttyS1 38400 raw
3.3. cat /dev/ttyS1
3.4 в другой консоли запускаю твою модернизированную программу
3.5 cat в другой консоли ни чего не печатает!

В твоей программе я добавил  вывод данных write() после установки новых параметров СОМ порта, затем
задержку перед установкой старых параметров СОМ порта.
Пробовал коментировать write() и послыать данные из третьей консоли ls / >> /dev/ttyS0 пока работает slee()... всё также, обмена данными нет.
 Вывод: визуально кажется, что скорость устанавливается, на саомом деле она не меняется и обмена данными не происходит. А если менять скорость, с помощью утилиты stty, то обмен данными
идёт ровно на 115200 быстро, на 110 медленно.

Изменённая твоя программа:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>

#define _POSIX_SOURCE 1

void die(char* msg) { perror(msg); exit(1); }
 
int main()
{
    int fd=0, size=0;
    struct termios oldtio, newtio;
    unsigned char data[]="Hello World!\n";

    size=strlen(data);    
 
    system("stty -a </dev/ttyS0");
 
    if ( (fd = open("/dev/ttyS0", O_RDWR|O_NOCTTY)) < 0 )  die("open");
    if ( tcgetattr(fd, &oldtio) == -1 )                    die("tcgetattr");
    newtio = oldtio;
    cfmakeraw(&newtio);
    if ( cfsetospeed(&newtio, B38400) == -1 )              die("cfsetospeed");
    if ( cfsetispeed(&newtio, B38400) == -1 )              die("cfsetispeed");
    if ( tcsetattr(fd, TCSANOW, &newtio) == -1 )           die("tcsetattr");
//    if ( write(fd, data, size) != size ) die("write");
     
//    puts("\n-----------------------------\n");
     
    system("stty -a </dev/ttyS0");

    sleep(20);

    if ( tcsetattr(fd, TCSANOW, &oldtio) == -1 )           die("restoring old tcsetattr");
    else printf(" sed old settings for /dev/ttyS0\n");
} 

binr ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.