Спецификация протокола WAKE

Материал из eeWiki - открытая энциклопедия по электронике
Перейти к: навигация, поиск

Wake logo.gif

Протокол WAKE является логическим уровнем интерфейса управления оборудованием с помощью асинхронного последовательного канала. Физический уровень интерфейса протоколом не определяется, может использоваться, например, RS-232, RS-485 или USB. Протокол позволяет производить обмен пакетами данных (data frames) длиной до 255 байт с адресуемыми устройствами, которых может быть до 127. Последовательный канал должен быть сконфигурирован следующим образом:

  • число бит в посылке - 8
  • количество стоп-бит - 1
  • бит четности - нет
  • скорость обмена - 300...115200 бод
  • использование линий управления модемом - произвольное

Основой протокола WAKE является протокол SLIP (UNIXTM Serial Link Interface Protocol). Передача данных осуществляется в двоичном виде, т.е. используются все возможные значения байта (00h...FFh).
Для передачи служебной информации зарезервированы два кода: FEND = C0h (Frame End) и FESC = DBh (Frame Escape).
Управляющий код FEND служит для обозначения начала посылки, а код FESC служит для передачи ESC-последовательностей.
Если в потоке данных встречаются байты, значения которых совпадают с управляющими кодами, производится подмена этих байт ESC-последовательностями. Такой механизм называют байт-стаффингом (byte stuffing).
Код FEND заменяется последовательностью <FESC>, <TFEND>, а код FESC - последовательностью <FESC>, <TFESC>, где TFEND = DCh (Transposed FEND), TFESC = DDh (Transposed FESC).
Коды TFEND и TFESC являются управляющими только в ESC-последовательностях, поэтому при передаче данных они в подмене не нуждаются.



Управляющие коды протокола WAKE
Обозначение Пояснение HEX-значение
FEND Frame End C0h
FESC Frame Escape DBh
TFEND Transposed Frame End DCh
TFESC Transposed Frame Escape DDh
Подмена байт данных ESC-последовательностями
Байт данных Передаваемая последовательность
C0h DBh, DCh
DBh DBh, DDh
Структура пакета WAKE

Структура пакета WAKE следующая: пакет всегда начинается управляющим кодом FEND (C0h). Затем следует необязательный байт адреса, после которого идет байт команды. За ним следует байт количества данных и собственно байты данных. Завершает пакет необязательный байт контрольной суммы CRC-8.

FEND ADDR CMD N Data1 ... DataN CRC

FEND: Управляющий код FEND (C0h) является признаком начала пакета. Благодаря стаффингу, этот код больше нигде в потоке данных не встречается, что позволяет в любой ситуации однозначно определять начало пакета.

ADDR: Байт адреса используется для адресации отдельных устройств. На практике распространена ситуация, когда управление осуществляется только одним устройством. В таком случае байт адреса не требуется, и его можно не передавать. Вместо него сразу за кодом FEND передается байт команды CMD. Для того, чтобы можно было однозначно установить, адресом или командой является второй байт пакета, введены некоторые ограничения. Для адресации используется 7 бит, а старший бит, передаваемый вместе с адресом, должен всегда быть установлен:

D7 D6 D5 D4 D3 D2 D1 D0
ADDR= 1 A6 A5 A4 A3 A2 A1 A0


Иногда возникает необходимость передать какую-то команду или данные сразу всем устройствам. Для этого предусмотрен коллективный вызов (broadcast), который осуществляется путем передачи нулевого адреса (учитывая единичный старший бит, в этом случае передаваемый байт равен 80h). Нужно отметить, что передача в пакете нулевого адреса полностью аналогична передаче пакета без адреса. Поэтому при реализации протокола можно автоматически исключать нулевой адрес из пакета. Учитывая разрядность адреса и один зарезервированный адрес для коллективного вызова, максимальное количество адресуемых устройств составляет 127.

