Структура COMMPROP - максимальные возможности драйвера COM-порта


Описание структуры COMMPROP


Все примеры приведены для среды разработки Embarcadero RAD Studio 11 (C++ Builder)

Структура COMMPROP описывает максимально возможные параметры драйвера COM-порта, выход за которые может привести (и скорей всего приведёт) к ошибкам передачи. Объявление типа находится в файле winbase.h.

typedef  struct  _COMMPROP {
    WORD wPacketLength;
    WORD wPacketVersion;
    DWORD dwServiceMask;
    DWORD dwReserved1;
    DWORD dwMaxTxQueue;
    DWORD dwMaxRxQueue;
    DWORD dwMaxBaud;
    DWORD dwProvSubType;
    DWORD dwProvCapabilities;
    DWORD dwSettableParams;
    DWORD dwSettableBaud;
    WORD wSettableData;
    WORD wSettableStopParity;
    DWORD dwCurrentTxQueue;
    DWORD dwCurrentRxQueue;
    DWORD dwProvSpec1;
    DWORD dwProvSpec2;
    WCHAR wcProvChar[1];
} COMMPROP,  *LPCOMMPROP;


Описание полей структуры COMMPROP

wPacketLength
Размер структуры COMMPROP в байтах. Размер учитывает данные в поле wcProvChar от подключенного к порту устройства.
wPacketVersion
Номер версии структуры COMMPROP.
dwServiceMask
Битовая маска. Для коммуникационных устройств всегда равна SP_SERIALCOMM.

#define  SP_SERIALCOMM  ((DWORD)0x00000001)
dwReserved1
Не используется. Должно быть установлено в 0.
dwMaxTxQueue
Максимальный размер (в байтах) внутреннего буфера передачи драйвера. Если ноль - максимальный размер буфера передачи без ограничения.
dwMaxRxQueue
Максимальный размер (в байтах) внутреннего буфера приёма драйвера. Если ноль - максимальный размер буфера приёма без ограничения.
dwMaxBaud
Максимальное значение скорости обмена в бодах (максимальный бодрейд).

// Settable baud rates in the provider.

#define BAUD_075          ((DWORD)0x00000001)
#define BAUD_110          ((DWORD)0x00000002)
#define BAUD_134_5        ((DWORD)0x00000004)
#define BAUD_150          ((DWORD)0x00000008)
#define BAUD_300          ((DWORD)0x00000010)
#define BAUD_600          ((DWORD)0x00000020)
#define BAUD_1200         ((DWORD)0x00000040)
#define BAUD_1800         ((DWORD)0x00000080)
#define BAUD_2400         ((DWORD)0x00000100)
#define BAUD_4800         ((DWORD)0x00000200)
#define BAUD_7200         ((DWORD)0x00000400)
#define BAUD_9600         ((DWORD)0x00000800)
#define BAUD_14400        ((DWORD)0x00001000)
#define BAUD_19200        ((DWORD)0x00002000)
#define BAUD_38400        ((DWORD)0x00004000)
#define BAUD_56K          ((DWORD)0x00008000)
#define BAUD_128K         ((DWORD)0x00010000)
#define BAUD_115200       ((DWORD)0x00020000)
#define BAUD_57600        ((DWORD)0x00040000)
#define BAUD_USER         ((DWORD)0x10000000)
dwProvSubType
Тип коммуникационного порта.

// Provider SubTypes

#define PST_UNSPECIFIED      ((DWORD)0x00000000)
#define PST_RS232            ((DWORD)0x00000001)
#define PST_PARALLELPORT     ((DWORD)0x00000002)
#define PST_RS422            ((DWORD)0x00000003)
#define PST_RS423            ((DWORD)0x00000004)
#define PST_RS449            ((DWORD)0x00000005)
#define PST_MODEM            ((DWORD)0x00000006)
#define PST_FAX              ((DWORD)0x00000021)
#define PST_SCANNER          ((DWORD)0x00000022)
#define PST_NETWORK_BRIDGE   ((DWORD)0x00000100)
#define PST_LAT              ((DWORD)0x00000101)
#define PST_TCPIP_TELNET     ((DWORD)0x00000102)
#define PST_X25              ((DWORD)0x00000103)
dwProvCapabilities
Битовое поле: определяет возможности, предоставляемые коммуникационным портом.

// Provider capabilities flags.

#define PCF_DTRDSR        ((DWORD)0x0001)
#define PCF_RTSCTS        ((DWORD)0x0002)
#define PCF_RLSD          ((DWORD)0x0004)
#define PCF_PARITY_CHECK  ((DWORD)0x0008)
#define PCF_XONXOFF       ((DWORD)0x0010)
#define PCF_SETXCHAR      ((DWORD)0x0020)
#define PCF_TOTALTIMEOUTS ((DWORD)0x0040)
#define PCF_INTTIMEOUTS   ((DWORD)0x0080)
#define PCF_SPECIALCHARS  ((DWORD)0x0100)
#define PCF_16BITMODE     ((DWORD)0x0200)
dwSettableParams
Битовое поле: определяет параметры порта, которые возможно изменить.

// Comm provider settable parameters.

#define SP_PARITY         ((DWORD)0x0001)
#define SP_BAUD           ((DWORD)0x0002)
#define SP_DATABITS       ((DWORD)0x0004)
#define SP_STOPBITS       ((DWORD)0x0008)
#define SP_HANDSHAKING    ((DWORD)0x0010)
#define SP_PARITY_CHECK   ((DWORD)0x0020)
#define SP_RLSD           ((DWORD)0x0040)
dwSettableBaud
Битовое поле: определяет допустимые скорости обмена.

