TDD для встраиваемых C: как разработать тесты для светодиодного драйвера? - PullRequest
0 голосов
/ 23 апреля 2020

Я новичок ie до TDD и следую "Тестовой разработке для встраиваемых систем C редакция 3".

Найдите очень интересный вопрос, заданный автором. Он находится в разделе Начало работы-> Тестирование вашего пути к выполнению-> Поместить знания на работу, P103:

Наш инженер по аппаратному обеспечению сообщил нам, что она может сэкономить $ 0,12 / плату, если светодиоды используют инвертированную логику c. Модифицируйте LedDriver и его тесты, чтобы использовать инвертированный лог c. Как можно улучшить наши тесты или дизайн, чтобы большинство тестов не заботились о инвертированной логике c? Наша компания только что завершила версию платы с инвертированной светодиодной логикой c. Мы узнаем, что некоторые из предыдущих версий все еще находятся в поле. Как следует модифицировать LedDriver и его тесты для поддержки обеих версий оборудования? Условная компиляция не является частью правильного ответа. Нам нужен один двоичный файл. Шелкография на производственной плате неправильная! Светодиод 1 обозначен 16, светодиод 2 - 15 и т. Д. Как вы модифицируете тесты и код для работы с реальным оборудованием?

Есть ли какая-либо рекомендация, которой я могу следовать для изменения производственного кода или тестового сценария в этих случаях?

BR

1 Ответ

0 голосов
/ 23 апреля 2020

Как правило, это звучит как задача для программиста, а не для тестера.

Если вы пишете в порт с активной высокой логикой c, то вы будете использовать PORT |= MASK;, иначе PORT &= ~MASK;. Основная проблема здесь заключается в том, что нам нужны разные операторы в зависимости от полярности, поэтому наивное решение будет таким:

if(active_high)
  PORT |= MASK;
else
  PORT &= ~MASK;

Это приводит к дополнительному коду. Лучшее решение - если мы можем сгенерировать MASK во время компиляции и всегда иметь код, выполняющий PORT = MASK;, не разрушая любые другие несвязанные выводы порта. Что, в свою очередь, означает, что это необходимо учитывать уже на этапе аппаратной маршрутизации!

Если возможно решение PORT = MASK;, вы можете сделать что-то вроде:

#define LED2 (1u << 2)  // active high
#define LED1 (0u << 1)  // active low
#define LED0 (1u << 0)  // active high

#define MASK (LED0 | LED1 | LED2)

Или, если хотите: #define POLARITY 1 ... #define LED2 (POLARITY << 2) ...


При этом одним из наиболее важных навыков в технике является критическое критическое мышление / скептицизм и нестандартное мышление.

Так что, если инженер по аппаратному обеспечению говорит, что они могут сэкономить 0,12 долл. / Плата, а ваша компания производит миллионы плат, подождите. Если вы продаете сто или около того в год, и исправление займет у вас несколько дней работы, то, возможно, попросите их потеряться, потому что зарплата программиста за исправление будет стоить во много раз больше, чем любые деньги, «сэкономленные» в течение срока службы. этот продукт.

Точно так же, «условная компиляция не является частью правильного ответа. Мы хотим один двоичный файл» - это требование для зрелого возраста. Если вы прикручиваете шелкографию к плате-прототипу, лучшее решение - поставить один двоичный файл для этой прокрученной платы до момента, когда вы выкатываете следующую версию PCB, а затем постоянно меняете прошивку в этот момент времени. , Эти вещи, как правило, должны обрабатываться контролем версий , а не условной компиляцией. Сделайте отдельную ветвь для испорченной платы, проблема решена.

Если это невозможно, хорошо ... при проектировании платы также можно выполнять трюки, такие как жертвование 4-мя выводами GPIO, их установка в качестве входных данных и t ie каждый в Vdd или GND для формирования двоичного числа. MCU может прочитать контакты, чтобы узнать аппаратную версию платы, и есть место для 16 ревизий. Тогда у вас может быть один двоичный файл, который поддерживает каждую версию.

Всегда ставьте под сомнение требования!

...