Основы отладки

Узнайте основы отладки систем на базе микроконтроллеров.

Авторы: José Bagur, Taddy Chung

Последняя ревизия: 10.04.2026

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

Проектирование встраиваемых систем сложно, поскольку оно сочетает разработку аппаратуры, прошивки и программного обеспечения в одном устройстве или продукте. Чтобы создавать качественную прошивку и ПО для встраиваемых систем, отладка — необходимый этап в процессе разработки. Отладка — это процесс подтверждения того, что многие вещи, которые мы считаем истинными и работающими в нашем коде, действительно таковы. Мы находим «баг» в коде, когда одно или несколько наших предположений оказываются неверными.

Примечание

Люди по всему миру говорят о «багах» давно; даже Томас Алва Эдисон использовал это слово в своё время. «Баг» использовался как старое слово для «монстра»; как гремлины в механике, баги вредны.

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

Инструменты и техники отладки

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

  • Компилятор и синтаксические ошибки.

  • Традиционные техники: trace code и GPIO.

  • Удалённые отладчики.

  • Симуляторы.

  • In-circuit эмуляторы и in-circuit отладчики.

  • Аппаратные инструменты: мультиметры, логические анализаторы, осциллографы и программно-определяемые радио (SDR).

Рассмотрим каждый из инструментов и техник.

Компилятор и синтаксические ошибки

Компиляция — это преобразование высокоуровневого кода в машинный язык, понимаемый процессором, например, микроконтроллером. В этом процессе компилятор также помогает выявить синтаксические ошибки. Они указывают на проблему с синтаксисом программы; например, когда в конце инструкции пропущена точка с запятой, компилятор выдаёт синтаксическую ошибку.

Компилятор Arduino IDE 2 показывает синтаксическую ошибку в скетче.

Компилятор Arduino IDE 2 показывает синтаксическую ошибку в скетче.

Использование компилятора для отладки синтаксических ошибок может быть непростым; рассмотрим две распространённые ситуации:

  • Компилятор показывает 100 ошибок: это обычно не означает, что ошибок 100; компилятор часто сбивается на некоторое время, найдя ошибку. Он пытается восстановиться и продолжить после первой ошибки, но иногда сообщает ложные. Только первое сообщение об ошибке действительно надёжно; пробуйте исправлять по одной и пересобирать программу.

  • Странные сообщения компилятора: ошибки компилятора показываются на сжатом жаргоне, иногда трудном для чтения, но содержащем ценную информацию. Внимательно читайте сообщение об ошибке; оно всегда укажет, где именно в коде произошла ошибка.

Традиционные техники: trace code и GPIO

Добавление trace code — пожалуй, простейшая и наиболее базовая техника отладки во встраиваемых системах. Метод состоит в добавлении в программу trace-кода для печати сообщений или значений переменных (используя функцию

Serial.print()

например) по мере выполнения программы. Например, определение того, зависает ли определённая функция, можно сделать с помощью trace-кода, как показано ниже:

// Print a message if the execution gets here
Serial.println("Code got here");

// Try to execute myFunction1()
myFunction1();

// Print a message if the execution gets here
Serial.println("Code got here, myFunction1 executed");

// Try to execute myFunction2()
myFunction2();

// Print a message if the execution gets here
Serial.println("Code got here, myFunction2 executed");

Использование trace-кода для отладки обычно применимо только на ранних этапах разработки кода встраиваемой системы. Добавление trace-кода требует значительного процессорного времени и ресурсов. Поэтому это может легко нарушать критические по времени задачи. Кроме того, если UART используется для других задач, отображение trace-кода может быть проблематичным.

Совет

Можно передавать строки из flash-памяти в инструкцию Serial.print(), обернув их макросом F(); например, Serial.println(F("Code got here")) печатает строку из flash.

Другая техника trace-кода — сброс стратегической информации в массив во время выполнения, чтобы потом, например по завершении программы, изучить содержимое массива; этот метод также называют dump into array. Допустим,

good

и

bad

