Программирование RS232 устройства (Попытки подобрать протокол для ТСД)

Модератор: Модераторы разделов

reinhard
Сообщения: 86
ОС: Fedora Core, FreeBSD

Программирование RS232 устройства

Сообщение reinhard »

Всем привет!

Есть терминал сбора данных CIPHERLAB 8001 с последовательным интерфейсом. Программа для загрузки в него данных только под Windows. Требуется, чтобы он заработал под Linux. Под wine не заработала.
Под виндой запускаю HHD Serial port monitor и запускаю обмен данными. Программа и устройство настроены на 115200.
Вот такой протокол обмена (по данным монитора).

Код: Выделить всё

0,IRP_MJ_CREATE,DOWN,TRUE,0x0,44 00 4C 00 6F 00 6F 00 6B 00 75 00 70 00 2E 00 65 00 78 00 65 00 00 00 ,D.L.o.o.k.u.p...e.x.e...,
1,IRP_MJ_CREATE,UP,FALSE,0x0,,,
2,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_QUEUE_SIZE: Set queue size),DOWN,TRUE,0x0,00 01 00 00 B0 04 00 00 ,.......,
3,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_QUEUE_SIZE: Set queue size),UP,FALSE,0x0,,,
4,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_TIMEOUTS: Retrieve timeouts),DOWN,FALSE,0x0,,,
5,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_TIMEOUTS: Retrieve timeouts),UP,TRUE,0x0,FF FF FF FF 00 00 00 00 00 00 00 00 05 00 00 00 32 00 00 00 ,yyyy............2...,
6,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_TIMEOUTS: Set timeouts),DOWN,TRUE,0x0,FF FF FF FF 00 00 00 00 00 00 00 00 05 00 00 00 32 00 00 00 ,yyyy............2...,
7,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_TIMEOUTS: Set timeouts),UP,FALSE,0x0,,,
8,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_BAUD_RATE: Retrieve Baud Rate),DOWN,FALSE,0x0,,,
9,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_BAUD_RATE: Retrieve Baud Rate),UP,TRUE,0x0,00 C2 01 00 ,.A..,
10,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_LINE_CONTROL: Retrieve line control),DOWN,FALSE,0x0,,,
11,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_LINE_CONTROL: Retrieve line control),UP,TRUE,0x0,00 00 08 ,...,
12,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_CHARS: Retrieve special characters),DOWN,FALSE,0x0,,,
13,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_CHARS: Retrieve special characters),UP,TRUE,0x0,00 00 00 00 00 00 ,......,
14,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_HANDFLOW: Retrieve handshake information),DOWN,FALSE,0x0,,,
15,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_HANDFLOW: Retrieve handshake information),UP,TRUE,0x0,01 00 00 00 40 00 00 00 00 08 00 00 00 02 00 00 ,....@...........,
16,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_BAUD_RATE: Set baud rate),DOWN,TRUE,0x0,00 96 00 00 ,.?..,
17,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_BAUD_RATE: Set baud rate),UP,FALSE,0x0,,,
18,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_RTS: Set RTS),DOWN,FALSE,0x0,,,
19,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_RTS: Set RTS),UP,FALSE,0x0,,,
20,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_DTR: Set DTR),DOWN,FALSE,0x0,,,
21,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_DTR: Set DTR),UP,FALSE,0x0,,,
22,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_LINE_CONTROL: Set line control),DOWN,TRUE,0x0,00 00 08 ,...,
23,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_LINE_CONTROL: Set line control),UP,FALSE,0x0,,,
24,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_CHARS: Set special characters),DOWN,TRUE,0x0,00 00 00 00 00 00 ,......,
25,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_CHARS: Set special characters),UP,FALSE,0x0,,,
26,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_HANDFLOW: Set handshake information),DOWN,TRUE,0x0,01 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 ,....@...........,
27,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_HANDFLOW: Set handshake information),UP,FALSE,0x0,,,
28,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_BAUD_RATE: Retrieve Baud Rate),DOWN,FALSE,0x0,,,
29,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_BAUD_RATE: Retrieve Baud Rate),UP,TRUE,0x0,00 96 00 00 ,.?..,
30,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_LINE_CONTROL: Retrieve line control),DOWN,FALSE,0x0,,,
31,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_LINE_CONTROL: Retrieve line control),UP,TRUE,0x0,00 00 08 ,...,
32,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_CHARS: Retrieve special characters),DOWN,FALSE,0x0,,,
33,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_CHARS: Retrieve special characters),UP,TRUE,0x0,00 00 00 00 00 00 ,......,
34,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_HANDFLOW: Retrieve handshake information),DOWN,FALSE,0x0,,,
35,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_HANDFLOW: Retrieve handshake information),UP,TRUE,0x0,01 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 ,....@...........,
36,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_BAUD_RATE: Set baud rate),DOWN,TRUE,0x0,80 25 00 00 ,?%..,
37,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_BAUD_RATE: Set baud rate),UP,FALSE,0x0,,,
38,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_CLR_RTS: Clear RTS),DOWN,FALSE,0x0,,,
39,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_CLR_RTS: Clear RTS),UP,FALSE,0x0,,,
40,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_DTR: Set DTR),DOWN,FALSE,0x0,,,
41,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_DTR: Set DTR),UP,FALSE,0x0,,,
42,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_LINE_CONTROL: Set line control),DOWN,TRUE,0x0,00 00 08 ,...,
43,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_LINE_CONTROL: Set line control),UP,FALSE,0x0,,,
44,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_CHARS: Set special characters),DOWN,TRUE,0x0,00 00 00 00 00 00 ,......,
45,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_CHARS: Set special characters),UP,FALSE,0x0,,,
46,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_HANDFLOW: Set handshake information),DOWN,TRUE,0x0,01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ,................,
47,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_HANDFLOW: Set handshake information),UP,FALSE,0x0,,,
48,IRP_MJ_WRITE,DOWN,TRUE,0x0,0F ,.,
49,IRP_MJ_WRITE,UP,TRUE,0x0,0F ,.,
50,IRP_MJ_READ,DOWN,FALSE,0x0,,,
51,IRP_MJ_READ,UP,FALSE,0x0,,,
52,IRP_MJ_READ,DOWN,FALSE,0x0,,,


