реклама на сайте
подробности

 
 
> COM-порт -общение компьютера с черным ящиком
MEFF
сообщение Feb 12 2010, 16:46
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 26-02-06
Пользователь №: 14 713



Есть некое устройство и программа, которая общается с ним. Исходников и документации нет.
Общается по 3-м проводам (GND, RX, TX).
Хочется написать свою программку. Сниффинг обмена вроде бы прояснил ситуацию, протокол вроде бы понятен, но с общением есть проблемы crying.gif

При работе через терминальные проги железяка или молчит в ответ на запросы, или отвечает один раз и больше не реагирует. 07.gif

Вот пример лога общения родной программы (использовал Eltima Serial Port Monitor 4, но пробовал и другие):

CODE
[12/02/2010 17:19:21] 9245 IRP_MJ_CREATE - Opens a COM port (COM1)
[12/02/2010 17:19:21] 9247 IOCTL_SERIAL_SET_QUEUE_SIZE - Request sets the size of the internal receive buffer
InSize - 1024
OutSize - 300
[12/02/2010 17:19:21] 9249 IOCTL_SERIAL_GET_BAUD_RATE
BaudRate - 9600
[12/02/2010 17:19:21] 9251 IOCTL_SERIAL_GET_LINE_CONTROL
StopBits - 0
Parity - 0
WordLength - 8
[12/02/2010 17:19:21] 9253 IOCTL_SERIAL_GET_CHARS
EofChar - 0
ErrorChar - 0
BreakChar - 0
EventChar - 0
XonChar - 17
XoffChar - 19
[12/02/2010 17:19:21] 9255 IOCTL_SERIAL_GET_HANDFLOW
ControlHandShake - 0x1 (SERIAL_DTR_CONTROL)
FlowReplace - 0x40 (SERIAL_RTS_CONTROL)
XonLimit - 2048
XoffLimit - 512

Зачем-то еще раз GET_BAUDRATE, GET_LINE_CONTROL, GET_CHARS, GET_HANDFLOW

[12/02/2010 17:19:21] 9265 IOCTL_SERIAL_SET_BAUD_RATE
BaudRate - 9600
[12/02/2010 17:19:21] 9267 IOCTL_SERIAL_SET_RTS
[12/02/2010 17:19:21] 9269 IOCTL_SERIAL_SET_DTR
[12/02/2010 17:19:21] 9271 IOCTL_SERIAL_SET_LINE_CONTROL
StopBits - 0
Parity - 0
WordLength - 8
[12/02/2010 17:19:21] 9273 IOCTL_SERIAL_SET_CHARS
EofChar - 0
ErrorChar - 0
BreakChar - 0
EventChar - 0
XonChar - 17
XoffChar - 19
[12/02/2010 17:19:21] 9275 IOCTL_SERIAL_SET_HANDFLOW - Request sets the configuration of handshake flow control
ControlHandShake - 0x1 (SERIAL_DTR_CONTROL)
FlowReplace - 0x40 (SERIAL_RTS_CONTROL)
XonLimit - 2048
XoffLimit - 512

Несколько десятков вот таких команд:

[12/02/2010 17:19:21] 9277 IRP_MJ_DEVICE_CONTROL - Request operates a serial port STATUS_SUCCESS
IOCTL_SERIAL_GET_COMMSTATUS - Request returns information about the communication status of a COM port
Errors - 0
HoldReasons - 0
AmountInInQueue - 0
AmountInOutQueue - 0
EofReceived - 0
WaitForImmediate - 0

Запрос железке:

[12/02/2010 17:19:23] 9347 IRP_MJ_DEVICE_CONTROL - Request operates a serial port STATUS_SUCCESS
IOCTL_SERIAL_SET_BREAK_ON - Sets the line control break signal active
9349 IRP_MJ_DEVICE_CONTROL - Request operates a serial port STATUS_SUCCESS
IOCTL_SERIAL_SET_BREAK_OFF - Request sets the line control break signal inactive

[12/02/2010 17:19:23] 9351 IRP_MJ_WRITE - Request transfers data from a client to a COM port STATUS_SUCCESS
00 ff ff 01 f0 a6 10 47 .??.?│.G

Вот тут непонятно, почему Errors = 1 - глюк программы-сниффера?

