IX. Реализация КД и ЦК.*
КД выполнен на МК Atmel ATmega8, тактовая частота 8 МГц. ЦК соединяется с Сервером с помощью USB и получает от него питание. Для того, чтобы не писать свой драйвер, в ЦК реализован стандартный USB-профиль последовательного порта. Применен МК AT90USB162 как наиболее простой и знакомый.
Примечание*:
В процессе реализации ЦК обнаружились следующие особенности.
В процессе реализации ЦК обнаружились следующие особенности.
- Отличия драйверов cdc в Windows и Linux.
Драйвер Windows читает данные из конечной точки независимо от того, открыт порт или нет. Если порт не открыт, данные уходят в пустоту. Драйвер Linux читает данные из конечной точки только в том случае, если порт открыт. Поэтому ожидать готовности хоста в бесконечном цикле НЕЛЬЗЯ. Зависание в ожидании готовности приводит к невозможности обрабатывать текущие запросы USB и устройство зависает, даже если драйвер начнет пытаться читать из конечной точки. - Зависание обмена на виртуальной машине.
Linux сервер дома, проектом занимаюсь еще и на работе в свободное время. На работе Linux запускаю из виртуальной машины Oracle VM VirtualBox (версия 4.2.12r84980). В пробной программе при чтении данных из порта обнаружилась неприятная особенность - с вероятностью 50% после получения первых 100-400 байт дальнейшее получение данных блокируется до повторного закрытия/открытия порта. На поиск причины потратил 3 дня. Для поиска использовал:- Перекомпилированный исходник cdc-acm с включенными опциями DEBUG и VERBOSE_DEBUG.
Для контроля драйвера ядра cdc-acm. - usbmon + wireshark
Для контроля usb-транзакций внутри виртуальной машины. - USBTrace
Для контроля usb-транзакций между ЦК и виртуальной машиной.
- CDC-ACM.
В нормальном режиме работы драйвер cdc-acm так сообщает о своих действиях:15:36:27 cdc-acm.c: acm_rx_tasklet: sending urb 0xdeb00000, rcv 0xde765a18, buf 0xde765b58 15:36:27 cdc-acm.c: Entering acm_read_bulk with status 0 15:36:27 cdc-acm.c: Entering acm_rx_tasklet 15:36:27 cdc-acm.c: acm_rx_tasklet: procesing buf 0xde765b44, size = 9
Т.е. он отправляет драйверу шины USB запрос и ждет ответа, получает ответ, обрабатывает ответ, отправляет новый запрос. Во время зависания он пишет только одну строчку:15:36:27 cdc-acm.c: acm_rx_tasklet: sending urb 0xdeb00b00, rcv 0xde765a04, buf 0xde765b44
Т.е. он отправил запрос и ждет ответа. После завершения программы пишет:15:37:03 cdc-acm.c: acm_control_msg: rq: 0x22 val: 0x0 len: 0x0 result: 0 15:37:03 cdc-acm.c: acm_ctrl_irq - urb shutting down with status: -2
Как видим, ответ так и не пришел. Вывод: драйвер CDC-ACM работает нормально, теряется ответ. - USBMON.
usbmon подтверждает действия драйвера. Получается, что виновато устройство ЦК? Но устройство ясно показывает, что из него не хотят читать. - USBTrace.
Чтобы выяснить все до конца, на машине-хосте тоже был установлен USB-анализатор - программа USBTrace. Программа платная, пришлось использовать crack. USBTrace позволяет отслеживать USB-транзакции, инициированные не только драйвером устройства, но и драйвером контроллера. Дело в том, что если захватить устройство в VirtualBox, то оно пропадает из списка устройств, вместо него виден только драйвер контроллера VBoxUSB.
Здесь начинается самое интересное:Seq Type Time Request I/O EP Status Len #70 URB 14.862351 BULK_OR_INTERRUPT_TRANSFER IN 81 STATUS_PENDING 0 #71 URB 14.862713 BULK_OR_INTERRUPT_TRANSFER IN 81 STATUS_SUCCESS 9 #72 DEVICE_CONTROL 50.768658 - OUT 0 STATUS_SUCCESS 96
Видно, что ответ от устройства на последний запрос все же пришел. Значит ответ теряется в драйвере VBoxUSB или в драйвере шины Linux.
Вывод: драйвер VBoxUSB в начале работы иногда теряет ответ на USB-транзакцию. Дальнейшее выяснение решено не проводить, т.к. устройство будет работать на реальной машине, а во время отладки на виртуальной можно смирится с тем, что иногда будут зависания. - Перекомпилированный исходник cdc-acm с включенными опциями DEBUG и VERBOSE_DEBUG.
- Проблема со стеком в ЦК.
Проблема была из-за невнимательности, её опишем как напоминание. МК ЦК имеет небольшой объем ОЗУ - 512 байт, поэтому его легко израсходовать. Было занято 80% памяти, устройство в целом работало нормально, не зависало но:- На объемых ответах устроство переставало что-либо выводить до перезагрузки, при этом продолжая работать.
- Происходили выпадания телеметрических данных.
Было увеличено количество свободной памяти за счет уменьшения буфера команд. Вышеперечисленные дефекты исчезли.