Как я могу проверить код Arduino?

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

есть Arduino эмулятор в разработке который может быть полезен, но он еще не готов к использованию.

AVR Studio от Atmel содержит симулятор чипа, который может быть полезен, но я не вижу, как я буду использовать его в совместно с IDE Arduino.

18 ответов


не запускать модульные тесты на устройстве Arduino или эмуляторе

дело против устройства микроконтроллера / эмулятора / Sim-тестов на основе

цель модульного тестирования-проверить качество вашего собственного кода. Модульные тесты должны никогда проверьте функциональность факторов, находящихся вне вашего контроля.

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

независимо от того, рассматриваете ли вы запуск тестов на устройстве или эмуляторе, вы все еще заставляете себя повторять жестоко медленный процесс:

  1. настроить код
  2. компиляция и загрузка в Arduino устройство
  3. наблюдать за поведением и гадать о том, работает ли он или нет.
  4. повторить

Шаг 3 особенно неприятен, если вы ожидаете получить диагностические сообщения через последовательный порт, но ваш проект сам должен использовать только последовательный порт вашего Arduino. Если вы думаете, что библиотека SoftwareSerial может помочь, вы должны знать, что это может нарушить любую функциональность, которая требует точного времени, например генерирование других сигналов одновременно. Именно эта проблема случилась со мной.

опять же, если вы должны были проверить свой эскиз с помощью эмулятора, и ваши критические по времени процедуры работали отлично, пока вы не загрузили в фактический Arduino, то единственный урок, который вы собираетесь узнать, заключается в том, что эмулятор неисправен-и зная это все еще показывает ничего о качестве собственной работы!

если глупо тестировать на устройстве или эмуляторе, что должны я делаю?

вы, вероятно, используете компьютер для работы над проектом Arduino. Этот компьютер буквально тысячи раз быстрее, чем микроконтроллер. Напишите тесты для сборки и запустить на компьютере.

помните, что поведение библиотеки Arduino и микроконтроллера должно быть предполагается, что либо правильно, либо по крайней мере последовательно неправильно.

когда ваши тесты производят вывод вопреки вашим ожиданиям, тогда у вас, вероятно, есть недостаток в вашем коде, который был протестирован. Если ваш тестовый вывод соответствует вашим ожиданиям, но программа не ведет себя правильно, когда вы загружаете ее в Arduino, то вы знаете, что ваши тесты были основаны на неправильных предположениях, и у вас, вероятно, есть дефектный тест. В любом случае вам будет дано реальное представление о том, какими должны быть ваши следующие изменения кода.

как построить и Запустите тесты на вашем ПК

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

Если части, которые вы хотите протестировать, вызывают какие-либо функции Arduino, вам нужно будет предоставить макетные замены в вашей тестовой программе. Это гораздо меньше работы, чем кажется. Ваши макеты на самом деле не должны ничего делать, кроме обеспечения предсказуемого ввода и вывода для ваших тестов.

любой из вашего собственного кода, который вы собираетесь протестировать, должен существовать в исходных файлах, отличных от.ФДЭ эскиз. Не волнуйтесь, ваш эскиз все равно будет компилироваться даже с некоторым исходным кодом за пределами эскиза. Когда вы действительно приступите к этому, в файле эскиза должно быть определено немного больше, чем обычная точка входа вашей программы.

все, что остается напишите фактические тесты, а затем скомпилируйте их с помощью своего любимого компилятора C++! Это, вероятно, лучше всего проиллюстрировать на примере реального мира.

фактический рабочий пример

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

источник mock_arduino.cpp, который содержит код, дублирующий некоторые функции поддержки, предоставляемые библиотекой Arduino:

#include <sys/timeb.h>
#include "mock_arduino.h"

timeb t_start;
unsigned long millis() {
  timeb t_now;
  ftime(&t_now);
  return (t_now.time  - t_start.time) * 1000 + (t_now.millitm - t_start.millitm);
}

void delay( unsigned long ms ) {
  unsigned long start = millis();
  while(millis() - start < ms){}
}

void initialize_mock_arduino() {
  ftime(&t_start);
}

я использую следующий макет для получения читаемого вывода, когда мой код записывает двоичные данные в аппаратный последовательный устройство.

fake_serial.h

#include <iostream>

class FakeSerial {
public:
  void begin(unsigned long);
  void end();
  size_t write(const unsigned char*, size_t);
};

extern FakeSerial Serial;

fake_serial.cpp

#include <cstring>
#include <iostream>
#include <iomanip>

#include "fake_serial.h"

void FakeSerial::begin(unsigned long speed) {
  return;
}

void FakeSerial::end() {
  return;
}

size_t FakeSerial::write( const unsigned char buf[], size_t size ) {
  using namespace std;
  ios_base::fmtflags oldFlags = cout.flags();
  streamsize oldPrec = cout.precision();
  char oldFill = cout.fill();

  cout << "Serial::write: ";
  cout << internal << setfill('0');

  for( unsigned int i = 0; i < size; i++ ){
    cout << setw(2) << hex << (unsigned int)buf[i] << " ";
  }
  cout << endl;

  cout.flags(oldFlags);
  cout.precision(oldPrec);
  cout.fill(oldFill);

  return size;
}

FakeSerial Serial;

и, наконец, фактическая тестовая программа:

#include "mock_arduino.h"

using namespace std;

void millis_test() {
  unsigned long start = millis();
  cout << "millis() test start: " << start << endl;
  while( millis() - start < 10000 ) {
    cout << millis() << endl;
    sleep(1);
  }
  unsigned long end = millis();
  cout << "End of test - duration: " << end - start << "ms" << endl;
}

void delay_test() {
  unsigned long start = millis();
  cout << "delay() test start: " << start << endl;
  while( millis() - start < 10000 ) {
    cout << millis() << endl;
    delay(250);
  }
  unsigned long end = millis();
  cout << "End of test - duration: " << end - start << "ms" << endl;
}

void run_tests() {
  millis_test();
  delay_test();
}

int main(int argc, char **argv){
  initialize_mock_arduino();
  run_tests();
}

этот пост достаточно длинный, поэтому, пожалуйста, обратитесь к мой проект на GitHub чтобы увидеть еще несколько тестовых случаев в действии. Я продолжаю работать в других ветвях, кроме master, поэтому проверьте эти ветви для дополнительных тестов.

я решил написать свои собственные легкие процедуры тестирования, но более надежные блок-тестирования, как CppUnit, также доступны.


в отсутствие каких-либо ранее существовавших модульных тестовых фреймворков для Arduino я создал ArduinoUnit. Вот простой эскиз Arduino, демонстрирующий его использование:

#include <ArduinoUnit.h>

// Create test suite
TestSuite suite;

void setup() {
    Serial.begin(9600);    
}

// Create a test called 'addition' in the test suite
test(addition) {
    assertEquals(3, 1 + 2);
}

void loop() {
    // Run test suite, printing results to the serial port
    suite.run();
}

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

например, я абстрактные порта с

#define SetPortA(v) {PORTA = v;}

тогда SetPortA можно легко высмеять, не добавляя код накладных расходов в версии PIC.

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

обновление:

я использую шов #include для кода блока, #включая код блока в файле C++ для тестовой установки и файл C для целевого кода.

в качестве примера я хочу мультиплексировать четыре 7 сегментных дисплея, один порт управляет сегментами, а второй выбирает дисплей. Код дисплея взаимодействует с дисплеями через SetSegmentData(char) и SetDisplay(char). Я могу высмеять их в своей тестовой установке C++ и проверить, что я получаю данные, которые я ожидаю. Для цель, которую я использую #define так что я получаю прямое назначение без накладных расходов на вызов функции

#define SetSegmentData(x) {PORTA = x;}

кажется,emulino сделал бы работу совершенно.

Emulino-это эмулятор для платформы Arduino от Greg Hewgill. (источник)

репозитории GitHub


simavr является AVR симулятор использование avr-gcc.

Он уже поддерживает несколько микроконтроллеров ATTiny и ATMega, и - по словам автора - легко добавить еще несколько.

в примерах лежит simduino, эмулятор Arduino. Он поддерживает запуск загрузчика Arduino и может быть запрограммирован с помощью avrdude через Socat (модифицированный С netcat).


вы можете модульный тест в Python с моим проектом,PySimAVR. Arscons используется для строительства и simavr для моделирования.

пример:

from pysimavr.sim import ArduinoSim    
def test_atmega88():
    mcu = 'atmega88'
    snippet = 'Serial.print("hello");'

    output = ArduinoSim(snippet=snippet, mcu=mcu, timespan=0.01).get_serial()
    assert output == 'hello'