Если возникает необходимость передать значение адреса 40h или 5Bh (передаваемый байт в этом случае будет равен C0h или DBh), то производится стаффинг, т.е. передача ESC-последовательности (см. таблицу 2). Поэтому следует учитывать, что устройства с такими адресами требуют большей на один байт длины пакета. Это может быть заметно в тех случаях, когда используются короткие пакеты. В таких случаях следует избегать назначения устройствам названных адресов.

CMD: Байт команды всегда должен иметь нулевой старший бит:

D7 D6 D5 D4 D3 D2 D1 D0
CMD= 0 C6 C5 C4 C3 C2 C1 C0


Таким образом, код команды занимает 7 бит, что позволяет передавать до 128 различных команд. Коды команд выбираются произвольно в зависимости от нужд приложения. Рекомендуется использовать несколько стандартных кодов команд:

Стандартные коды команд протокола WAKE
Код Название Описание команды
00h C_Nop Нет операции
01h C_Err Передача кода ошибки
02h C_Echo Запрос возврата переданного пакета
03h C_Info Запрос информации об устройстве



Коды остальных команд выбираются в зависимости от нужд приложения. Команды обычно имеют несколько параметров, которые передаются далее в виде пакета данных.
Поскольку код команды всегда имеет нулевой старший бит, этот код никогда не совпадает с управляющими кодами. Поэтому при передаче команды стаффинг никогда не производится.

N: Байт количества данных имеет значение, равное количеству передаваемых байт данных:

D7 D6 D5 D4 D3 D2 D1 D0
N= N7 N6 N5 N4 N3 N2 N1 N0

Таким образом, код количества данных занимает 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).

Избыточность протокола WAKE
Вид пакета Избыточность, %
FEND, CMD, 00h, CRC 75,0
FEND, CMD, 00h 66,7
FEND, ADDR, CMD, 00h, CRC 60,0
FEND, ADDR, CMD, 00h 50,0
FEND, ADDR, CMD, 0Ah, <10 bytes of data>, CRC 20,0
FEND, ADDR, CMD, 32h, <50 bytes of data>, CRC 5,5
FEND, ADDR, CMD, 7Fh, <127 bytes of data>, CRC 2,3
FEND, CMD, 7Fh, <127 bytes of data>, CRC 2,3
FEND, ADDR, CMD, 7Fh, <127 bytes of data> 1,5
FEND, CMD, 7Fh, <127 bytes of data> 1,5


Со стороны PC протокол реализован в динамической библиотеке wsp32.dll (вариант для RS-232) и wusb32.dll (вариант USB с использованием драйвера от FTDI). Библиотеки могут использоваться при разработке коммуникационных программ на любом языке. Дальнейшее описание предполагает, что библиотека используется приложением, написанным на языке C++. Заголовочный файл библиотеки wsp32.dll для работы через RS-232 приведен ниже:

  1.  
  2. #ifndef WSP32_H
  3. #define WSP32_H
  4. #ifdef WSP32_Exports
  5. #define WSP32_API __declspec(dllexport)
  6. #else
  7. #define WSP32_API __declspec(dllimport)
  8. #endif
  9. extern &quot;C&quot;
  10. {
  11. WSP32_API bool WINAPI AccessCOM(char *P);
  12. WSP32_API bool WINAPI OpenCOM(char *P, DWORD baud);
  13. WSP32_API bool WINAPI CloseCOM(void);
  14. WSP32_API bool WINAPI SetModLns(DWORD F);
  15. WSP32_API bool WINAPI GetModLns(LPDWORD lpD);
  16. WSP32_API bool WINAPI PurgeCOM(void);
  17. WSP32_API bool WINAPI FlushCOM(void);
  18. WSP32_API bool WINAPI GetMaskCOM(LPDWORD lpEvtMask);
  19. WSP32_API bool WINAPI SetMaskCOM(DWORD EvtMask);
  20. WSP32_API bool WINAPI WaitEventCOM(LPDWORD lpEvtMask);
  21. WSP32_API bool WINAPI RxFrame(DWORD To, unsigned char &amp;ADD,
  22. unsigned char &amp;CMD, unsigned char &amp;N, unsigned char *Data);
  23. WSP32_API bool WINAPI TxFrame(unsigned char ADDR, unsigned char CMD,
  24. unsigned char N, unsigned char *Data);
  25. }
  26. #endif
  27.  

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 приведен ниже:

  1.  
  2. #ifndef WUSB32_H
  3. #define WUSB32_H
  4. #ifdef WUSB32_Exports
  5. #define WUSB32_API __declspec(dllexport)
  6. #else
  7. #define WUSB32_API __declspec(dllimport)
  8. #endif
  9. extern &quot;C&quot;
  10. {
  11. WUSB32_API bool WINAPI AccessUSB(int DevNum);
  12. WUSB32_API bool WINAPI OpenUSB(int DevNum, DWORD baud);
  13. WUSB32_API bool WINAPI CloseUSB(void);
  14. WUSB32_API bool WINAPI PurgeUSB(void);
  15. WUSB32_API bool WINAPI RxFrameUSB(DWORD To, unsigned char &amp;ADD,
  16. unsigned char &amp;CMD, unsigned char &amp;N, unsigned char *Data);
  17. WUSB32_API bool WINAPI TxFrameUSB(unsigned char ADDR, unsigned char CMD,
  18. unsigned char N, unsigned char *Data);
  19. }
  20. #endif
  21.  