Далее около 20 тыс. строчек, повторяющих строчки 50-51.
Затем:

Код: Выделить всё

22814,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_BAUD_RATE: Retrieve Baud Rate),DOWN,FALSE,0x0,,,
22815,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_BAUD_RATE: Retrieve Baud Rate),UP,TRUE,0x0,80 25 00 00 ,?%..,
22816,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_LINE_CONTROL: Retrieve line control),DOWN,FALSE,0x0,,,
22817,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_LINE_CONTROL: Retrieve line control),UP,TRUE,0x0,00 00 08 ,...,
22818,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_CHARS: Retrieve special characters),DOWN,FALSE,0x0,,,
22819,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_CHARS: Retrieve special characters),UP,TRUE,0x0,00 00 00 00 00 00 ,......,
22820,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_HANDFLOW: Retrieve handshake information),DOWN,FALSE,0x0,,,
22821,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_HANDFLOW: Retrieve handshake information),UP,TRUE,0x0,01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ,................,
22822,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_BAUD_RATE: Set baud rate),DOWN,TRUE,0x0,80 25 00 00 ,?%..,
22823,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_BAUD_RATE: Set baud rate),UP,FALSE,0x0,,,
22824,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_RTS: Set RTS),DOWN,FALSE,0x0,,,
22825,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_RTS: Set RTS),UP,FALSE,0x0,,,
22826,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_DTR: Set DTR),DOWN,FALSE,0x0,,,
22827,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_DTR: Set DTR),UP,FALSE,0x0,,,
22828,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_LINE_CONTROL: Set line control),DOWN,TRUE,0x0,00 00 08 ,...,
22829,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_LINE_CONTROL: Set line control),UP,FALSE,0x0,,,
22830,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_CHARS: Set special characters),DOWN,TRUE,0x0,00 00 00 00 00 00 ,......,
22831,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_CHARS: Set special characters),UP,FALSE,0x0,,,
22832,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_HANDFLOW: Set handshake information),DOWN,TRUE,0x0,01 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 ,....@...........,
22833,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_HANDFLOW: Set handshake information),UP,FALSE,0x0,,,
22834,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_BAUD_RATE: Retrieve Baud Rate),DOWN,FALSE,0x0,,,
22835,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_BAUD_RATE: Retrieve Baud Rate),UP,TRUE,0x0,80 25 00 00 ,?%..,
22836,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_LINE_CONTROL: Retrieve line control),DOWN,FALSE,0x0,,,
22837,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_LINE_CONTROL: Retrieve line control),UP,TRUE,0x0,00 00 08 ,...,
22838,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_CHARS: Retrieve special characters),DOWN,FALSE,0x0,,,
22839,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_CHARS: Retrieve special characters),UP,TRUE,0x0,00 00 00 00 00 00 ,......,
22840,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_HANDFLOW: Retrieve handshake information),DOWN,FALSE,0x0,,,
22841,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_HANDFLOW: Retrieve handshake information),UP,TRUE,0x0,01 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 ,....@...........,
22842,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_BAUD_RATE: Set baud rate),DOWN,TRUE,0x0,00 C2 01 00 ,.A..,
22843,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_BAUD_RATE: Set baud rate),UP,FALSE,0x0,,,
22844,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_CLR_RTS: Clear RTS),DOWN,FALSE,0x0,,,
22845,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_CLR_RTS: Clear RTS),UP,FALSE,0x0,,,
22846,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_DTR: Set DTR),DOWN,FALSE,0x0,,,
22847,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_DTR: Set DTR),UP,FALSE,0x0,,,
22848,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_LINE_CONTROL: Set line control),DOWN,TRUE,0x0,00 00 08 ,...,
22849,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_LINE_CONTROL: Set line control),UP,FALSE,0x0,,,
22850,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_CHARS: Set special characters),DOWN,TRUE,0x0,00 00 00 00 00 00 ,......,
22851,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_CHARS: Set special characters),UP,FALSE,0x0,,,
22852,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_HANDFLOW: Set handshake information),DOWN,TRUE,0x0,01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ,................,                                                                             22853,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_HANDFLOW: Set handshake information),UP,FALSE,0x0,,,                                                              22854,IRP_MJ_WRITE,DOWN,TRUE,0x0,0F ,.,
22855,IRP_MJ_WRITE,UP,TRUE,0x0,0F ,.,
22856,IRP_MJ_READ,DOWN,FALSE,0x0,,,
22857,IRP_MJ_READ,UP,TRUE,0x0,0F ,.,