— две стратегические переменные, которые мы хотим зафиксировать. Первый шаг — определить буфер отладки в RAM:

#define DUMP_BUFFER_SIZE 32
unsigned char goodBuffer[DUMP_BUFFER_SIZE];
unsigned char badBuffer[DUMP_BUFFER_SIZE];
unsigned long count = 0;

Переменная

count

используется как индекс в буфер; она должна быть проинициализирована нулём перед началом отладки. Код ниже сбрасывает стратегическую информацию из

good

и

bad

в буфер:

void Save_Debug_Buffer(void) {
  if (count < DUMP_BUFFER_SIZE) {
    goodBuffer[count] = good;
    badBuffer[count] = bad;
    count++;
  }
}

Пины ввода/вывода общего назначения (GPIO) могут помочь в отладке, когда UART занят или trace-код не особенно полезен. Например, мы можем включать или выключать встроенный светодиод платы Arduino®, вставляя инструкцию

digitalWrite(LED_BUILTIN, HIGH)

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

// Print a message if the execution gets here
Serial.println("Code got here");

// Try to execute myFunction1()
myFunction1();

// Turn on the built-in LED for one second to indicate that myFunction1 was executed
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);

// Try to execute myFunction2()
myFunction2();

// Turn on the built-in LED for one second to indicate that myFunction2 was executed
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);

Удалённые отладчики

Удалённая отладка — ещё один распространённый подход к отладке встраиваемых систем. Удалённые отладчики работают, подключая встраиваемую систему к хост-компьютеру и используя ПО на хосте для взаимодействия с аппаратурой встраиваемой системы. Удалённые отладчики полезны, когда среда разработки находится на другой архитектуре, отличной от целевой. Например, разработка кода на Windows для системы на базе ARM-микроконтроллера.

Удалённые отладчики обычно состоят из двух основных частей: front-end debugger и back-end debugger.

  • Front-end отладчик содержит пользовательский интерфейс (графический или командной строки) и предоставляет программисту выбор по выполнению кода на аппаратуре встраиваемой системы.

  • Back-end отладчик, известный также как «debug monitor», специфичен для конкретной архитектуры процессора или семейства и обычно работает с внешним аппаратным средством, например ICE или ICD. Он стартует при сбросе процессора и обрабатывает выполнение инструкций между front-end отладчиком и аппаратурой встраиваемой системы.

Совет

Инструмент отладчика — недавно появившаяся, но менее известная функция Arduino IDE 2. См. этот туториал, показывающий использование отладчика Arduino® IDE 2 на поддерживаемых платах.

Симуляторы

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

Совет

Tinkercad Circuits — отличный симулятор для начинающих в экосистеме Arduino®. Он может симулировать набор инструкций Arduino® UNO и работу нескольких электронных компонентов: резисторов, светодиодов, моторов, ЖК-экранов и некоторых датчиков.

Симуляция схемы в Tinkercad Circuits.

Симуляция схемы в Tinkercad Circuits.

In-Circuit эмуляторы и In-Circuit отладчики

In-circuit emulator (или ICE) — специализированный инструмент, позволяющий разработчикам исследовать состояние процессора, пока выполняется конкретная программа. ICE сами по себе считаются встраиваемыми системами; они являются копией целевого процессора и его памяти (RAM и ROM); поэтому они дают неинвазивный способ отладки кода на целевом процессоре. Исторически ICE были инструментом выбора разработчиков встраиваемых систем, но по мере роста сложности процессоров и тактовой частоты ICE становились дороже, и их доступность значительно снизилась.

ICE Mikrotek начала 1990-х для микропроцессоров 8086.

ICE Mikrotek начала 1990-х для микропроцессоров 8086.

Binarysequence, CC BY-SA 3.0, через Wikimedia Commons.

In-circuit debugger (или ICD) — также специализированный инструмент, подключаемый между хост-компьютером и процессором для более быстрой и удобной отладки приложений в реальном времени; этот инструмент использует часть памяти и GPIO целевого микроконтроллера во время отладки. С ICD разработчики получают доступ к встроенному в CPU модулю отладки через интерфейс (например, JTAG). Этот модуль позволяет загружать, запускать, останавливать и шагать по процессору.