Значения указаны в описании поля dwMaxBaud.

wSettableData
Битовое поле: определяет допустимые длины символов в передаваемых битах.

// Settable Data Bits

#define DATABITS_5        ((WORD)0x0001)
#define DATABITS_6        ((WORD)0x0002)
#define DATABITS_7        ((WORD)0x0004)
#define DATABITS_8        ((WORD)0x0008)
#define DATABITS_16       ((WORD)0x0010)
#define DATABITS_16X      ((WORD)0x0020)
wSettableStopParity
Битовое поле: определяет допустимые режимы чётности и допустимое количество стоповых битов.

// Settable Stop and Parity bits.

#define STOPBITS_10       ((WORD)0x0001)
#define STOPBITS_15       ((WORD)0x0002)
#define STOPBITS_20       ((WORD)0x0004)
#define PARITY_NONE       ((WORD)0x0100)
#define PARITY_ODD        ((WORD)0x0200)
#define PARITY_EVEN       ((WORD)0x0400)
#define PARITY_MARK       ((WORD)0x0800)
#define PARITY_SPACE      ((WORD)0x1000)
dwCurrentTxQueue
Текущий размер (в байтах) внутренней очереди передачи драйвера. Если ноль - данный параметр недоступен.
dwCurrentRxQueue
Текущий размер (в байтах) внутренней очереди приёма драйвера. Если ноль - данный параметр недоступен.
dwProvSpec1
Значение поля, установленное в COMMPROP_INITIALIZED - означает, что для структуры COMMPROP выделен достаточный объем памяти для получения в том числе и устройствозависимых данных из поля wcProvChar.
dwProvSpec2
Данные, зависящие от подключаемого к порту устройства. Если формат неизвестен - значение поля игнорируется.
wcProvChar
Данные, зависящие от подключаемого к порту устройства. Если формат неизвестен - значение поля игнорируется.




Получение информации о структуре COMMPROP

Получить информацию о структуре COMMPROP можно вызвав функцию GetCommProperies(). Прототип функции находится в файле winbase.h.

WINBASEAPI  BOOL  WINAPI  GetCommProperties(
   _In_     HANDLE      hFile,
   _Inout_  LPCOMMPROP  lpCommProp
);

-  HANDLE hFile - указатель типа void на дескриптор открытого порта.

-  LPCOMMPROP lpCommProp - указатель на структуру COMMTIMEOUTS.

При успешном вызове функции возвращаемое значение будет ненулевым (true), при ошибке функция возвращает 0 (false). Информацию о ошибке можно получить, вызвав функцию GetLastError().

Модификаторы вызова функции и аргументов:

-  WINBASEAPI (он же DECLSPEC_IMPORT, или __declspec(dllimport)) - указывает на класс хранилища функции. Позволяет получить доступ к объектам библиотеки DLL.

-  WINAPI (он же __stdcall) - соглашение о вызове функций Win32 API: аргументы передаются справа налево через стек; очистка стека ложится на вызываемую функцию; возвращаемое значение в регистре eax.

-  _In_ и _Out_ - макросы, которые вызываются только при использовании SAL2.0 — языка заметок для драйверов Windows (способ описания свойств функций, параметров, возвращаемых значений, структур и полей структуры). В данном случае не используются.



Алгоритм получения информации о структуре COMMPROP

1.  Открыть нужный порт.

2.  Выделить память в куче под структуру COMMPROP.

3.  Получить информацию из структуры COMMPROP.

4.  Если не совпадает информация о размере структуры sizeof(COMMPROP) и данных в поле wPacketLength перераспределить память по значению в поле wPacketLength. Если размер совпал, то уже получена полная информация из структуры COMMPROP, дальныйшие вычсления необязательны.

5.  Установить в поле wProvSpec1 значение COMMPROP_INITIALIZED (означает, что для структуры COMMPROP выделен достаточный объем памяти для получения в том числе и устройствозависимых данных из поля wcProvChar).

6.  Получить полную информацию из структуры COMMPROP.

#include <Windows.h>
...
HANDLE    COMport;
COMMPROP *lpCOMMPROP;
...
COMport = CreateFile(...);   //- открыть COM-порт, подставив нужные аргументы
lpCOMMPROP = (COMMPROP*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(COMMPROP));
GetCommProperties(COMport, lpCOMMPROP);

if(lpCOMMPROP->wPacketLength != sizeof(COMMPROP)) {
   lpCOMMPROP = (COMMPROP*) HeapRealloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpCOMMPROP, lpCOMMPROP->wPacketLength);
   lpCOMMPROP->wProvSpec1 = COMMPROP_INITIALIZED;
   GetCommProperties(COMport, lpCOMMPROP);
}
...
HeapFree(GetProcessHeap(), 0, lpCOMMPROP);
CloseHandle(COMport);




Сохранение информации в структуре COMMPROP

Сохранить информацию в структуре COMMPROP можно вызвав функцию SetCommTimeouts(). Прототип функции находится в файле winbase.h.

WINBASEAPI  BOOL  WINAPI  SetCommProperties(
   _In_  HANDLE      hFile,
   _In_  LPCOMMPROP  lpCommProp
);

Вызов функции в момент передачи может вызвать искажение передаваемых данных. Параметры и возвращаемые значения аналогичны GetCommProperties().