Далее протокол продолжается, я его "прицепил".
Но мне не удается дойти даже до этого места.

Вот как я понимаю что происходит:
комп лочит порт на 9600, сбрасывает RTS, посылает устройству символ с кодом 0x0f, пытается прочитать из порта, у него ничего не выходит.
Затем он лочит порт на 115200, сбрасывает RTS, посылает устройству символ с кодом 0x0f, и на этот раз успешно читает его из порта.
Осталось непонятным что означает

[red]IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_HANDFLOW: Set handshake information),DOWN,TRUE,0x0,01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ,................,[red]
Понятно, что это установка параметров handshake, но каких именно - не могу нигде найти. Подозреваю, что проблема именно в этом.

Вот код программы:

Код: Выделить всё

#include <stdio.h>
#include <string.h>  /* Объявления строковых функций */
#include <unistd.h>  /* Объявления стандартных функций UNIX */
#include <fcntl.h>   /* Объявления управления файлами */
#include <errno.h>   /* Объявления кодов ошибок */
#include <termios.h> /* Объявления управления POSIX-терминалом */
#include <sys/ioctl.h>

int main(void)
{
int            fd;
struct termios options;
char buffer[255];  /* буфер ввода */
char *bufptr;      /* текущий символ в буфере */
char *curptr;
int  nbytes;       /* число прочитанных байтов*/
int  tries;        /* число попыток */
int status;
/* открытие порта */
fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0)
   {
   perror("open_port: Unable to open - ");
   return(2);
   }