SEGGER J-Link EDU JTAG/SWD debug-зонд.

SEGGER J-Link EDU JTAG/SWD debug-зонд.

SEGGER Microcontroller GmbH & Co, CC BY-SA 3.0, через Wikimedia Commons.

Примечание

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

Поддержка ICD на Arduino®

Платы Arduino® с микроконтроллером SAMD поддерживают ICD-отладку:

Плата Arduino® Zero имеет встроенный отладчик Atmel® Embedded Debugger (EDGB). Помимо поддержки программирования и отладки, EDGB также позволяет потоковую передачу данных между хостом и целевым процессором. См. этот туториал, чтобы научиться использовать возможности отладки Arduino® Zero с Arduino IDE 2.

Arduino® Zero EDGB.

Arduino® Zero EDGB.

Платы Arduino® с микроконтроллером SAMD имеют встроенные возможности on-chip debug; их можно использовать с внешним ICD-инструментом через интерфейсы JTAG или SWD. CMSIS-DAP-совместимые debug-зонды можно использовать с Arduino IDE 2 «из коробки» без файла конфигурации; нестандартные зонды требуют специальной конфигурации. См. туториалы:

Платы Arduino® Portenta H7, H7 Lite и H7 Lite Connected из семейства Pro также поддерживают ICD-отладку; они используют отладчик TRACE32 от Lauterbach. TRACE32 позволяет тестировать встраиваемое железо и ПО, используя интерфейс in-circuit debug процессоров. См. туториал:

Arduino® Portenta H7.

Arduino® Portenta H7.

Аппаратные инструменты

Разработчики встраиваемых систем и обычные разработчики ПО различаются в одном ключевом аспекте: «близости» к аппаратуре; разработчики встраиваемых систем обычно ближе к железу. Есть несколько инструментов, которые они используют, чтобы понять, что происходит с аппаратурой — это очень помогает при низкоуровневой отладке ПО. Эти инструменты — мультиметры, логические анализаторы, осциллографы и программно-определяемые радио (SDR).

Рассмотрим каждый из аппаратных инструментов отладки. Базовое понимание этих инструментов значительно улучшает навыки отладки.

Примечание

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

Мультиметры

Цифровой мультиметр (DMM) — аппаратный инструмент, измеряющий два или более электрических значения, обычно напряжение (вольты), ток (амперы) и сопротивление (омы). DMM — отличный инструмент и одно из самых фундаментальных средств тестирования для отладки электрических проблем во встраиваемой системе.

Цифровой мультиметр.

Цифровой мультиметр.

oomlout, CC BY-SA 2.0, через Wikimedia Commons.

Логические анализаторы

Логический анализатор — аппаратный инструмент, специально разработанный для захвата, отображения и измерения электрических сигналов в цифровой схеме. Состоит из нескольких цифровых входных пинов, способных определять, находится ли электрический сигнал на конкретном логическом уровне (1 или 0). Логические анализаторы также могут показывать соотношение и тайминг разных сигналов в цифровой схеме и часто способны анализировать протоколы цифровой связи (например, SPI).

24 МГц 8-канальный логический анализатор.

24 МГц 8-канальный логический анализатор.

SparkFun Electronics, CC BY-SA 2.0, через Wikimedia Commons.

Осциллографы

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

50 МГц 4-канальный осциллограф.

50 МГц 4-канальный осциллограф.

Dave Jones from Australia, CC BY-SA 2.0, через Wikimedia Commons.

Программно-определяемые радио

Программно-определяемое радио (SDR) — система радиосвязи, использующая ПО для модуляции и демодуляции радиосигналов. Традиционная обработка опирается на аппаратные компоненты, что ограничивает их перепрограммирование. SDR гораздо гибче, поскольку их можно перенастраивать программно.

SDR HackRF.

SDR HackRF.

