Функции заглушки в симуляциях - PullRequest
6 голосов
/ 06 января 2009

Я работаю над проектом встроенного C, который зависит от некоторого внешнего HW. Я хотел бы заглушить код доступа к этим частям, чтобы я мог смоделировать систему без использования HW. До сих пор я использовал некоторые макросы, но это заставляет меня немного изменить свой рабочий код, чего я бы хотел избежать.

Пример:

stub.h
#ifdef _STUB_HW
#define STUB_HW(name) Stub_##name
#else /*_STUB_HW*/
#define STUB_HW(name) name
#endif /*_STUB_HW*/

my_hw.c
WORD STUB_HW(clear_RX_TX)()
{ /* clear my rx/tx buffer on target HW */ }

test_my_hw.c
#ifdef _STUB_HW
WORD clear_RX_TX()
{ /* simulate clear rx/tx buffer on target HW */ }

С помощью этого кода я могу включить / выключить заглушку с помощью тега препроцессора _STUB_HW

Есть ли способ сделать это, не меняя код моего продукта и избегая множества ifdefs. И я не буду смешивать prod и test code в одном файле, если смогу избежать этого. Мне все равно, как выглядит тестовый код, если я могу максимально сохранить его от рабочего кода.

Edit:

Было бы неплохо, если бы можно было выбирать / переименовывать функции без замены всего файла. Например, взять все функции, начиная с nRF_##, затем присвоить новое имя и затем вставить test_nRF_## в nRF_##, если это возможно

Ответы [ 3 ]

9 голосов
/ 06 января 2009

Я просто создаю два файла ActualDriver.c и StubDriver.c, которые содержат абсолютно одинаковые имена функций. При создании двух сборок, связывающих производственный код с различными объектами, нет конфликтов имен. Таким образом, производственный код не содержит тестов или условных кодов.

1 голос
/ 09 января 2009

Я согласен с вышеизложенным. Стандартным решением этого является определение непрозрачного абстрагированного набора вызовов функций, которые являются «драйвером» для hw, а затем вызов этого в основной программе. Затем предоставьте две разные реализации драйвера, одну для hw, одну для sw. Вариант sw будет соответствующим образом имитировать IO-эффект hw.

Обратите внимание, что если цель находится на более низком уровне, т. Е. Написание кода, в котором должен быть смоделирован каждый аппаратный доступ, а не целые функции, это может быть немного сложнее. Но здесь могут быть определены разные функции «write_to_memory» и «read_from_memory» (или макросы, если скорость на цели важна).

В любом случае нет необходимости изменять имена функций, достаточно иметь два разных пакетных файла, создавать файлы или целевые объекты сборки IDE (в зависимости от того, какие инструменты вы используете).

Наконец, во многих случаях лучшим техническим решением является использование полнофункционального симулятора целевой системы, такого как Qemu , Simics , SystemC , CoWare , VaST или аналогичные. Это позволяет вам постоянно выполнять один и тот же код, а вместо этого вы строите модель аппаратного обеспечения, которая работает как фактическое аппаратное обеспечение с точки зрения программного обеспечения. Это требует гораздо больших первоначальных инвестиций, но для многих проектов оно того стоит. Это в основном избавляет от неприятной проблемы наличия разных сборок для цели и хоста и гарантирует, что вы всегда будете использовать свой кросс-компилятор с опциями сборки развертывания. Обратите внимание, что многие встроенные компиляторы поставляются с некоторыми базовыми встроенными возможностями симуляции.

1 голос
/ 06 января 2009

Как сказал Герхард, используйте общий заголовочный файл "driver.h" и отдельные файлы реализации аппаратного уровня, содержащие фактические и заглушенные функции.

В eclipse у меня есть две цели, и я «исключаю из сборки» файл driver.c, который не должен использоваться, и проверяю, включен ли нужный объект в сборку. Затем Eclipse генерирует make-файл во время сборки.

Еще одна проблема, на которую следует обратить внимание, - убедиться, что вы определяете целые числа фиксированного размера, чтобы ваш код вел себя одинаково с точки зрения переполнения. (Хотя из вашего примера кода я вижу, что вы это делаете.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...