Начать тест:

$ nosetests pysimavr/examples/test_example.py
pysimavr.examples.test_example.test_atmega88 ... ok

Я не знаю ни одной платформы, которая может тестировать код Arduino.

, есть Fritzing платформа, которую вы можете использовать для моделирования оборудования, а затем экспортировать диаграммы PCB и прочее.

стоит проверить.


мы используем платы Arduino для сбора данных в большом научном эксперименте. Впоследствии, мы должны поддерживать несколько плат Arduino с различными реализациями. Я написал утилиты Python для динамической загрузки шестнадцатеричных изображений Arduino во время модульного тестирования. Код, найденный по ссылке ниже, поддерживает Windows и Mac OS X через файл конфигурации. Чтобы узнать, где ваши шестнадцатеричные изображения размещаются Arduino IDE, нажмите клавишу shift, прежде чем нажать кнопку сборки (воспроизведения). Нажмите клавишу shift при нажатии upload, чтобы узнать, где ваш avrdude (утилита загрузки командной строки) находится в вашей системе / версии Arduino. Кроме того, вы можете посмотреть включенные файлы конфигурации и использовать свое местоположение установки (в настоящее время на Arduino 0020).

http://github.com/toddstavish/Python-Arduino-Unit-Testing


эта программа позволяет автоматизировать запуск нескольких модульных тестов Arduino. Процесс тестирования запускается на ПК, но тесты выполняются на фактическом оборудовании Arduino. Один набор модульных тестов обычно используется для тестирования одной библиотеки Arduino. (это

Форум Arduino:http://arduino.cc/forum/index.php?topic=140027.0

страница проекта GitHub:http://jeroendoggen.github.com/Arduino-TestSuite

страница в индексе пакета Python: http://pypi.python.org/pypi/arduino_testsuite

модульные тесты написаны с помощью "библиотеки модульного тестирования Arduino":http://code.google.com/p/arduinounit

для каждого набора модульных тестов выполняются следующие шаги:

  • прочитайте конфигурационный файл, чтобы узнать, какие тесты запускать
  • скрипт компилирует и загружает эскиз Arduino, содержащий код модульного тестирования.
  • unit-тесты бежать на плате Arduino.
  • результаты теста печатаются через последовательный порт и анализируются скриптом Python.
  • скрипт запускает следующий тест, повторяя вышеуказанные шаги для всех тестов, запрошенных в файле конфигурации.
  • скрипт печатает сводку, показывающую обзор всех неудачных / пройденных тестов в полном testsuite.

Я использую Searduino при написании кода Arduino. Searduino-это симулятор Arduino и среда разработки (Makefiles, C-код ...) это позволяет легко взломать C / C++ с помощью вашего любимого редактора. Вы можете импортировать эскизы Arduino и запускать их в симуляторе.

скриншот Searduino 0.8:http://searduino.files.wordpress.com/2014/01/jearduino-0-8.png

Searduino 0.9 выйдет и видео будет записываться как только как длится тесты проводятся .... через день или два.

тестирование на симуляторе не следует рассматривать как реальные тесты, но это, безусловно, помогло мне найти глупые / логические ошибки (забывая делать pinMode(xx, OUTPUT), etc.).

кстати: я один из людей, разрабатывающих Searduino.


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

в принципе, попробуйте построить как можно больше окончательного кода из как можно большего количества известных строительных блоков. Оставшаяся аппаратная работа будет намного проще и быстрее. Вы можете закончить его с помощью существующих эмуляторов и / или эмулирующих устройств самостоятельно. И, конечно, вам нужно будет как-то проверить настоящую вещь. В зависимости от обстоятельств, это может быть или не быть очень хорошо автоматизировано (т. е. кто или что будет нажимать кнопки и предоставлять другие входы? кто или что будет наблюдать и интерпретировать различные показатели и результаты?).


Джеймс У. Греннинг пишет отличные книги, и это о модульном тестировании встроенного кода C


есть проект под названием ncore, который обеспечивает родное ядро для Arduino. И позволяет писать тесты для кода Arduino.

описание проекта

собственное ядро позволяет компилировать и запускать эскизы Arduino на ПК, как правило, без изменений. Он предоставляет собственные версии стандартные функции Arduino и командной строки interepreter дать входные данные для эскиза, которые обычно поступают из аппаратного обеспечения себя.

также на "что мне нужно, чтобы использовать его в раздел"

Если вы хотите построить тесты, вам понадобится cxxtest от http://cxxtest.tigris.org. NCORE был протестирован с помощью cxxtest 3.10.1.


Если вы хотите модульный тестовый код вне MCU (на рабочем столе), проверьте libcheck: https://libcheck.github.io/check/

Я использовал его для тестирования моего собственного встроенного кода несколько раз. Это довольно прочная структура.


я рад объявить (как представляется) первый стабильный релиз рубиновый камень называется arduino_ci что я построил для этой цели. Хотя он ограничен тестированием библиотек Arduino (а не автономных эскизов), он позволяет запускать модульные тесты на Travis CI.

предполагая, что у вас установлены Ruby и rubygems, добавление этого CI в библиотеку просто. Давайте представим себе очень простую библиотеку в каталоге библиотеки Arduino под названием DoSomething. Он содержит файл заголовка, и эта реализация:

#include <Arduino.h>
#include "do-something.h"

int doSomething(void) {
  return 4;
};

давайте проверим это с arduino_ci. Во-первых, вам нужно добавить Gemfile в корневом каталоге вашей библиотеки со следующим содержимым:

source 'https://rubygems.org'
gem 'arduino_ci', '~> 0.1.7'

далее запустить bundle install.

далее, создайте каталог под названием test/. (Каждый .cpp файл, который вы размещаете здесь, будет считаться отдельным набором тестов). Мы создадим один тест сейчас, в test/is_four.cpp:

#include <ArduinoUnitTests.h>
#include "../do-something.h"

unittest(library_does_something)
{
  assertEqual(4, doSomething());
}

unittest_main()  // this is a macro for main().  just go with it.

вот и все. Если это assertEqual синтаксис и структура теста выглядит знакомо, это потому, что я принял некоторые библиотека ArduinoUnit Мэтью Мердока что он имел в виду в ответ.

теперь вы готовы запустить bundle exec arduino_ci_remote.rb, который будет выполнять эти тесты. Это может дать результат примерно так:

$ bundle exec arduino_ci_remote.rb
Installing library under test...                                               ✓
Library installed at /Users/XXXXX/Documents/Arduino/libraries/DoSomething...   ✓
Checking GCC version...
    Using built-in specs.
    COLLECT_GCC=g++-4.9
    COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc@4.9/4.9.4_1/libexec/gcc/x86_64-apple-darwin16.    7.0/4.9.4/lto-wrapper
    Target: x86_64-apple-darwin16.7.0
    Configured with: ../configure --build=x86_64-apple-darwin16.7.0     --prefix=/usr/local/Cellar/gcc@4.9/4.9.4_1     --libdir=/usr/local/Cellar/gcc@4.9/4.9.4_1/lib/gcc/4.9 --enable-languages=c,c++,objc,    obj-c++,fortran --program-suffix=-4.9 --with-system-zlib --enable-libstdcxx-time=yes     --enable-stage1-checking --enable-checking=release --enable-lto --enable-plugin     --with-build-config=bootstrap-debug --disable-werror --with-pkgversion='Homebrew GCC     4.9.4_1' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues     MAKEINFO=missing --disable-nls --enable-multilib
    Thread model: posix
    gcc version 4.9.4 (Homebrew GCC 4.9.4_1)
...Checking GCC version                                                        ✓
Installing board package arduino:sam...                                        ✓
Unit testing is_four.cpp...

TAP version 13
1..1
# Subtest: library_does_something
    ok 1 - assertEqual 4 == doSomething()
    1..1
ok 1 - library_does_something
...Unit testing is_four.cpp                                                    ✓
Failures: 0

запуск того же кода как часть задания CI на Трэвис ки (например, чтобы вы могли вызвать его из запросов GitHub pull) тоже просто. Просто добавьте это в свой :

language: ruby
script:
   - bundle install
   - bundle exec arduino_ci_remote.rb

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


можно использовать emulare - вы можете перетащить микроконтроллер на диаграмму и запустить свой код в Eclipse. Документация на веб-сайте рассказывает вам, как ее настроить.


используйте Proteus VSM с библиотекой Arduino для отладки кода или его тестирования.

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


попробовать Autodesk circuit simulator. Он позволяет тестировать код Arduino и схемы со многими другими аппаратными компонентами.