Alexander Neumann, Public domain, через Wikimedia Commons.

Отладка с аппаратными инструментами

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

Иногда светодиоды отсутствуют или недоступны; в системе нет способа сделать визуальный осмотр. Однако в этом случае можно использовать осциллограф для мониторинга состояния GPIO напрямую. Осциллограф также можно использовать, чтобы видеть, выдаёт ли код определённую обратную связь, переключая GPIO в нужное логическое состояние. DMM также может пригодиться для той же задачи.

Чтобы получить максимум от осциллографа и GPIO — измеряйте производительность, то есть электрические и временные характеристики сигнала. Например, ненужная задержка в коде:

void myFunction() {
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.println("Code got here");
  count++;
  digitalWrite(LED_BUILTIN, LOW);
}

Длительность выполнения

myFunction()

можно измерить, переводя GPIO в высокое состояние при начале выполнения; по завершении — в низкое. Осциллограф затем покажет, заняло ли выполнение функции точно заданное время, дольше или короче, или есть ли неучтённое электрическое поведение.

Теперь поговорим о беспроводной связи. Беспроводная связь — ключевая возможность при разработке новых IoT-устройств с разными требованиями. Аппаратура Arduino® не исключение. Вопрос: как отлаживать беспроводную связь между устройствами?

Простой и распространённый метод — использование acknowledge-флагов. Их применение помогает понять поведение устройства при установленной связи, предоставляя их текущий статус. Этот процесс встречается также в физических протоколах связи (I2C, SPI). Из-за разных типов протоколов в беспроводной связи использование acknowledge-флагов отличается своими правилами. Простейший способ подтвердить успешный обмен — проверить лог данных на каждом конце. Аппаратные инструменты (DMM, осциллографы, логические анализаторы) могут добавить деталей.

Однако не всё подключено на физическом слое — есть абстрактный слой. В беспроводной связи это электромагнитные волны, распространяющиеся в пространстве. Зачем нам отлаживать электромагнитные волны? Иногда нужно проверить, что конфигурация беспроводного приёмопередатчика конкретной встраиваемой системы корректна, например, его мощность передачи. SDR могут пригодиться: их можно использовать как дешёвые анализаторы спектра. Анализатор спектра — аппаратный инструмент, измеряющий магнитуду сигнала относительно частоты; в основном используется для измерения спектра мощности сигнала. Использование SDR как анализатора спектра — обычно опциональный метод отладки в процессе разработки, обеспечивающий более устойчивый дизайн.

Совет

Несколько программ работают с SDR; GQRX — одно из популярных, open-source, кросс-платформенное (Linux, macOS). AirSpy и CubicSDR — другие популярные программы (Windows, Linux, macOS).

Показанное визуальное представление сигнала через ПО SDR можно использовать для проверки выходной мощности передачи и количества переданных данных. Это поможет визуализировать конфигурацию беспроводной связи устройства. Можно проверить мощность приёма и передачи, число переданных байт, и частоту, на которой идёт передача. Эти свойства можно отлаживать через спектр частот для лучшей производительности беспроводной связи.

Сигналы LoRa, показанные на спектрограмме. Источник: The Things Network.

Сигналы LoRa, показанные на спектрограмме. Источник: The Things Network.

Пример техник отладки

Простой пример продемонстрирует реализацию некоторых техник отладки в экосистеме Arduino®. Используем плату Arduino® Nano 33 BLE Sense с её встроенным IMU. Пример использует данные акселерометра, гироскопа и магнитометра одновременно:

/*
  Program:
  - Debugging_techniques_example.ino

  Description:
  - This example combines data from the LSM9DS1 accelerometer, gyroscope, and magnetometer into a single code. On top of it,
  it helps to understand different methods and techniques of debugging when the code structure combines multiple tasks.

  The circuit:
  - Arduino Nano 33 BLE Sense.

  Code based on examples created by Riccardo Rizzo, Jose García, and Benjamin Dannegård.
  Modified by Taddy Ho Chung and José Bagur (16/02/22).
*/

