Многие из тех, кто делает проекты чуть сложнее «Hello, World!» для микроконтроллеров рано или поздно сталкиваются с проблемой отладки кода. В таких ситуациях, как правило, отладочная информация представляет собой вывод в консоль, либо определенное количество «мыргов» каким-либо светодиодом. Тем, кто отлаживался с помощью printf, prinln и иже с ними, нет нужды объяснять, что даже понять в какие места поставить дебажный вывод — иногда проблема, интерпретировать же результат и понять где ошибка еще сложнее.
Относительно недавно я наткнулся на софтину, которая позволяет отлаживать код Arduino прямо в кристалле способом, который очень похож на обычную отладку кода, к которому можно подключить более-менее развитый отладчик. Кому интересно, милости прошу под кат.
Во избежание кривотолков, скажу, что топик ни в коем разе не является рекламным, а имеет целью разделить с сообществом мой опыт отладки кода для Arduino и качественный скачок, который этот опыт претерпел в связи с нахождением мной продукта VisualMicro (www.visualmicro.com). Так же хочется сразу предупредить комментарии типа «ага, ставить монстра VisualStudio для написания маленьких прошивок для маленьких контроллеров...». Сам я являюсь пользователем VisualStudio со стажем лет эдак в 15, она у меня уже в мозжечке сидит (даже если где-то объективно неудобна, то я этого уже все равно не замечаю в силу привычки). Так что унификация дебаггинг-процесса для Arduino и кода, который я обычно пишу в VS, вызывает у меня дикий восторг: надо же, «взрослый дебаггинг» для «маленькой железяки». По поводу «монструозности» имею сказать следующее. Да, размер VS намного больше Arduino IDE, но место на винте сейчас дешевле овса. Имея двухтерабайтный винчестер, жадничать гигабайт — моветон. Да он грузится дольше, но если посчитать разницу увеличенного времени загрузки и сэкономленного на дебаггинге времени, получается приличный профит. Студию я загружаю один раз в день (так что это +20 секунд загрузки в день на моем не самом навороченном домашнем ноуте на Core i3 первого поколения), а вот на дебаггинг трачу часы. Кроме того, через очень короткое время Arduino IDE для неновичка в программировании становится тесноватой и начинаешь задумываться как бы сломать рамки, которые она накладывает. Ну и последний аргумент против такого сетапа для отладки Arduino — VS стоит конских денег. Да, это правда, но есть несколько «но»:
Итак, VisualMicro — это плагин для VisualStudio (и, как следствие, для AtmelStudio), в котором есть:
Существует две версии плагина — бесплатная, которая реализует первые три пункта, и платная, поддерживающая отладку. Стоит относительно недешево — около 29$, но разработчики обещают бесплатную лицензию бетатестерам, да и просто людям, как-либо вложившимся в проект.
Возможностей у продукта много и они достаточно хорошо описаны в Wiki, а статья не претендует на звание руководства по применению, так что опишу только те, которые я успел попользовать, а именно:
Первое, что нужно сказать, что волшебства никакого не происходит. Возможность отладки появляется за счет инструментирования кода (прямых доказательств в виде упоминаний в том же Wiki не нашел, код не дизассемблировал, но увеличение размера «дебагабельного» кода по сравнению с оригинальным говорит само за себя). Т.е. плагин при компиляции с поддержкой отладки встраивает в код куски, которые позволяют отлаживаться. Естественно, размер кода при этом растет. С другой стороны, когда вы за ненадобностью выкинете из кода все отладочные println, с удовольствием обнаружите, что в итоге даже с инструментированием код стал компактнее. Второе замечание касается отличия отладки с помощью этого плагина от процесса «обычной отладки». Все привыкли, что код компилируется один раз и потом уже в runtime, при подключенном отладчике, можно ставить точки останова и смотреть какую угодно память. Здесь это не так. Точку останова нужно ставить до начала процесса отладки, потому что упомянутому мной инструментированию подвергаются только те участки кода, для которых заранее известно желание пользователя в них останавливаться. С просмотром значений переменных ситуация схожая: необходимо заранее дать плагину знать какие переменные и в каких местах вы собираетесь смотреть/менять. Благо делается это не слишком сложно.
Предположим, что вы знаете как зашивать скетч через Arduino IDE (ну мало ли...), т.е. с прошивкой у вас проблем не возникает. Предположим, вы уже установили плагин, т.е. прошли через процедуру настройки. Допустим, у вас уже есть скетч, который вы подготовили в Arduino IDE. В этом случае создание проекта в VS сводится к открытию скетча через File->Open->Sketch project. Для созданного проекта нужно поставить опцию MicroDebug в Full. После этого у вас есть две возможности — классические для VS «Start without debugging» и «Start debugging». Первая компилирует код и заливает его в Arduino. Вторая — компилирует код с инструментированием и начинает сессию отладки. По умолчанию, кстати, плагин не разрешает программе останавливаться, даже если вы настроили точку останова. В этом есть своя логика. Поскольку Arduino используется, например, в робототехнических проектах, останов может привести к печальным последствиям. Представьте, вы включили двигатели робота, он начал двигаться, а вы остановили программу. Что случится? Упадет с лестницы? Врежется в стену? В кошку? В ногу? Для того, чтобы включить остановку на точках останова, нужно в свойствах проекта поставить опцию Enable Break/Pause в True.
Нужно отметить, что когда вы начинаете отладочную сессию, открывается ряд окон. В обязательном порядке открывается окно монитора последовательного порта и ряд других, состав которых зависит от настройки текущей сессии. Заканчивается сессия закрытием окна монитора. Пока окно открыто, Visual Micro будет считать, что вы отлаживаетесь.
Теперь рассмотрим арсенал средств отладки, который использовал я.
Так называемые точки трассировки, т.е. точки программы, для которых вы хотели бы знать какое-то состояние программы, но прерывать ее выполнение не хотели бы. С точки зрения VS точка трассировки — это обычный breakpoint, но для которого стоит галка «Continue execution» в окошке «When breakpoint is hit» (на всякий случай, туда можно добраться кликнув правой кнопкой по крыжику breakpoint'а:). Трассировка в VisualMicro осуществляется написанием соответствующего сообщения в том же окошке. При этом для вывода переменных из программы нужно воспользоваться специальными макросами вида {XXX}, где XXX — имя переменной.
Вообще, как видно из скриншота, в скобки можно вставлять любое выражение, которое возвращает результат.
После того, как вы расставили точки трассировки и запустили прошивку в режиме отладки, можете наблюдать как при прохождении мест установок в окошко MicroDebugTrace
сыпятся сообщения установленного вами формата, содержащие затребованные вами переменные и выражения. Кроме того, затребованные переменные выводятся так же в специальное окно Expressions.
Точки останова очень похожи на точки трассировки. Конфигурируются абсолютно так же, разница лишь в том, что не нужно ставить галку «Continue execution», при этом по достижении точки останова выполнение скетча приостанавливается. Тут надо отметить одну особенность Visual Micro. В отличие от взрослых отладчиков линия, на которой стоит точка останова, выполнится, прежде чем отладчик остановится. Это связано с особенностями инструментирования кода. После того, как отладчик остановил выполнение скетча, есть возможность посмотреть состояние программы к моменту остановки (но только в части, указанной вами: будут отображены только те переменные, которые вы затребовали, т.е. указали в списке переменных для текущей точки останова точно таким же способом, как это указывалось для точки трассировки). Можно поменять значения переменных как во взрослом отладчике, но опять, только если вы декларировали такую необходимость. Если для того, чтобы отладчик забрал из МК переменные, их нужно было указать в виде {XXX} в строке трассировки, то для возможности изменения нужно указать их в виде {XXX=?}. Переменные, которые можно менять, отмечены желтым цветом в окне Expressions. Кроме того, поддерживаются обычные возможности точек останова — счетчик попаданий и условные останов.
Из коробки Visual Micro поддерживает три вида отчетов: аналоговые входы, цифровые входы и количество свободной оперативной памяти.
Первые два активно попользовать не удалось, поскольку для отладки быстротекущих процессов они не годятся (у первого низкая разрешающая способность по времени, второй вообще индицирует текущий логический уровень на пине), так что я использую осциллограф/логический анализатор. Отладку же медленно текущих процессов почти всегда можно осуществлять в терминах ассоциированных с выводами переменных.
А вот отчет о количестве свободной памяти я нашел крайне полезным, поскольку уже несколько раз вляпывался в ситуацию, когда память кончалась. Найти такого рода проблему — задача не из самых легких, поскольку спектр симптомов очень широк — от спонтанных перезагрузок МК до некорректного поведения «которого никогда не может быть».
У Visual Micro куча возможностей, которые перечислять нет ни смысла, ни возможности. Отмечу лишь те, которые для себя посчитал потенциально полезными:
Относительно недавно я наткнулся на софтину, которая позволяет отлаживать код Arduino прямо в кристалле способом, который очень похож на обычную отладку кода, к которому можно подключить более-менее развитый отладчик. Кому интересно, милости прошу под кат.
Введение
Во избежание кривотолков, скажу, что топик ни в коем разе не является рекламным, а имеет целью разделить с сообществом мой опыт отладки кода для Arduino и качественный скачок, который этот опыт претерпел в связи с нахождением мной продукта VisualMicro (www.visualmicro.com). Так же хочется сразу предупредить комментарии типа «ага, ставить монстра VisualStudio для написания маленьких прошивок для маленьких контроллеров...». Сам я являюсь пользователем VisualStudio со стажем лет эдак в 15, она у меня уже в мозжечке сидит (даже если где-то объективно неудобна, то я этого уже все равно не замечаю в силу привычки). Так что унификация дебаггинг-процесса для Arduino и кода, который я обычно пишу в VS, вызывает у меня дикий восторг: надо же, «взрослый дебаггинг» для «маленькой железяки». По поводу «монструозности» имею сказать следующее. Да, размер VS намного больше Arduino IDE, но место на винте сейчас дешевле овса. Имея двухтерабайтный винчестер, жадничать гигабайт — моветон. Да он грузится дольше, но если посчитать разницу увеличенного времени загрузки и сэкономленного на дебаггинге времени, получается приличный профит. Студию я загружаю один раз в день (так что это +20 секунд загрузки в день на моем не самом навороченном домашнем ноуте на Core i3 первого поколения), а вот на дебаггинг трачу часы. Кроме того, через очень короткое время Arduino IDE для неновичка в программировании становится тесноватой и начинаешь задумываться как бы сломать рамки, которые она накладывает. Ну и последний аргумент против такого сетапа для отладки Arduino — VS стоит конских денег. Да, это правда, но есть несколько «но»:
- Иногда он бесплатный (пруфлинк)
- Иногда он уже есть
- А теперь самый убойный: Atmel распространяет VisualStudio 2010 как rebranded-продукт под названием AtmelStudio. Бесплатно. Да еще и включает в его состав VisualAssist, плагин для рефакторинга, тоже бесплатно
Итак, VisualMicro — это плагин для VisualStudio (и, как следствие, для AtmelStudio), в котором есть:
- Организация проекта способом, привычным для пользователей VisualStudio
- Поддержка нативных плюшек VS типа IntelliSense
- Компиляция и прошивка МК прямо из VS
- Отладка кода в кристалле
Существует две версии плагина — бесплатная, которая реализует первые три пункта, и платная, поддерживающая отладку. Стоит относительно недешево — около 29$, но разработчики обещают бесплатную лицензию бетатестерам, да и просто людям, как-либо вложившимся в проект.
Возможностей у продукта много и они достаточно хорошо описаны в Wiki, а статья не претендует на звание руководства по применению, так что опишу только те, которые я успел попользовать, а именно:
- Компиляция с загрузкой в кристалл
- Tracepoints и Breakpoints
- Мониторинг состояния выводов и RAM
Собственно, процесс
Первое, что нужно сказать, что волшебства никакого не происходит. Возможность отладки появляется за счет инструментирования кода (прямых доказательств в виде упоминаний в том же Wiki не нашел, код не дизассемблировал, но увеличение размера «дебагабельного» кода по сравнению с оригинальным говорит само за себя). Т.е. плагин при компиляции с поддержкой отладки встраивает в код куски, которые позволяют отлаживаться. Естественно, размер кода при этом растет. С другой стороны, когда вы за ненадобностью выкинете из кода все отладочные println, с удовольствием обнаружите, что в итоге даже с инструментированием код стал компактнее. Второе замечание касается отличия отладки с помощью этого плагина от процесса «обычной отладки». Все привыкли, что код компилируется один раз и потом уже в runtime, при подключенном отладчике, можно ставить точки останова и смотреть какую угодно память. Здесь это не так. Точку останова нужно ставить до начала процесса отладки, потому что упомянутому мной инструментированию подвергаются только те участки кода, для которых заранее известно желание пользователя в них останавливаться. С просмотром значений переменных ситуация схожая: необходимо заранее дать плагину знать какие переменные и в каких местах вы собираетесь смотреть/менять. Благо делается это не слишком сложно.
Предположим, что вы знаете как зашивать скетч через Arduino IDE (ну мало ли...), т.е. с прошивкой у вас проблем не возникает. Предположим, вы уже установили плагин, т.е. прошли через процедуру настройки. Допустим, у вас уже есть скетч, который вы подготовили в Arduino IDE. В этом случае создание проекта в VS сводится к открытию скетча через File->Open->Sketch project. Для созданного проекта нужно поставить опцию MicroDebug в Full. После этого у вас есть две возможности — классические для VS «Start without debugging» и «Start debugging». Первая компилирует код и заливает его в Arduino. Вторая — компилирует код с инструментированием и начинает сессию отладки. По умолчанию, кстати, плагин не разрешает программе останавливаться, даже если вы настроили точку останова. В этом есть своя логика. Поскольку Arduino используется, например, в робототехнических проектах, останов может привести к печальным последствиям. Представьте, вы включили двигатели робота, он начал двигаться, а вы остановили программу. Что случится? Упадет с лестницы? Врежется в стену? В кошку? В ногу? Для того, чтобы включить остановку на точках останова, нужно в свойствах проекта поставить опцию Enable Break/Pause в True.
Нужно отметить, что когда вы начинаете отладочную сессию, открывается ряд окон. В обязательном порядке открывается окно монитора последовательного порта и ряд других, состав которых зависит от настройки текущей сессии. Заканчивается сессия закрытием окна монитора. Пока окно открыто, Visual Micro будет считать, что вы отлаживаетесь.
Теперь рассмотрим арсенал средств отладки, который использовал я.
Tracepoints
Так называемые точки трассировки, т.е. точки программы, для которых вы хотели бы знать какое-то состояние программы, но прерывать ее выполнение не хотели бы. С точки зрения VS точка трассировки — это обычный breakpoint, но для которого стоит галка «Continue execution» в окошке «When breakpoint is hit» (на всякий случай, туда можно добраться кликнув правой кнопкой по крыжику breakpoint'а:). Трассировка в VisualMicro осуществляется написанием соответствующего сообщения в том же окошке. При этом для вывода переменных из программы нужно воспользоваться специальными макросами вида {XXX}, где XXX — имя переменной.
Вообще, как видно из скриншота, в скобки можно вставлять любое выражение, которое возвращает результат.
После того, как вы расставили точки трассировки и запустили прошивку в режиме отладки, можете наблюдать как при прохождении мест установок в окошко MicroDebugTrace
сыпятся сообщения установленного вами формата, содержащие затребованные вами переменные и выражения. Кроме того, затребованные переменные выводятся так же в специальное окно Expressions.
Breakpoints
Точки останова очень похожи на точки трассировки. Конфигурируются абсолютно так же, разница лишь в том, что не нужно ставить галку «Continue execution», при этом по достижении точки останова выполнение скетча приостанавливается. Тут надо отметить одну особенность Visual Micro. В отличие от взрослых отладчиков линия, на которой стоит точка останова, выполнится, прежде чем отладчик остановится. Это связано с особенностями инструментирования кода. После того, как отладчик остановил выполнение скетча, есть возможность посмотреть состояние программы к моменту остановки (но только в части, указанной вами: будут отображены только те переменные, которые вы затребовали, т.е. указали в списке переменных для текущей точки останова точно таким же способом, как это указывалось для точки трассировки). Можно поменять значения переменных как во взрослом отладчике, но опять, только если вы декларировали такую необходимость. Если для того, чтобы отладчик забрал из МК переменные, их нужно было указать в виде {XXX} в строке трассировки, то для возможности изменения нужно указать их в виде {XXX=?}. Переменные, которые можно менять, отмечены желтым цветом в окне Expressions. Кроме того, поддерживаются обычные возможности точек останова — счетчик попаданий и условные останов.
Отчеты
Из коробки Visual Micro поддерживает три вида отчетов: аналоговые входы, цифровые входы и количество свободной оперативной памяти.
Первые два активно попользовать не удалось, поскольку для отладки быстротекущих процессов они не годятся (у первого низкая разрешающая способность по времени, второй вообще индицирует текущий логический уровень на пине), так что я использую осциллограф/логический анализатор. Отладку же медленно текущих процессов почти всегда можно осуществлять в терминах ассоциированных с выводами переменных.
А вот отчет о количестве свободной памяти я нашел крайне полезным, поскольку уже несколько раз вляпывался в ситуацию, когда память кончалась. Найти такого рода проблему — задача не из самых легких, поскольку спектр симптомов очень широк — от спонтанных перезагрузок МК до некорректного поведения «которого никогда не может быть».
Другие возможности
У Visual Micro куча возможностей, которые перечислять нет ни смысла, ни возможности. Отмечу лишь те, которые для себя посчитал потенциально полезными:
- Наличие фреймворка для расширения. Можно прикручивать какие-то визуализации, специфичные для проекта. Пример
- Отладка не только через последовательный порт, но и по Bluetooth, XBee, IP, software serial
- Поддержка Teensy, Attiny, avrIO, Intel Galileo, Texas Instruments StellarPad, LaunchPad, ChipKIT/Pic32, STM32