Pull to refresh

Тестирование встраиваемых систем — один аспект, о котором почему-то мало говорят

Reading time4 min
Views8.3K
К написанию статьи подтолкнуло прочтение статьи с похожим названием, последнее посещение Embedded World и опыт разработки в этой области.

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

Безусловно, подход имеет место быть, и с его помощью можно многое протестировать и найти, но…

Вот в качестве примера простенькая система: микроконтроллер и подключенный к нему по I2C инфракрасный датчик температуры. Как будем тестировать?

Что тут можно виртуализировать, чтоб тест не потерял всякий смысл? Если весь код по сути сводится к инициализации I2C периферии контроллера и реализации протокола коммуникации с самим датчиком? И еще блокировка доступа к ресурсу для случая многозадачного окружения.

На мой взгляд, для нормального тестирования нужно иметь возможность прочитать с датчика значение температуры, и каким-либо образом извне получить данные о реальной температуре окружающей среды и/или объекта, на который указывает датчик. И сравнить их. Т.е. для нормального «end-to-end' тестирования без реальной платы с контроллером и датчиком, а также интерфейсом связи „наружу“, на мой взгляд, никак не обойтись… В самом крайнем случае можно считать, что температура в помещении, где работают люди, будет в диапазоне 18-30 градусов, и проверять полученное значение на попадание в этот интервал. Но если надо проверить точность, то — без термо-камеры, увы, не обойтись.

Пример из жизни: пришлось нам как-то работать с чипом ADG2128 — матрица коммутации 8х12 с управлением по I2C. А чип, как оказалось, имел недокументированный глюк — его I2C часть „будила“ чип не только, когда получала его адрес в начале пакета, а при любом обнаружении его адреса на шине. Даже в середине передачи. I2C как бы предназначен для того, чтобы на нем несколько устройств висело. А теперь — идет коммуникация с другим устройством, висящим на той же шине, и в середине коммуникации проскакивает байт с адресом этого ADG, он просыпается и начинает выдавать свои данные в шину… В общем, интересный был баг, и его исправление-костыль тоже было весьма своеобразным, хоть и работающим в конце-концов.

Так вот — каким образом такой или подобный глюк можно было бы „отловить“, используя подход тестирования без наличия самой встроенной системы с „живым“ чипом на ней?

Еще пару примеров из жизни встраиваемых систем — после добавления очередной функции заканчивается память контроллера. Добавление новой функциональности приводит к „гонкам“ или взаимной блокировке. Как вариант, к аналогичным последствиям приводят неправильные, но все же возможные в реальности действия пользователя из серии „подключить к устройству не то/ не так/ не туда / не вовремя“. Или же послать неправильную конфигурацию на устройство. Или же само устройство при определенной конфигурации начнет потреблять тока больше, чем может обеспечить USB. Или при подключении устройства к ноуту, работающему от батареи, не возникнет соединения „земли“ с „землей“ в розетке — и измерение окажется поразительно неточным из-за бага в спроектированной схеме…

На мой взгляд — нормальное, „полноценное“ тестирование будет возможно лишь в виде разработки еще одного устройства, реального, „железного“, которое будет эмулировать все необходимые воздействия на наше тестируемое устройство, плюс наш тестовый фреймворк должен иметь возможность управления самим нашим тестируемым устройством и устройством симуляции воздействий.

Когда мы разрабатывали DSLAM (телекоммуникационное устройство, на одном конце которого — широкий Ethernet, а на другом 32/64/128 DSL модемов), тестовый стенд выглядел как-то так: 64 модема, подключенных к 64-портам генератора L2/L3 трафика, и Uplink, подключенный к еще одному порту. Тестовый скрипт конфигурировал DSLAM, генераторы трафика, запускал трафик и проверял результаты.

Когда мы разрабатывали многоканальный прикладной осциллограф, устройство тестирования выглядело так: коробочка, имеющая 4 независимых выхода, подключенных ко входам тестируемого осциллографа, каждый выход мог симулировать все поддерживаемые осциллографом сенсоры (типа токовых клещей или датчика давления), а также выдавать значения, которые выдавал бы настоящий сенсор. Тестовый сценарий — задать на выходах комбинацию сенсоров и генерируемых значений, сконфигурировать тестируемое устройство (задать сенсор, диапазон и т.п.), измерить их тестируемым устройством, сравнить со сгенерированными.

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

Системы использовались как на этапе разработки для регрессионного тестирования, так и на этапе производства для проверки нового устройства перед отправкой его „в поле“.

Несомненно, такой подход затратен — но при длительном и сложном многофункциональном проекте, мне кажется, альтернативы ему нет. А без него — прямая дорога к „смертельной петле тестирования“ (Росту необходимого количества „ручных“ тестов по мере добавления новых функций, как следствие — даже простейшее изменение в коде невозможно сделать быстро: 1 час на изменение/багфикс и неделя ручного регрессионного тестирования, ага. Про неделю — не шутка, увы.)

Сейчас делаем саму систему тестирования в виде более-менее универсальной модульной системы, посмотрим, будет ли оно кому-нибудь еще нужно…
Tags:
Hubs:
+12
Comments8

Articles