[12/02/2010 17:19:23] 9353 IRP_MJ_DEVICE_CONTROL - Request operates a serial port STATUS_SUCCESS
IOCTL_SERIAL_GET_COMMSTATUS - Request returns information about the communication status of a COM port
Errors - 1
HoldReasons - 0
AmountInInQueue - 0
AmountInOutQueue - 0
EofReceived - 0
WaitForImmediate - 0
[12/02/2010 17:19:23] 9355 IRP_MJ_DEVICE_CONTROL - Request operates a serial port STATUS_SUCCESS
IOCTL_SERIAL_GET_COMMSTATUS - Request returns information about the communication status of a COM port
Errors - 0
HoldReasons - 0
AmountInInQueue - 25
AmountInOutQueue - 0
EofReceived - 0
WaitForImmediate - 0

Ну и сам ответ железки:

[12/02/2010 17:19:23] 9357 IRP_MJ_READ - Transfers data from a COM port to a client STATUS_SUCCESS
00 00 00 00 01 f0 a6 10 29 99 04 50 00 00 00 00 .....?│.)T.P....
00 00 00 00 00 00 00 00 a3 99 04 50 00 00 00 00 ........?T.P....


Дальше пара IOCTL_SERIAL_GET_COMMSTATUS
IOCTL_SERIAL_SET_BREAK_ON
IOCTL_SERIAL_SET_BREAK_OFF
IRP_MJ_WRITE 00 ff ff 01 03 00 04 06 - запрос железке
IOCTL_SERIAL_GET_COMMSTATUS
IRP_MJ_READ - ответ железки

ну и т.д.




В winapi я не силен, попробовал накропать небольшую программенку, на основе каких-то примеров.

CODE
#include <windows.h>
#include <stdio.h>

HANDLE hCom;


char *pcCommPort = "COM1";


void mem_read (char *buffer, WORD addr, unsigned char count)
{
unsigned char command_mem_request [8] = {
0, 0xFF, 0xFF, 1, 0xF0, 0xA6, 0x10, 0x47 };

unsigned char buffer2 [30];

// Зачем это - не знаю.
// В логе фирменной программы была установка/снятие BREAK
SetCommBreak (hCom);
ClearCommBreak (hCom);

// Запрос железке
WriteFile (hCom, @command_mem_request, 8, &dwBytes, NULL);
if (dwBytes != 8) printf ("Error!!!\n");

// Хотим ответ
// По факту ничего не получаем
while (1)
{
ReadFile (hCom, &buffer2, 0x1, &dwBytes, NULL);
printf ("%u bytes read!\n", dwBytes);
}
}


int main(int argc, char *argv[])
{
unsigned char buffer, buffer_prev = 0xF0;
COMMTIMEOUTS CommTimeouts;
DCB dcb;

hCom = CreateFile( pcCommPort,
GENERIC_READ | GENERIC_WRITE,
0, // must be opened with exclusive-access
NULL, // no security attributes
OPEN_EXISTING, // must use OPEN_EXISTING
0, // not overlapped I/O
NULL // hTemplate must be NULL for comm devices
);

if (hCom == INVALID_HANDLE_VALUE)
{
printf ("CreateFile failed with error %d.\n", GetLastError());
return (1);
}


if (!SetupComm (hCom, 1024, 300); )
{
printf ("SetupComm with error %d.\n", GetLastError());
return (1);
}

if (!GetCommState (hCom, &dcb))
{
printf ("GetCommState failed with error %d.\n", GetLastError());
return (1);
}

dcb.BaudRate = CBR_9600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;

if (!SetCommState(hCom, &dcb))
{
printf ("SetCommState failed with error %d.\n", GetLastError());
return (1);
}

if (hCom != INVALID_HANDLE_VALUE && hCom != NULL)
printf ("COM1 cofigured!\n");

mem_read (NULL, 0xA6F0, 0x10);

return (0);
}



Лог сниффера:

CODE
IRP_MJ_CREATE
IOCTL_SERIAL_SET_QUEUE_SIZE
InSize - 1024
OutSize - 300
IOCTL_SERIAL_GET_BAUD_RATE
BaudRate - 9600
IOCTL_SERIAL_GET_LINE_CONTROL
StopBits - 0
Parity - 0
WordLength - 8
IOCTL_SERIAL_GET_CHARS
EofChar - 0
ErrorChar - 0
BreakChar - 0
EventChar - 0
XonChar - 17
XoffChar - 19
IOCTL_SERIAL_GET_HANDFLOW
ControlHandShake - 0x1 (SERIAL_DTR_CONTROL)
FlowReplace - 0x40 (SERIAL_RTS_CONTROL)
XonLimit - 2048
XoffLimit - 512

