четверг, 26 мая 2011 г.

Своя отказоустойчивая шина ВВ. Реализация очередей.

Если забыть о минимальном времени обработки прерывания микроконтроллером и о размерах ОЗУ (данные показатели у современных МК довольно высоки), то можно было бы сказать, что параллельная обработка сигналов с "самодельных" шин не представляет особой сложности.
Проблемы начинаются, когда мы видим, что на шине появляются паразитные сигналы: это может быть спецификой работы передатчика при его включении-выключении, внешние наводки и т.п. Например, я время от времени регистрировал характерные данные на своём МК и долго не мог понять их просхождение. Виновником оказалась моя привычка дрыгать ногами под столом и задевать штекер питания настольных аудиоколонок, которые очень сильно "звонили".
В этом случае мы должны оградиться от таких помех логическими, программными, методами: если я знаю характер сигнала, а именно, его количественные и временные характеристики, то я могу написать фильтр для сообщений от передатчика.
Количественно-временные показатели я могу получить с помощью таймера.
Алгоритм прост:
- Начальное состояние: счётчик обнулён, таймер остановлен;
- При получении первого сигнала таймер запускается, счётчик инкрементируется (как и при получении последующих сигналов);
- Если показания счётчика достигли длины ожидаемого сообщения, таймер останавливается и проверяется его значение: оно должно быть не меньше заранее заданной константы. Таким образом мы защищаемся от наводок, несущих большое количество данных за короткий период времени;
- Если таймер достиг максимального значения (т.е. времени, за которое сообщение точно должно было быть доставлено), то и таймер, и счётчик обнуляются. Вернулись к исходным значениям. Этим действием нейтралезуем  короткие всплески на шине.

Теперь надо уточнить ещё один оставшийся момент: сколько мне нужно таймеров для предотвращения DoS в своей системе? Столько же, сколько и линий передачи данных? Достаточно лишь завести очередь, к кажной ячейки которой будет привязан свой таймер. Ячейка будет характеризоваться состоянием свободна-занята. Таким образом доступ к такой ячейке производиться свободно, но ни как в FIFO.
А вопрос о случае заполнения всей очереди при поступлении большого количество запросов (т.е. вопрос о величине и готовности "жертвования" системных таймеров) зависит от характеристик протокола передачи данных и от условий эксплуатации.

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

/* Очередь входящих сообщений */
volatile struct sPeriphMsg {
    unsigned long ulPeriphMsgBuf[PERIPH_MSG_LEN]; // буфер для пакета
    unsigned short usBitCount; // счётчик
    unsigned short usDevId; // ID устройства. Так я найду свою ячейку при поступлении следующего сигнала.
} g_sPeriphMsg[PERIPH_QUEUE_LEN];

Комментариев нет:

Отправить комментарий