|
Спецификация протокола WAKE |
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Протокол WAKE является логическим уровнем интерфейса
управления оборудованием с помощью асинхронного последовательного канала.
Физический уровень интерфейса протоколом не определяется, может
использоваться, например, RS-232, RS-485 или USB. Протокол позволяет
производить обмен пакетами данных (data frames) длиной до 255 байт с
адресуемыми устройствами, которых может быть до 127. Последовательный
канал должен быть сконфигурирован следующим образом:
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Таблица 1. Управляющие коды протокола
WAKE.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Таблица 2. Подмена байт данных
ESC-последовательностями.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
труктура пакета WAKE следующая: пакет всегда начинается управляющим кодом FEND
(C0h). Затем следует необязательный байт адреса, после которого идет байт
команды. За ним следует байт количества данных и собственно байты данных.
Завершает пакет необязательный байт контрольной суммы CRC-8. Таблица 3. Структура пакета WAKE.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
FEND:
Управляющий код FEND (C0h) является признаком начала пакета. Благодаря
стаффингу, этот код больше нигде в потоке данных не встречается, что
позволяет в любой ситуации однозначно определять начало
пакета. ADDR: Байт адреса используется для адресации отдельных устройств. На практике распространена ситуация, когда управление осуществляется только одним устройством. В таком случае байт адреса не требуется, и его можно не передавать. Вместо него сразу за кодом FEND передается байт команды CMD. Для того, чтобы можно было однозначно установить, адресом или командой является второй байт пакета, введены некоторые ограничения. Для адресации используется 7 бит, а старший бит, передаваемый вместе с адресом, должен всегда быть установлен:
Иногда возникает необходимость передать какую-то команду или данные сразу всем устройствам. Для этого предусмотрен коллективный вызов (broadcast), который осуществляется путем передачи нулевого адреса (учитывая единичный старший бит, в этом случае передаваемый байт равен 80h). Нужно отметить, что передача в пакете нулевого адреса полностью аналогична передаче пакета без адреса. Поэтому при реализации протокола можно автоматически исключать нулевой адрес из пакета. Учитывая разрядность адреса и один зарезервированный адрес для коллективного вызова, максимальное количество адресуемых устройств составляет 127.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Если возникает необходимость
передать значение адреса 40h или 5Bh (передаваемый байт в этом случае
будет равен C0h или DBh), то производится стаффинг, т.е. передача
ESC-последовательности (см. таблицу 2). Поэтому следует учитывать, что
устройства с такими адресами требуют большей на один байт длины пакета.
Это может быть заметно в тех случаях, когда используются короткие пакеты.
В таких случаях следует избегать назначения устройствам названных
адресов. CMD: Байт команды всегда должен иметь нулевой старший бит:
Таким образом, код команды занимает 7 бит, что позволяет передавать до 128 различных команд. Коды команд выбираются произвольно в зависимости от нужд приложения. Рекомендуется использовать несколько стандартных кодов команд:
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Таблица 4. Стандартные коды команд протокола
WAKE.
Коды остальных команд выбираются в зависимости от нужд приложения. Команды обычно имеют несколько параметров, которые передаются далее в виде пакета данных. Поскольку код команды всегда имеет нулевой старший бит, этот код никогда не совпадает с управляющими кодами. Поэтому при передаче команды стаффинг никогда не производится. N: Байт количества данных имеет значение, равное количеству передаваемых байт данных:
Таким образом, код количества данных занимает 8 бит, в результате один пакет может содержать до 255 байт данных. Значение N не учитывает служебные байты пакета FEND, ADDR, CMD, N и CRC. В результате стаффинга фактическая длина пакета может возрасти. Значение N не учитывает этот факт и отражает количество полезных байт данных (т.е. значение N всегда таково, как будто стаффинг не осуществляется). Если передаваемая команда не имеет параметров, то передается N = 00h и байты данных опускаются. Если возникает необходимость передать значение N, равное C0h или DBh, то производится стаффинг, т.е. передача ESC-последовательности (см. таблицу 2). Однако при таких больших значениях N длина пакета столь велика, что его удлинение еще на один байт практически незаметно. Data1...DataN: Байты данных, количество которых определяется значением N. При N = 00h байты данных отсутствуют. Байты данных могут иметь любое значение, кроме FEND (C0h) и FESC (DBh). Если возникает необходимость передать одно из этих значений, то производится стаффинг, т.е. передача ESC-последовательности (см. таблицу 2), состоящей из управляющего кода FESC и кода TFEND (TFESC). СRC: Байт контрольной суммы CRC-8. Может
отсутствовать в некоторых реализациях протокола. Контрольная сумма
CRC-8 рассчитывается перед операцией стаффинга для всего пакета,
начиная с байта FEND и заканчивая последним байтом данных. Если в пакете
передается адрес, то при вычислении контрольной суммы используется его
истинное значение, т.е. единичный старший бит не учитывается. Для расчета
контрольной суммы используется полином CRC = X8 + X5 + X4 + 1. Значение
CRC перед вычислением инициализируется числом DEh. При передаче значения
байта контрольной суммы C0h и DBh заменяются ESC-последовательностями (см.
таблицу 2). Таблица 5. Величина избыточности протокола
WAKE.
Со стороны PC протокол реализован в динамической библиотеке wsp32.dll (вариант для RS-232) и wusb32.dll (вариант USB с использованием драйвера от FTDI). Библиотеки могут использоваться при разработке коммуникационных программ на любом языке. Дальнейшее описание предполагает, что библиотека используется приложением, написанным на языке C++. Заголовочный файл библиотеки wsp32.dll для работы через RS-232 приведен ниже: |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#ifndef WSP32_H
#define WSP32_H
#ifdef WSP32_Exports
#define WSP32_API __declspec(dllexport)
#else
#define WSP32_API __declspec(dllimport)
#endif
extern "C"
{
WSP32_API bool WINAPI AccessCOM(char *P);
WSP32_API bool WINAPI OpenCOM(char *P, DWORD baud);
WSP32_API bool WINAPI CloseCOM(void);
WSP32_API bool WINAPI SetModLns(DWORD F);
WSP32_API bool WINAPI GetModLns(LPDWORD lpD);
WSP32_API bool WINAPI PurgeCOM(void);
WSP32_API bool WINAPI FlushCOM(void);
WSP32_API bool WINAPI GetMaskCOM(LPDWORD lpEvtMask);
WSP32_API bool WINAPI SetMaskCOM(DWORD EvtMask);
WSP32_API bool WINAPI WaitEventCOM(LPDWORD lpEvtMask);
WSP32_API bool WINAPI RxFrame(DWORD To, unsigned char &ADD,
unsigned char &CMD, unsigned char &N, unsigned char *Data);
WSP32_API bool WINAPI TxFrame(unsigned char ADDR, unsigned char CMD,
unsigned char N, unsigned char *Data);
}
#endif
bool AccessCOM(char *P) - функция проверяет доступность
порта. В качестве параметра передается имя порта (например, "COM1").
Возвращает true в случае доступности порта. bool OpenCOM(char *P, DWORD baud) - функция открывает порт. В качестве параметров передаются имя порта (например, "COM1") и скорость в бодах, которая может принимать одно из стандартных значений (например, 115200). Возвращает true в случае успешного выполнения. Функция устанавливает на линии DTR уровень -12В, а на линии RTS уровень +12В. bool CloseCOM(void) - функция закрывает порт. Возвращает true в случае успешного выполнения. bool SetModLns(DWORD F) - функция осуществляет управление линиями RTS и DTR. Возвращает true в случае успешного выполнения. Параметр такой же, как у функции API EscapeCommFunction. bool GetModLns(LPDWORD lpD) - функция считывает линии управления модема CTS и DSR. Возвращает true в случае успешного выполнения. Параметр такой же, как у функции API GetCommModemStatus. bool PurgeCOM(void) - функция очищает буфер COM-порта и прерывает текущие операции приема/передачи. Возвращает true в случае успешного выполнения. bool FlushCOM(void) - функция очищает буфер COM-порта, дождавшись завершения передачи. Возвращает true в случае успешного выполнения. bool GetMaskCOM(LPDWORD lpEvtMask) - функция считывает маску событий COM-порта. Возвращает true в случае успешного выполнения. Параметр такой же, как у функции API GetCommMask. bool SetMaskCOM(DWORD EvtMask) - функция устанавливает маску Возвращает true в случае успешного выполнения. Параметр такой же, как у функции API SetCommMask. bool WaitEventCOM(LPDWORD lpEvtMask) - функция служит для ожидания события COM-порта. Возвращает true в случае успешного выполнения. bool RxFrame(DWORD To, unsigned char &ADD, unsigned char &CMD, unsigned char &N, unsigned char *Data) - функция осуществляет прием WAKE-пакета. Возвращает true в случае успешного выполнения. bool TxFrame(unsigned char ADDR, unsigned char CMD, unsigned char N, unsigned char *Data) - функция осуществляет передачу WAKE-пакета. Возвращает true в случае успешного выполнения. Библиотека wusb32.dll содержит меньший набор функций. Имена функций двух dll не совпадают, что позволяет подключать к одному проекту сразу обе библиотеке, обеспечивая при этом работу как через RS-232, так и через USB. Библиотека wusb32.dll требует для своей работы установленного direct-драйвера от FTDI (тестировалась с версией драйвера 1.06.20) и наличия библиотеки FTD2XX.dll (тестировалась с версией библиотеки 2.01.04). Заголовочный файл библиотеки wusb32.dll для работы через USB приведен ниже: #ifndef WUSB32_H #define WUSB32_H #ifdef WUSB32_Exports #define WUSB32_API __declspec(dllexport) #else #define WUSB32_API __declspec(dllimport) #endif extern "C" { WUSB32_API bool WINAPI AccessUSB(int DevNum); WUSB32_API bool WINAPI OpenUSB(int DevNum, DWORD baud); WUSB32_API bool WINAPI CloseUSB(void); WUSB32_API bool WINAPI PurgeUSB(void); WUSB32_API bool WINAPI RxFrameUSB(DWORD To, unsigned char &ADD, unsigned char &CMD, unsigned char &N, unsigned char *Data); WUSB32_API bool WINAPI TxFrameUSB(unsigned char ADDR, unsigned char CMD, unsigned char N, unsigned char *Data); } #endifbool AccessUSB(int DevNum) - функция проверяет доступность USB порта. В качестве параметра передается номер порта (для одного устройства обычно DevNum=0). Возвращает true в случае доступности порта. bool OpenUSB(int DevNum, DWORD baud) - функция открывает порт. В качестве параметров передаются номер порта и скорость в бодах. Скорость имеет значение только при работе с FT232BM. bool CloseUSB(void) - функция закрывает порт. Возвращает true в случае успешного выполнения. bool PurgeUSB(void) - функция очищает буфер порта и прерывает текущие операции приема/передачи. Возвращает true в случае успешного выполнения. bool RxFrameUSB(DWORD To, unsigned char &ADD, unsigned char &CMD, unsigned char &N, unsigned char *Data) - функция осуществляет прием WAKE-пакета. Возвращает true в случае успешного выполнения. bool TxFrameUSB(unsigned char ADDR, unsigned char CMD, unsigned char N, unsigned char *Data) - функция осуществляет передачу WAKE-пакета. Возвращает true в случае успешного выполнения. Для тестирования приложений с применением протокола WAKE служит приложение WakeUp!, с помощью которого можно передавать сформированные вручную фреймы и получать ответ устройства. Программа WakeUp! позволяет передать один из трех заданных фреймов или выбранную последовательность фреймов. Каждый фрейм содержит поле адреса устройства (ADDR), поле команды (CMD), поле названия команды (USER CMD NAME) и поле данных (DATA FRAME). Поле названия команды никакого отношения к передаваемым данным не имеет, оно просто позволяет ввести любое название команды. Это название сохраняется в ini-файле. Длина фрейма (поле N) формируется автоматически. Каждый из трех фреймов можно передать отдельно с помощью кнопки, расположенной правее поля данных фрейма. Дополнительно существует возможность передачи последовательности из фреймов, которые отмечены. Последовательность из фреймов можно передать однократно или циклически, для этого имеются соответствующие кнопки. Все переданные и принятые фреймы отображаются в нижнем поле. Кнопка "Clear" предназначена для очистки поля переданных и принятых фреймов, кнопка "Exit" служит для выхода из программы. Все эти кнопки продублированы в меню "Frame".Меню "Port" позволяет выбрать один из портов USB1…USB4 или COM1…COM4. Поле "Baud Rate" позволяет выбрать одну из стандартных скоростей обмена или ввести нестандартную скорость. Поле "Timeout" позволяет ввести значение таймаута для приема пакетов от устройства. В строке состояния отображается количество выполненных циклов для циклической передачи, а также количество ошибок. Ошибки для приема и передачи учитываются отдельно. Кроме того, в строке состояния отображается время выполнения команды или суммарное время выполнения нескольких команд, если передается последовательность фреймов. Время измеряется от начала передачи фрейма до конца приема ответа на фрейм. Если передается несколько фреймов, значения суммируются. Протокол WAKE не накладывает никаких ограничений на командный уровень, тем не менее выше приводилась таблица рекомендуемых кодов для стандартных команд. Типичный обмен мастера с подчиненным устройством происходит следующим образом: мастер передает пакет, который содержит код команды для выполнения. Подчиненное устройство выполняет эту команду и в ответ возвращает мастеру пакет с тем же кодом команды. Таким образом осуществляется квитирование. Так как арбитраж происходит только на уровне пакетов, инициатором обмена всегда выступает мастер. Т.е. ни при каких условиях подчиненное устройство не может передать пакет без запроса мастера. Кратко рассмотрим назначение стандартных команд:
Таблица 6. Стандартные коды ошибок протокола
WAKE.
Назначение кодов стандартных ошибок:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| musidora@rambler.ru |
Последнее обновление
09.08.2009
|
Инженер и веб-мастер Богданов Андрей Александрович
Water LAB © |