Зачем-то еще раз GET_BAUDRATE, GET_LINE_CONTROL, GET_CHARS, GET_HANDFLOW

IOCTL_SERIAL_SET_BAUD_RATE
BaudRate - 9600
IOCTL_SERIAL_SET_RTS
IOCTL_SERIAL_SET_DTR
IOCTL_SERIAL_SET_LINE_CONTROL
StopBits - 0
Parity - 0
WordLength - 8
IOCTL_SERIAL_SET_CHARS
EofChar - 0
ErrorChar - 0
BreakChar - 0
EventChar - 0
XonChar - 17
XoffChar - 19
IOCTL_SERIAL_SET_HANDFLOW
ControlHandShake - 0x1 (SERIAL_DTR_CONTROL)
FlowReplace - 0x40 (SERIAL_RTS_CONTROL)
XonLimit - 2048
XoffLimit - 512

Даем запрос устройству.

IOCTL_SERIAL_SET_BREAK_ON
IOCTL_SERIAL_SET_BREAK_OFF
IRP_MJ_WRITE 00 ff ff 01 f0 a6 10 47

И вместо ответа вот такая ерунда в цикле:

14101 IRP_MJ_READ - STATUS_TIMEOUT



Есть у кого-нибудь мысли, что я делаю не так?

Какая функция winapi вызывает IOCTL_SERIAL_GET_COMMSTATUS?

P.S. Прошу прощения за большой объем сообщения laughing.gif

Сообщение отредактировал rezident - Feb 12 2010, 23:24
Причина редактирования: Уменьшение видимого размера цитаты исходника.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Xenia
сообщение Feb 12 2010, 19:55
Сообщение #2


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Тогда не знаю...
Но если вы так быстро это проверяете, то проверьте для меня вот это:
Код
BOOL TransmitCommChar(
    HANDLE hFile,    // handle of communications device
    char cChar     // character to transmit
);

Дает ли она какой-нибудь IOCTL, а если да, то какой?
Это самая загадочная команда из всех, т.к. про нее прочти ничего не написано. А очень хотелось бы знать, в каком виде она поступает на USB-устройство.
Go to the top of the page
 
+Quote Post
MEFF
сообщение Feb 12 2010, 20:45
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 26-02-06
Пользователь №: 14 713



Цитата(Xenia @ Feb 12 2010, 22:55) *
Тогда не знаю...
Но если вы так быстро это проверяете, то проверьте для меня вот это:
Код
BOOL TransmitCommChar(
    HANDLE hFile,    // handle of communications device
    char cChar     // character to transmit
);

Дает ли она какой-нибудь IOCTL, а если да, то какой?
Это самая загадочная команда из всех, т.к. про нее прочти ничего не написано. А очень хотелось бы знать, в каком виде она поступает на USB-устройство.


[12/02/2010 22:23:32] 41636 IRP_MJ_DEVICE_CONTROL - Request operates a serial port
STATUS_SUCCESS
IOCTL_SERIAL_IMMEDIATE_CHAR - Request causes a specified character to be transmitted as soon as possible

Попробовал с помощью нее побайтно запрос отправить - все равно устройство не отвечает.
Serial Port Monitor ее как-то странно обрабатывает. Что команда есть - рисует, а в dump view (дамп принимаемых/отсылаемых байт) ничего нет. Наверное не поддерживает ее полностью =)

Цитата(UniSoft @ Feb 12 2010, 22:58) *
Скорее всего эта

Код
BOOL ClearCommError(


Спасибо! Это действительно она.
Правда, после посылки запроса и ClearCommError, железка не отвечает AmountInInQueue = 0 =(

Код
         IOCTL_SERIAL_GET_COMMSTATUS - Request returns information about the communication status of a COM port
            Errors - 0
            HoldReasons - 0
            AmountInInQueue - 0
            AmountInOutQueue - 0
            EofReceived - 0
            WaitForImmediate - 0


То ли порт как-то хитро инициализируется, то ли что.... =(

Сообщение отредактировал MEFF - Feb 12 2010, 21:07
Go to the top of the page
 
+Quote Post

Сообщений в этой теме


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 20:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01406 секунд с 7
ELECTRONIX ©2004-2016