bool 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 в случае успешного выполнения.

Программа WakeUp!

Для тестирования приложений с применением протокола WAKE служит приложение WakeUp!, с помощью которого можно передавать сформированные вручную фреймы и получать ответ устройства. Окно программы WakeUp! показано на рис. 1.

Рис. 1. Окно программы WakeUp!

Программа WakeUp! позволяет передать один из трех заданных фреймов или выбранную последовательность фреймов. Каждый фрейм содержит поле адреса устройства (ADDR), поле команды (CMD), поле названия команды (USER CMD NAME) и поле данных (DATA FRAME). Поле названия команды никакого отношения к передаваемым данным не имеет, оно просто позволяет ввести любое название команды. Это название сохраняется в ini-файле. Длина фрейма (поле N) формируется автоматически. Каждый из трех фреймов можно передать отдельно с помощью кнопки, расположенной правее поля данных фрейма. Дополнительно существует возможность передачи последовательности из фреймов, которые отмечены. Последовательность из фреймов можно передать однократно или циклически, для этого имеются соответствующие кнопки. Все переданные и принятые фреймы отображаются в нижнем поле. Кнопка "Clear" предназначена для очистки поля переданных и принятых фреймов, кнопка "Exit" служит для выхода из программы. Все эти кнопки продублированы в меню "Frame".Меню "Port" позволяет выбрать один из портов USB1…USB4 или COM1…COM4. Поле "Baud Rate" позволяет выбрать одну из стандартных скоростей обмена или ввести нестандартную скорость. Поле "Timeout" позволяет ввести значение таймаута для приема пакетов от устройства. В строке состояния отображается количество выполненных циклов для циклической передачи, а также количество ошибок. Ошибки для приема и передачи учитываются отдельно. Кроме того, в строке состояния отображается время выполнения команды или суммарное время выполнения нескольких команд, если передается последовательность фреймов. Время измеряется от начала передачи фрейма до конца приема ответа на фрейм. Если передается несколько фреймов, значения суммируются.

Назначение стандартных команд

Протокол WAKE не накладывает никаких ограничений на командный уровень, тем не менее выше приводилась таблица рекомендуемых кодов для стандартных команд. Типичный обмен мастера с подчиненным устройством происходит следующим образом: мастер передает пакет, который содержит код команды для выполнения. Подчиненное устройство выполняет эту команду и в ответ возвращает мастеру пакет с тем же кодом команды. Таким образом осуществляется квитирование. Так как арбитраж происходит только на уровне пакетов, инициатором обмена всегда выступает мастер. Т.е. ни при каких условиях подчиненное устройство не может передать пакет без запроса мастера. Кратко рассмотрим назначение стандартных команд:

  • C_Nop - команда "нет операции". На практике никогда не используется. Код зарезервирован для упрощения "разбора" кодов команд в подчиненном устройстве.
  • C_Err - команда "ошибка". Мастер никогда не передает код этой команды. Если подчиненное устройство принимает от мастера пакет, который не соответствует действительному пакету протокола WAKE (например, обнаружена ошибка CRC), то мастеру передается ответ в виде пакета с кодом этой команды, не содержащий данных. Команда введена по той причине, что пакет, принятый подчиненным устройством с ошибкой, не содержит надежной информации о команде, которую передавал мастер. Говоря другими словами, подчиненное устройство "не знает", на какую команду оно отвечает.
  • C_Echo - запрос на возврат переданного пакета. Если мастер передает пакет с этим кодом команды, подчиненное устройство передает в ответ пакет с таким же кодом команды и с теми же данными. Максимальное количество данных в этом пакете может ограничиваться конкретной реализацией протокола WAKE в подчиненном устройстве (размером буфера).
  • C_Info - запрос информации о подчиненном устройстве. В ответ на эту команду подчиненное устройство возвращает пакет, содержащий ASCII-строку, заканчивающуюся нулем. Эта строка обычно содержит название устройства, версию его firmware и серийный номер. Имя устройства используется для подтверждения установления связи - мастер должен не только получить ответ в формате WAKE, но и убедиться, что подключено именно то устройство, которое нужно. Серийный номер может использоваться, например, для поиска на диске нужного файла калибровочных коэффициентов.

Другие команды могут быть определены пользователем в зависимости от нужд приложения.

Стандартные коды ошибок протокола WAKE

Если при выполнении команды подчиненным устройством возможно возникновение ошибок, возвращаемый пакет в качестве первого байта данных может содержать код ошибки. Рекомендуется использовать несколько стандартных кодов ошибок:

Код Название Описание команды
00h Err_No Нормальное завершение команды
01h Err_Tx Ошибка обмена
02h Err_Bu Устройство занято
03h Err_Re Устройство не готово
04h Err_Pa Неправильные параметры
05h Err_Nr Устройство не отвечает
Назначение кодов стандартных ошибок
  • Err_No - нет ошибки, команда выполнена правильно
  • Err_Tx - ошибка обмена. Код этой ошибки может передаваться подчиненным устройством в пакете с кодом команды C_Err. Фактически этот пакет означает "ошибка приема пакета мастера". Другая ситуация, когда может передаваться этот код ошибки, это ошибка обмена подчиненного устройства с другими подчиненными микроконтроллерами.
  • Err_Bu - устройство занято. Эта ошибка возникает в том случае, когда мастер делает попытку запустить в подчиненном устройстве какой-то процесс, который еще не завершился после предыдущего запуска. Пример - "АЦП занят".
  • Err_Re - устройство не готово. Этот код ошибки может быть использован в группе команд, с помощью которых мастер опрашивает готовность подчиненного устройства. Такие команды возвращают код Err_Re, пока устройство (например, АЦП) не готово, а затем возвращают Err_No. Этот код можно возвращать и на команду запроса данных, если они еще не готовы. Тогда можно обойтись без специальных команд опроса готовности.
  • Err_Pa - неправильные команды. Эта ошибка возникает в том случае, если

мастер пытается выполнить в подчиненном устройстве какую-то функцию с неверным параметрами. В таком случае вместо пакета с данными подчиненное устройство возвращает пакет с этим кодом ошибки.

  • Err_Nr - устройство не отвечает. Эта ошибка может возникать в том случае, если подчиненное устройство имеет quot;в

подчинении" другие устройства, которые не отвечают (например, отключены). Этот набор ошибок может быть изменен в зависимости от нужд конкретного приложения. В качестве примера применения протокола WAKE в конкретном устройстве приведено описание системы команд блока управления криостатом CTC-25N.

Файлы

Спецификация протокола WAKE в формате pdf - (225 Kb)
Текущая версия и примеры для uC с реализацией конкретных команд - (352 Kb)



Ридико Леонид Иванович
e-mail: wubblick@yahoo.com