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

 
 
> 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

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


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

 


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


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