fcntl(fd, F_SETFL, 0);

/* получение текущих опций */
tcgetattr(fd, &options);

/* установка неструктурированного ввода, 1-секундный таймаут */
options.c_cflag     |= (CLOCAL | CREAD);
options.c_lflag     &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag     &= ~OPOST;
options.c_cc[VMIN]  = 0;
options.c_cc[VTIME] = 10;
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
/* установка опций */
tcsetattr(fd, TCSANOW, &options);

ioctl(fd, TIOCMGET, &status);
status &= ~TIOCM_RTS;
ioctl(fd, TIOCMSET, &status);
ioctl(fd, TIOCMGET, &status);
printf ("RTS - %x\n",status & TIOCM_RTS);
printf ("DTR - %x\n",status & TIOCM_DTR);
if (write(fd, "\x0f", 1) < 1)
   {
   printf("write error\n");
   }
//printf("write 0x0f complete!\n");
bufptr = buffer;
while ((nbytes = read(fd, bufptr, buffer + sizeof(buffer) - bufptr - 1)) > 0)
    {
    bufptr += nbytes;
    if (bufptr[-1] == '\x0f')
      break;
    }
if (bufptr == buffer)
   {
   printf("No Data!\n");
   }
else
   {
   printf("%d symbols read\n",bufptr-buffer);
   for(curptr=buffer;curptr<bufptr;curptr++)
      {
      printf("%x %c\n",*curptr, *curptr);
      }
   }

tcgetattr(fd, &options);
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
tcsetattr(fd, TCSANOW, &options);
ioctl(fd, TIOCMGET, &status);
status &= ~TIOCM_RTS;
ioctl(fd, TIOCMSET, &status);
ioctl(fd, TIOCMGET, &status);
printf ("RTS - %x\n",status & TIOCM_RTS);
printf ("DTR - %x\n",status & TIOCM_DTR);
if (write(fd, "\x0f", 1) < 1)
   {
   printf("write error\n");
   }

bufptr = buffer;
while ((nbytes = read(fd, bufptr, buffer + sizeof(buffer) - bufptr - 1)) > 0)
    {
    bufptr += nbytes;
    if (bufptr[-1] == '\x0f')
      break;
    }
if (bufptr == buffer)
   {
   printf("No Data!\n");
   }
else
   {
   printf("%d symbols read\n",bufptr-buffer);
   for(curptr=buffer;curptr<bufptr;curptr++)
      {
      printf("%x %c\n",*curptr, *curptr);
      }
   }
return(0);
}


Будучи запущенной программа выводит

Код: Выделить всё

RTS - 0
DTR - 2
No Data!
RTS - 0
DTR - 2
No Data!


т.е. записала успешно, а прочитать не удалось в обоих случаях.
Пробоват подключать модем и писать в него AT - все работало, т.е.
Опыт программирования RS232 у меня более чем скромный, поэтому прошу помощи и/или указания на ошибки.
Заранее благодарен!
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Спасибо сказали:
diafour
Сообщения: 14

Re: Программирование RS232 устройства

Сообщение diafour »

Попробуйте явно добавить размерность байта:

- options.c_cflag |= (CLOCAL | CREAD);
+ options.c_cflag |= (CS8 | CLOCAL | CREAD);


22848,IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_SET_LINE_CONTROL: Set line control),DOWN,TRUE,0x0,00 00 08
00 - 1 стоповый бит
00 - без четности
08 - 8 битовый байт
Спасибо сказали:
reinhard
Сообщения: 86
ОС: Fedora Core, FreeBSD

Re: Программирование RS232 устройства

Сообщение reinhard »

diafour писал(а):
10.07.2007 11:43
Попробуйте явно добавить размерность байта:


Попробовал, не помогло.
Спасибо сказали:
diafour
Сообщения: 14

