Я думаю, это плохая вещь, чтобы попытаться отладить проект на основе микроконтроллера с помощью printf()
.
Я могу понять, что у вас нет предопределенного места для вывода, и что оно может потреблять ценные выводы. В то же время я видел, как люди используют вывод UART TX для вывода на терминал IDE с пользовательским DEBUG_PRINT()
макросом.
printf
, конечно, весь код, необходимый для реализации,printf
связывается с исполняемым файлом. Но это потому, что код использовал его, а не из-за заголовка.Ответы:
Я могу придумать несколько недостатков использования printf (). Имейте в виду, что «встроенная система» может варьироваться от чего-то с несколькими сотнями байтов программной памяти до полномасштабной монтируемой в стойку QNX RTOS-управляемой системы с гигабайтами оперативной памяти и терабайтами энергонезависимой памяти.
Требуется куда-то отправить данные. Возможно, у вас уже есть отладочный или программный порт в системе, а может и нет. Если вы этого не сделаете (или тот, который у вас не работает), это не очень удобно.
Это не легкая функция во всех контекстах. Это может иметь большое значение, если у вас есть микроконтроллер с небольшим количеством памяти K, потому что соединение в printf может съесть 4K само по себе. Если у вас микроконтроллер 32K или 256K, это, вероятно, не проблема, не говоря уже о большой встроенной системе.
Он практически бесполезен для поиска определенных видов проблем, связанных с выделением памяти или прерываниями, и может изменить поведение программы, если включены операторы или нет.
Это довольно бесполезно для работы с чувствительными ко времени вещами. Вам было бы лучше с логическим анализатором и осциллографом или анализатором протокола, или даже симулятором.
Если у вас большая программа, и вам приходится много раз перекомпилировать, когда вы меняете операторы printf и меняете их, вы можете потратить много времени.
Для чего это хорошо - это быстрый способ вывода данных в предварительно отформатированном виде, который каждый программист C знает, как использовать нулевую кривую обучения. Если вам нужно выложить матрицу для фильтра Kalman, который вы отлаживаете, было бы неплохо выложить его в формате, который MATLAB мог бы прочитать. Конечно, лучше, чем смотреть на места ОЗУ по одному в отладчике или эмуляторе ,
Я не думаю, что это бесполезная стрелка в колчане, но ее следует использовать экономно, наряду с gdb или другими отладчиками, эмуляторами, логическими анализаторами, осциллографами, инструментами статического анализа кода, инструментами покрытия кода и так далее.
источник
printf()
реализаций не являются поточно-ориентированными (то есть не входящими), что не является убийцей сделок, а является чем-то, что следует иметь в виду при использовании в многопоточной среде.В дополнение к некоторым другим хорошим ответам, отправка данных в порт с последовательной скоростью передачи данных может быть очень медленной по отношению к времени цикла и оказывать влияние на работу остальных программ (как и любая отладка). процесс).
Как говорили другие люди, в использовании этой техники нет ничего «плохого», но она, как и многие другие методы отладки, имеет свои ограничения. Если вы знаете и можете справиться с этими ограничениями, это может оказаться чрезвычайно удобным, чтобы помочь вам получить правильный код.
Встраиваемые системы имеют определенную непрозрачность, что, как правило, делает отладку небольшой проблемой.
источник
Есть две основные проблемы, с которыми вы столкнетесь при попытке использовать
printf
микроконтроллер.Во-первых, может быть затруднительно передать вывод на правильный порт. Не всегда. Но некоторые платформы сложнее других. Некоторые из файлов конфигурации могут быть плохо документированы, и может потребоваться много экспериментов.
Второе - память. Полноценная
printf
библиотека может быть БОЛЬШОЙ. Иногда вам не нужны все спецификаторы формата, и могут быть доступны специализированные версии. Например,stdio.h
предоставляемый AVR содержит три разныхprintf
размера и функциональности.У меня был случай, когда библиотека не была доступна, и у меня было минимальное количество памяти. Поэтому у меня не было выбора, кроме как использовать собственный макрос. Но использование
printf
или нет на самом деле является одним из того, что будет соответствовать вашим требованиям.источник
Чтобы добавить к тому, что Spehro Pefhany говорил о «чувствительных ко времени вещах»: давайте рассмотрим пример. Допустим, у вас есть гироскоп, из которого ваша встроенная система выполняет 1000 измерений в секунду. Вы хотите отладить эти измерения, поэтому вам нужно распечатать их. Проблема: их распечатка приводит к тому, что система слишком занята, чтобы считывать 1000 измерений в секунду, что приводит к переполнению буфера гироскопа, что приводит к считыванию (и печати) поврежденных данных. Итак, печатая данные, вы повредили данные, заставив вас думать, что при чтении данных возникает ошибка, а может, и нет. Так называемый гейзенбаг.
источник
Основная причина отказа отладки с помощью printf () заключается в том, что она обычно неэффективна, неадекватна и не нужна.
Неэффективно: printf () и kin используют много флэш-памяти и оперативной памяти относительно того, что доступно на небольшом микроконтроллере, но большая неэффективность заключается в реальной отладке. Изменение того, что регистрируется, требует перекомпиляции и перепрограммирования цели, что замедляет процесс. Он также использует UART, который вы могли бы использовать для выполнения полезной работы.
Недостаточно: есть только так много деталей, которые вы можете выводить через последовательный канал. Если программа зависает, вы не знаете точно, где, только последний завершенный вывод.
Нет необходимости: многие микроконтроллеры можно удаленно отлаживать. JTAG или проприетарные протоколы могут использоваться для приостановки процессора, просмотра регистров и оперативной памяти и даже изменения состояния работающего процессора без перекомпиляции. Вот почему отладчики, как правило, являются лучшим способом отладки, чем операторы печати, даже на ПК с огромным пространством и мощностью.
К сожалению, самая распространенная микроконтроллерная платформа для новичков, Arduino, не имеет отладчика. AVR поддерживает удаленную отладку, но протокол Atmel debugWIRE является проприетарным и недокументированным. Вы можете использовать официальную панель разработки для отладки с помощью GDB, но если у вас есть такая возможность, вы, вероятно, больше не будете беспокоиться об Arduino.
источник
printf () не работает сам по себе. Он вызывает много других функций, и если у вас мало стекового пространства, вы можете вообще не использовать его для отладки проблем, близких к пределу вашего стека. В зависимости от компилятора и микроконтроллера строка формата также может быть помещена в память, а не по ссылке из флэш-памяти. Это может значительно сложиться, если вы добавите свой код в операторы printf. Это большая проблема в среде Arduino - новички, использующие десятки или сотни операторов printf, внезапно сталкиваются с кажущимися случайными проблемами, потому что они перезаписывают свою кучу своим стеком.
источник
Даже если кто-то хочет выплюнуть данные в какую-либо форму консоли ведения журнала,
printf
функция, как правило, не очень хороший способ сделать это, так как она должна изучить переданную строку формата и проанализировать ее во время выполнения; даже если код никогда не использует какой-либо спецификатор формата, кроме%04X
, контроллеру, как правило, потребуется включить весь код, который потребуется для анализа строк произвольного формата. В зависимости от того, какой именно контроллер вы используете, может быть гораздо эффективнее использовать код, например:На некоторых PIC-микроконтроллерах,
log_hexi32(l)
вероятно, потребуется 9 инструкций и может потребоваться 17 (еслиl
находится во втором банке), аlog_hexi32p(&l)
может потребоваться 2. Самаlog_hexi32p
функция может быть написана длиной около 14 инструкций, поэтому она будет окупаться, если вызываться дважды ,источник
Одно замечание, о котором не упоминалось ни в одном другом ответе: в базовом микро (IE есть только цикл main () и, возможно, в любой момент работает несколько ISR, а не многопоточная ОС), если происходит сбой / остановка / получение Застряв в цикле, ваша функция печати просто не произойдет .
Кроме того, люди говорят, что «не используйте printf» или «stdio.h занимает много места», но не предоставили много альтернатив - встраиваемый. Kyle упоминает упрощенные альтернативы, и это именно то, что вы, вероятно, должны быть делать, как само собой разумеющееся на базовой встроенной системе. Базовая процедура вытеснения нескольких символов из UART может состоять из нескольких байтов кода.
источник