#include <Arduino_LSM9DS1.h>

#define DUMP_BUFFER_SIZE 32
unsigned char GoodBuffer[DUMP_BUFFER_SIZE];
unsigned char BadBuffer[DUMP_BUFFER_SIZE];
unsigned long count = 0;
uint8_t good, bad = 0;

float x, y, z, ledvalue;
int degreesX = 0, degreesY = 0;
int plusThreshold = 30, minusThreshold = -30;

void setup() {
  Serial.begin(9600);
  while (!Serial);
  Serial.println("- Started");

  if (!IMU.begin()) {
    Serial.println("- Failed to initialize IMU!");

    bad++;
    save_debug_buffer();
    disp_debug_buffer();
    debug_stop();
  }

  accelermeter_setup();
  gyroscope_setup();

}

void loop() {
  for (int i = 0; i < 5; i++) {
    accelerometer_task();
    gyroscope_task();
    magnetometer_task();
  }

  save_debug_buffer();
  debug_stop();
}

// Accelerometer setup
void accelermeter_setup() {
  Serial.print(F("- Accelerometer sample rate: "));
  Serial.print(IMU.accelerationSampleRate());
  Serial.println(F(" Hz"));
}

// Read accelerometer data in all three directions task
void accelerometer_task() {
  if (IMU.accelerationAvailable()) {
    Serial.println(F("- Accelerometer data ready"));
    IMU.readAcceleration(x, y, z);
    good++;
  } else {
    Serial.println(F("- Accelerometer data not ready"));
    bad++;
  }

  if (x > 0.1) {
    x = 100 * x;
    degreesX = map(x, 0, 97, 0, 90);
    Serial.print(F("- Tilting up "));
    Serial.print(degreesX);
    Serial.println(F("  degrees"));
  }

  if (x < -0.1) {
    x = 100 * x;
    degreesX = map(x, 0, -100, 0, 90);
    Serial.print(F("- Tilting down "));
    Serial.print(degreesX);
    Serial.println(F("  degrees"));
  }

  if (y > 0.1) {
    y = 100 * y;
    degreesY = map(y, 0, 97, 0, 90);
    Serial.print(F("- Tilting left "));
    Serial.print(degreesY);
    Serial.println(F("  degrees"));
  }

  if (y < -0.1) {
    y = 100 * y;
    degreesY = map(y, 0, -100, 0, 90);
    Serial.print(F("- Tilting right "));
    Serial.print(degreesY);
    Serial.println(F("  degrees"));
  }

  delay(1000);
}

// Gyroscope setup
void gyroscope_setup() {
  Serial.print(F("- Gyroscope sample rate = "));
  Serial.print(IMU.gyroscopeSampleRate());
  Serial.println(F(" Hz"));
  Serial.println();
  Serial.println(F("- Gyroscope in degrees/second"));
}

// Read gyroscope data in all three directions task
void gyroscope_task( ) {
  if (IMU.gyroscopeAvailable()) {
    IMU.readGyroscope(x, y, z);
    Serial.println(F("- Gyroscope data ready"));
    good++;
  } else {
    Serial.println(F("- Gyroscope data not ready"));
    bad++;
  }

  if(y > plusThreshold) {
    Serial.println(F("- Collision front"));
    delay(500);
  }

  if(y < minusThreshold) {
    Serial.println(F("- Collision back"));
    delay(500);
  }

  if(x < minusThreshold) {
    Serial.println(F("- Collision right"));
    delay(500);
  }

  if(x > plusThreshold) {
    Serial.println(F("- Collision left"));
    delay(500);
  }
}

// Read magnetometer data in all three directions task
void magnetometer_task(){
  IMU.readMagneticField(x, y, z);

  if(x < 0) {
    ledvalue = -(x);
  }
  else {
    ledvalue = x;
  }

  analogWrite(LED_BUILTIN, ledvalue);
  delay(500);
}

