Я почав кодувати Arduino зовсім недавно. І ці помилки в коді мене вбивають. Оскільки в Arduino немає апаратного налагодження, serial.print () - єдиний мій курорт. Які методи / практики ви застосовуєте для налагодження коду Arduino?
Я почав кодувати Arduino зовсім недавно. І ці помилки в коді мене вбивають. Оскільки в Arduino немає апаратного налагодження, serial.print () - єдиний мій курорт. Які методи / практики ви застосовуєте для налагодження коду Arduino?
Відповіді:
Модульність - твій друг. Напишіть свій основний цикл, щоб виконати його, зателефонувавши до функцій, які викликають функції, ..., до рівня, на якому ваші функції будуть простими. Почніть з основної петлі та наступного рівня вниз, зробіть заглушки; або порожній:
function foo(){
;
}
або підробка:
function read_temperature(){
return(95);
}
, які не роблять нічого, окрім повернення того, що потрібно для виклику, щоб мати можливість продовжувати. Коли цей рівень працює, перейдіть до рівня та починайте заповнювати простий код, який також викликає функції заглушки. Поступово зніміть функцію за раз, поки у вас не буде робочої програми.
Щоб налагодити функцію, яка повертає неправильне значення, або створити її без будь-якого впливу з іншої частини програми, ви можете побудувати риштування - простий ескіз, який просто подає функцію деякі приклади значень, а в межах функції роздрукуйте значення параметрів і деякі проміжні значення, доки ви не зрозумієте, яка частина функції відмовляється. Я навіть робив фейки-функції, які підказують мене на терміналі, щоб повернути значення. (Очевидно, ця методика може працювати лише в тому випадку, якщо система може переносити відносно льодовикову швидкість у нас людей! Ще одне використання для риштування.)
Заглушка працює особливо добре, щоб перешкоджати функціям, що інтерфейсують до апаратного забезпечення, дозволяючи почати розробляти додаток до того, як вам доведеться зануритися в описи даних, часові проблеми та інші деталі (наприклад, не маючи деталей!), Які в іншому випадку можуть затримуватися. ваш прогрес.
Якщо говорити про проблеми з терміном, увімкнення вихідного штифта в певній точці вашої програми, наприклад, вхід та вихід із ISR, дає вам квадратну хвилю на штирі Arduino, частота чи робочий цикл може дати деяке уявлення про внутрішній час вашої програми. Форма прямого порту-вводу / виводу, наприклад,
PORTC ^= 0x01;
, буде спотворювати час менше, ніж дзвінки digitalWrite()
. Корисно, якщо у вас є "зручне поле" або один із DMM, здатний вимірювати частоту та / або робочий цикл.
Аналогічно, ви можете використовувати аналоговий вихідний штифт для виведення числового значення на ваш лічильник зсередини програми, не порушуючи занадто сильно синхронізуючи або роздуваючи код за допомогою послідовних функцій вводу / виводу. Використовуйте і прямі форми вводу / виводу тут.
3 Інші методики:
Нарощуйте функціональність програми, повільно тестуючи на кожному етапі, таким чином ви стикаєтеся лише з невеликим набором помилок одночасно.
Побудуйте програму навколо інтерпретатора команд, щоб ви могли одночасно працювати з секціями, як тут .
Пульсуйте у значні моменти часу та використовуйте сферу застосування.
Візуальний Micro плагін для Visual Studio надає Arduino Debug . Включає трасування і розрив вихідного коду, також дозволяє "переглядати" та / або змінювати вирази та змінні.
Виходячи з розкішних інструментів, таких як ARM або інших платформ (AVR, PIC з гідними інструментами), я погоджуюся, що засоби налагодження Arduino занадто обмежені. Але це інструмент для початківців з низьким рівнем входу.
Serial.print () - ваш друг. До мого конкретного проекту (коледжу) у мене не було додано жодних світлодіодів, тому Serial.print () це так. Якщо я хочу перевірити, чи правильно запускається код через оператори, я зазвичай розміщую Serial.print ("A"); , потім переходимо до B, C тощо або щось через розділ, де я налагоджую. Я порівнюю букви налагодження з тим, на що я очікував, що це має зробити.
Крім цього, немає точок перерви чи крокового коду. Arduino - це не що інше, як плата з чіпом AVR atmega, завантажувачем + середовищем розробки та безліччю бібліотек програмного забезпечення. На жаль, робота з завантажувачем обмежує можливості налагодження.
Для використання serial.print
більш контрольованого ви можете визначити глобальну булеву змінну для включення та вимикання налагодження. Будь-які рядки з serial.print
буде обгорнуто в if
оператор, який буде виконаний, лише якщо прапор налагодження увімкнено. Таким чином, ви можете залишити рядки налагодження в коді навіть тоді, коли закінчите, але переконайтеся, що прапор налагодження встановити в положення OFF (Вимкнено) пізніше.
Краще, ніж безпосередньо serial.print, використовуйте макроси. Приклад:
#ifdef TRACE1
#define trace1(s) serial.print(s)
#define traceln1(s) serial.println(s)
#else
#define trace1(s)
#define traceln1(s)
#endif
Використовуйте його так:
function doIt(param1, param2) {
trace1("->doIt("); trace1("param1: "); trace1(param1); trace1(" param2: "); trace1(param2); traceln1(")");
...
traceln1("<-doIt");
}
У вас можуть бути різні рівні слідів (#ifdef TRACE2 ...)
із більш детальною інформацією.
І ви можете використовувати «F» макрос (trace1(F("param1"));)
. Макрос "F" запобігає використанню вкрай обмеженої кількості SRAM.
Блимайте світлодіоди, друкуйте речі на послідовному порту, а також записуйте та відладжуйте невеликі розділи коду одночасно, іноді лише кілька рядків.
Бувають моменти, коли можна модулювати. Наприклад, у C ви можете розробити та протестувати обчислювальну функцію, наприклад, яка не торкається обладнання на хост-комп'ютері, іншому процесорі, оберніть функцію тестовим стендом, щоб подати на неї входи та перевірити виходи тощо.
Іншим подібним способом може бути використання симулятора наборів інструкцій, якщо у вас є доступ до одного (якщо ні, це дуже навчальний та корисний проект, після того, як ви зробите декілька з них, ви можете вирватись на вихідні або два). Ще краще, якщо хтось має клон Verilog або VHDL процесора (наприклад, OpenCores ), ви можете спробувати GHDL, Verilator або Icarus Verilog . Це може бути досить близько, щоб включити периферійні пристрої, які вас цікавлять, і ви можете отримати видимість рівня сигналу в тому, що відбувається всередині.
Звичайно, це, мабуть, не ідеальний клон, але це може бути досить добре. Verilator дозволяє дуже просто створювати периферійні пристрої в C / C ++, щоб ви могли імітувати все, до чого підключений ваш AVR-пристрій.
Вихід UART та блимання світлодіодів та / або блимання ліній GPIO та використання осцилографа або вольтметра. Ключ до того, що не сходити з розуму - це написання та налагодження невеликих розділів коду. Я краще написати 10 рядків одночасно і виконати 100 тестів, ніж 1000 рядків і спробувати відладкувати їх усі за один кадр. Особливо, коли ви дізнаєтесь, що більшість таблиць даних та програмістів посилання на керівництво по техніці не завжди є правильним. Деякі злому завжди потрібні.