Структура 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
#define SP_SERIALCOMM ((DWORD)0x00000001)
// 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)
// 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)
// 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)
// 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)
Значения указаны в описании поля dwMaxBaud.
// 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)
// 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)
Получение информации о структуре 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().