// For debugging purposes
void save_debug_buffer(void) {
  if (count < DUMP_BUFFER_SIZE) {
    GoodBuffer[count] = good;
    BadBuffer[count] = bad;
    disp_debug_buffer();
    count++;
  }
}

// Debugging array buffer
void disp_debug_buffer() {
  Serial.println(F("\n Debugging array buffer result >>"));
  Serial.print(F("- Good marks: "));
  Serial.println(GoodBuffer[count]);

  Serial.print(F("- Bad marks: "));
  Serial.println(BadBuffer[count]);
}

void debug_stop() {
  Serial.flush();
  exit(1);
}

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

good

и

bad

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

Важно знать, когда останавливать код во время отладки. Например, остановка после первого прогона даёт следующий результат:

Один runtime-инстанс отладочного массива.

Один runtime-инстанс отладочного массива.

В Arduino Serial Monitor мы видим, что у нас 1 good-метка и 1 bad-метка. Good пришёл от гироскопа (данные были готовы), bad — от акселерометра (данные не готовы). То есть акселерометр не успевает подготовить данные до измерительной задачи. Можно прогнать несколько итераций до сектора сброса:

5 runtime-инстансов отладочного массива.

5 runtime-инстансов отладочного массива.

Акселерометр выполнил задачу без проблем, кроме первого прогона, что дало 9 good и 1 bad. Инструкции

Serial.println(F())

в setup модулей и в задачах также показывают, прошёл ли код операции без проблем.

Дополнительно можно изменить loop, добавив

digitalWrite(12, HIGH)

перед задачами и

digitalWrite(12, LOW)

после, чтобы измерить время их выполнения с помощью GPIO 12 и осциллографа. Это поможет понять и потребление энергии:

void loop() {
  for (int i = 0; i < 5; i++) {
    digitalWrite(12, LOW);
    accelerometer_task();
    gyroscope_task();
    magnetometer_task();
    digitalWrite(12, HIGH);
  }

  save_debug_buffer();
  debug_stop();
}
Использование осциллографа и GPIO для измерения времени выполнения задач.

Использование осциллографа и GPIO для измерения времени выполнения задач.

Заключительные мысли об отладке

Отладка — необходимый этап в разработке надёжного ПО для встраиваемых систем. Закончим статью упоминанием четырёх наиболее важных фаз отладки, описанных Robin Knoke в статье об отладке embedded C, опубликованной в журнале Embedded Systems Programming:

  • Тестирование: фаза проверяет возможности embedded-ПО, стимулируя его широким диапазоном входных значений в разных средах.

  • Стабилизация: фаза попыток контролировать условия, генерирующие конкретный баг.

  • Локализация: фаза сужения диапазона возможностей до изоляции бага в конкретном сегменте кода.

  • Коррекция: фаза устранения бага из ПО.

Знание потенциальных причин багов позволяет принять стратегии, минимизирующие их возникновение. Существует много техник отладки и внешних устройств, помогающих в этом процессе. Возможно, некоторым проектам не нужны внешние отладчики. Однако когда ПО предъявляет разные требования, особенно к масштабируемости, всё резко меняется. Техники и внешние отладчики поддержат процесс разработки, обеспечивая сложное ПО.

Отладка может быть недооценённым аспектом разработки встраиваемых систем, но это её самый серьёзный и важный инструмент. Если мы хотим разрабатывать надёжные встраиваемые системы, процесс отладки должен последовательно применяться для достижения этих целей.

Дополнительные материалы

Если хотите узнать больше об инструментах и техниках отладки:

Литература

[1] P. Koopman, Better Embedded System Software. S.L.: Drumnadrochit Press, 2010.

[2] D. J. Agans, Debugging: The Nine Indispensable Rules for Finding Even the Most Elusive Software and Hardware Problems. New York: Amacom, 2002.

[3] M. Barr and A. Massa, Programming Embedded Systems: with C and GNU Development Tools. Johanneshov: MTM, 2013.

[4] J. W. Valvano, Embedded Systems: Introduction to ARM® Cortex™-M Microcontrollers. United States: Self-published, 2015.