Есть терминал сбора данных 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 у меня более чем скромный, поэтому прошу помощи и/или указания на ошибки.
Заранее благодарен!