Re: Программирование RS232 устройства

Сообщение diafour »

http://www.linuxjournal.com/node/7000/print

Вот что нашлось.
Along with the tty structure changes, a few tty ioctls have been removed, specifically the TIOCMGET, TIOCMBIS, TIOCMBIC and TIOCMSET ioctls.
Это не ваш случай?
Спасибо сказали:
reinhard
Сообщения: 86
ОС: Fedora Core, FreeBSD

Re: Программирование RS232 устройства

Сообщение reinhard »

diafour писал(а):
10.07.2007 15:10
Along with the tty structure changes, a few tty ioctls have been removed, specifically the TIOCMGET, TIOCMBIS, TIOCMBIC and TIOCMSET ioctls.
Это не ваш случай?


Странно...
То есть TIOCMGET теперь не работает?
Там еще написано
They have been replaced with two new function callbacks, tiocmget and tiocmset, that have been added to the struct tty_operations structure.


Однако

Код: Выделить всё

grep -R tiocmget /usr/include/*

не показывает ничего, а TIOCMGET определен в /usr/include/asm/ioctls.h

Код: Выделить всё

Linux oldb.bit.ab.ru 2.6.18-1.2798.fc6 #1 SMP Mon Oct 16 14:54:20 EDT 2006 i686 i686 i386 GNU/Linux


Опять же, ioctl(fd, TIOCMGET, &status) что-то возвращает...
Спасибо сказали:
reinhard
Сообщения: 86
ОС: Fedora Core, FreeBSD

Re: Программирование RS232 устройства

Сообщение reinhard »

Поставил на винду portmon. Там вроде более понятно расшифровывается. Но все равно непонятно.

Код: Выделить всё

6041    0.00000726      DLookup.exe     IOCTL_SERIAL_SET_CHAR   Serial1 SUCCESS EOF:0 ERR:0 BRK:0 EVT:0 XON:0 XOFF:0
6042    0.00001145      DLookup.exe     IOCTL_SERIAL_SET_HANDFLOW       Serial1 SUCCESS Shake:1 Replace:0 XonLimit:0 XoffLimit:0


Как из-под Linux установить символы ERR,BRK,EVT,XON,XOFF в 0?
Как выставить Shake, Replace, XonLimit, XoffLimit?

Код: Выделить всё

6088    0.00000140      DLookup.exe     IOCTL_SERIAL_SET_TIMEOUTS       Serial1 SUCCESS RI:-1 RM:0 RC:0 WM:5 WC:50


Как выставить эти таймауты?
termios(3) прочитан, ответа нет.
Спасибо сказали:
vladsleeping
Сообщения: 1
ОС: Linux

Re: Программирование RS232 устройства

Сообщение vladsleeping »

Доброго дня!
По работе в «наследство» досталась тестовая прога для модуля с интерфейсом RS-232. Режим работы порта 8N1, без контроля четности, скорость 115200.
В процедуре записи в порт после вызова write идёт следующая конструкция:

Код: Выделить всё

    write ( fd, buf, len );
    do
    {
        usleep(1);
        ioctl ( fd, TIOCSERGETLSR, &status );
    } while (!(status & TIOCSER_TEMT));

    status |= TIOCM_RTS;
    ioctl ( fd, TIOCMBIC, &status );
return 0;

Так как тест запускается на персоналке, то usleep (1) на поверку выливается в паузу 20 мс (судя по всему, минимальный тик таймера), что является слишком долгим интервалом при работе с модулем. Попробовал закомментить usleep, в результате RTS выставляется ранее, чем успевают передаться данные, и последний байт данных теряется.
Попробовал вместо do-while использовать tcdrain(fd) – та же история с потерей последнего байта. Совместное использование tcdrain и затем do-while выливается в задержки переменной длины 5…13 мс, что тоже слишком долго.
Вот пытаюсь понять, что же сделать, чтобы RTS сбрасывался вовремя, а не слишком рано или чрезмерно поздно =)
Спасибо сказали: