Регистрация  Вход
Ваша корзина пуста
Документация
 Протокол WAKE16  (476 КБ)

Протокол обмена WAKE16

Протокол WAKE16 является логическим уровнем интерфейса управления оборудованием с помощью асинхронного последовательного канала. Физический уровень интерфейса протоколом не определяется. В качестве него может использоваться, например, RS-232 или RS-485. Протокол позволяет производить обмен пакетами данных длиной до 216 байт с адресуемыми устройствами, которых может быть до 215 – 1. Последовательный канал должен быть сконфигурирован следующим образом:

  • Число байт в посылке – 8
  • Количество стоп-бит – 1
  • Бит чётности – нет
  • Скорость обмена – 1200 ÷ 921600 бит/сек
  • использование линий управления модемом – произвольное.

Основой протокола WAKE16 является протокол SLIP (UNIXTM Serial Link Interface Protocol). Передача данных осуществляется в двоичном виде, то есть используются все возможные значения байта (0x00...0xFF). Для передачи служебной информации зарезервированы два кода: FEND = 0xC0 (Frame End) и FESC = 0xDB (Frame Escape). Управляющий код FEND служит для обозначения начала посылки, а код FESC служит для передачи ESC-последовательностей. Если в потоке данных встречаются байты, значения которых совпадают с управляющими кодами, производится подмена этих байт ESC-последовательностями. Этот механизм называют байт-стаффингом. Код FEND заменяется последовательностью <FESC>, <TFEND>, а код FESC – последовательностью <FESC>, <TFESC>, где TFEND = 0xDC (Transposed FEND), TFESC = 0xDD (Transposed FESC). Коды TFEND и TFESC являются управляющими только в ESC-последовательностях, поэтому при передаче данных они в подмене не нуждаются.

Структура пакета

Пакет всегда начинается управляющим кодом FEND (0xC0). Затем следует необязательный байт адреса, после которого идет байт команды. За ним следует байт количества данных и собственно байты данных. Завершает пакет байт контрольной суммы CRC16:

FEND ADDR CMD N Data1 ... DataN CRC16

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

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

  D15 ... D1 D0
ADDR= 1 ... A1 A0

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

Если возникает необходимость передать значение адреса, содержащие значения 0x40 или 0x5B (передаваемый байт в этом случае будет равен 0xC0 или 0xDB), то производится байт-стаффинг. Поэтому следует учитывать, что устройства с такими адресами требуют большей длины пакета. Это может быть заметно в тех случаях, когда используются короткие пакеты. В таких случаях следует избегать назначения устройствам названных адресов.

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

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

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

Код Описание команды
0x01   Передача управления основной программе центрального контроллера
0x02   Передача управления загрузчику центрального контроллера
0x03   Чтение блока FLASH-памяти центрального контроллера
0x04   Запись блока FLASH-памяти центрального контроллера
0x08   Сброс устройства
0x71   Запрос информации об устройстве
0x7A   Изменение адреса устройства

Команды обычно имеют несколько параметров, которые передаются далее в виде пакета данных.

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

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

  D15 ... D1 D0
N= 0 ... N1 N0

Таким образом, один пакет может содержать до 216 байт данных. Значение N не учитывает служебные байты пакета FEND, ADDR, CMD, N и CRC16. В результате байт-стаффинга фактическая длина пакета может возрасти. Значение N не учитывает этот факт и отражает количество полезных байт данных (то есть значение N всегда таково, как будто байт-стаффинг не осуществляется). Если передаваемая команда не имеет параметров, то передается N = 0x0000 и байты данных опускаются.

Если возникает необходимость передать значение N, равное 0xC0 или 0xDB, то производится байт-стаффинг. Однако при таких больших значениях N длина пакета столь велика, что его удлинение ещё на один байт практически незаметно.

Data1...DataN: байты данных, количество которых определяется значением N. При N = 0 байты данных отсутствуют. Байты данных могут иметь любое значение, кроме FEND (0xC0) и FESC (0xDB). Если возникает необходимость передать одно из этих значений, то производится байт-стаффинг.

СRC: 16-битное слово контрольной суммы CRC16. Контрольная сумма рассчи-тывается перед операцией байт-стаффинга для всего пакета, начиная с байтов адреса (или байта команды, если адреса нет) и заканчивая последним байтом данных. При вычислениях используется значение адреса вместе со старшим битом.

Для расчёта контрольной суммы используется полином CRC16 = X16 + X12 + X5 + 1 ([1] 0001 0000 0010 0001 = 0x1021). Значение CRC16 перед вычислением инициализируется числом 0xFFFF. Если CRC16 содержит значения байтов 0xC0 и 0xDB, то они заменяются ESC-последовательностями.

Функция для вычисления CRC16 показана ниже (используется "зеркальный" полином 1000 0100 0000 1000 [1] = 0x8408):

void UpdateCRC16 (char b)
 {
  char i;

  CRC16 ^= b;

  for (i = 8; i > 0; i--)
   if (CRC16 & 1)
    CRC16 = (CRC16 >> 1) ^ 0x8408;
   else
    CRC16 >>= 1;
 }

Эту функцию следует вызвать для каждого байта, в результате чего переменная CRC16 будет содержать вычисленное значение контрольной суммы.