Метод 2. Моргалки (Работа портами Ввода-вывода)
Трассировка и аналитика это все замечательно, но когда мы начинаем отлаживать что то внешнее, то тут трассировка нам поможет мало. Т.к. глючить может не внутри, а снаружи.
Либо у нас будет не глюк, а банальное непонимание ситуации. Фразу из даташита, например, неправильно перевел или глаз замылился. Что то забыл или не туда припаял. Да мало ли как можно накосячить.
В общем, правильный алгоритм может работать из-за кривой аппаратной реализации. А чтобы понять где косяк надо проследить и знать как это работает внутри. В общем, заглянуть в код программы.
Причем нам не обязательно точно следить за тем, что там происходит покомандно — это мы или трейсом или туплением отладим. Интересней знать куда ушла прога.
Самым простым методом тут будет отладочный вывод. Все просто — мы берем и определяем один из выводов под отладку. Причем даже если у нас какая-нибудь крошечная тинька и все выводы расписаны буквально по нескольку раз, то все равно можно найти один лишний вывод — достаточно закомментить код который его использует, но в данный момент его правильность нас не интересует.
А у вывода может быть три состояния — Hi, Lo и Hi-Z. Так что рекомендую скреативить такой вот пробничек:
Тогда если у нас Hi-Z то будут тускленько гореть оба диода. Ну, а на соответствующий уровень свой диод в гордом одиночестве.
А в код пихаем дебажные секции вида:
1 2 3 | ;Set Hi SBI DEBUGDDR,DEBUG SBI DEBUGPORT,DEBUG |
1 2 3 | ;Set Lo SBI DEBUGDDR,DEBUG CBI DEBUGPORT,DEBUG |
1 2 3 | ;Set Hi-Z CBI DEBUGDDR,DEBUG CBI DEBUGPORT,DEBUG |
Можно их в макросы завернуть. Удобней будет.
По состоянию дебаг вывода мы можем увидеть в каком месте программа прошла. А комбинируя нашу троичную систему получим целых 9 возможных комбинаций на 2 вывода.
Однако если у нас надо отследить последовательность, то мы можем и не успеть разглядеть переимгивание светиков. Но никто не мешает воткнуть в код после смены состояния дебагвывода тупую задержку вида:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | PUSHF ; Макрос сохранения флагов PUSH R16 PUSH R17 PUSH R18 LDI R16,255 ; Грузим три байта LDI R17,255 ; Нашей выдержки LDI R18,255 Dloop: SUBI R16,1 ; Вычитаем 1 SBCI R17,0 ; Вычитаем только С SBCI R18,0 ; Вычитаем только С BRCC DLoop ; Если нет переноса - переход POP R18 POP R17 POP R16 POPF ; Макрос восстановления флагов |
Оформляется как прерывание для того, чтобы иметь минимальное влияние на код. Можно тоже оформить в виде макроса и втыкать его одной строчкой. Запрет прерываний опционально.
Либо вставлять затуп:
1 | RJMP PC |
Контроллер на этой команде встанет и дальше никуда не пойдет (правда если включен вачдог, то он ребутнется по вачдогу).
А можно же сразу после задержки перевести отладочный вывод в режим входа PullUp и просить кнопку пробника. Если нажата, можно идти дальше. Можно и без задержки, сделать, но надо смотреть, чтобы дребезг не помешал.
1 2 3 4 5 6 | ;STOP DB_BTN CBI DEBUGDDR,DEBUG SBI DEBUGPORT,DEBUG SBIC DEBUGPIN,DEBUG RJMP PC-1 |
Можно просто наставить таких кнопочных чекпоинтов. И пускать программу по ним своей могучей волевой рукой. А пока программа тупит на задержках или ожиданиях кнопок, можно спокойно замерить напряжения/пощупать лог уровни, состояние других выводов, да просто подумать.
Разумеется, если в схеме уже присутствуют светодиоды и кнопки, то и пробник тут не нужен — обойдемся имеющимися средствами — переназначив их на время отладки конкретного участка.
Правда в случаях отладки асинхронных устройств, работающих на четких временных выдержках данная затея может не прокатить, но для них есть другие варианты, о них позже.





> В общем, правильный алгоритм может работать из-за кривой реализации.
а может и не работать ;)
Имелось ввиду изза кривой аппаратной реализации.
Di HALT как всегда просто нереально угадал, и мне именно этой информации сейчас и не хватало. Как раз вконтакте вопрос связанный с этой темой задавал. Ди даже в том топике поучаствовал. =)) А теперь думаю у меня все вопросы отпадут.
я обычно интуитивно отлаживаю светиками.. правда хитрые схемы на >2 «уровней» не делаю :) ибо ног у меги16 хватает за глаза..
кстати, ещё как вариант: если отлаживается какая-то периодическая функция, можно каждый проход (либо в каком-либо условии) инвертировать свободную ногу и щупать её осциллографом.. за неимением оного я цепляю миниатюрный а-ля «pc speaker», которым обычно биос пикает :) занижается частота МК, и можно послушать, ровномерно ли оно пищит, либо где-то залипает..
да способов отладки масса, если задуматься..
Про осциллограф тоже будет, чуть дальше :)))) Кстати, со спикером классная идея. На слух колебания частоты можно очень хорошо спалить.
так началось же всё изучение микропремудростей как раз со всяких мигалок, пищалок и дрыгалок =) из подобных простейших элементов взаимодействия с окружающей средой и строятся отладки, т.к. уже точно известно, как оно работает.. а, например, при отлаженном и связанным с компом USARTе, можно вообще слать на терминал (или в отладочную прогу, для этого написанную) байтики проходов.. и по ним смотреть, куда и при каких условиях он туда залез.. «#define debug» и «#ifdef debug … #endif» творят чудеса, как уже где-то говорилось, только в асмовском диалекте :)
мда, сказывается опыт отладки «через жопу» пхпшных скриптов без дебаггера, что поделать.. %))
ГыГы… и я тоже когда-то давно, намного раньше, чем занялся контроллерами, убил уйму времени на отладку ПХПшных скриптов «через жопу» без дебаггера. =) Полезный, однако, опыт. С тех пор я дебаггером вообще не пользуюсь, даже когда пишу большие программы для большого компа =).
ну с одной стороны конечно можно понавставлять «отлажочных шоумесседжей», как я их обычно называю %) но с другой стороны, иногда всё-таки проще смотреть на состояние памяти, переменных, стэка и пр.. так решается больше проблем за более короткий срок.. просто лично меня от подобного на МК сдерживает во-первых отсутствие JTAG-а, а во-вторых, лень установки эмулятора %) тут мне проще извратиться.. а когда занимаешься системным программированием, то уж гораздо лучше тыкать F7 и F8 :)
До сих пор периодически , как отладочный инструмент использую щуп с высокоомным наушником и последовательно соединенным конденсатором. не раз спасал, начиная со звуковых схем. просто и доступною. у спикера оказалось низкое сопротивление.
А нет макрооператоров вида «.ifdef DEBUG код код код .enddef»
смысл в том, что если определена константа DEBUG в начале программы, то компилятор оставит строки кода внутри «.ifdef DEBUG код код код .enddef», иначе же выкинет автоматом и их не придется удалять руками. В С++ есть еще такое.
Архиполезно — пол программы переворотишь с ног на голову, пока разберешься где глюк, а потом вспоминай что ты поправил удалил или закомментил…
Есть, но я их не люблю. С этими дебажными сессиями исходный код превращается в полную помойку. Ну нах. Я обычно дебаг тычки ставлю без табуляций и выделяю яркими маркерами комментов, чтобы точно найти.
> Однако если у нас надо отследить последовательность, то мы можем и не успеть разглядеть переимгивание светиков.Но никто не мешает воткнуть в код после смены состояния дебагвывода тупую задержку
а ещё можно тактировать МК при помощи кнопки (с фильтром дребезга) =)
Я предпочитаю делать это с помощью МК. Причем система такая — этот МК дает такты автоматически, но следит за отладочной линией. И если линия уходит в 0 то тут же прекращает дрыгать ножкой, переходя в ручной режим. Своего рода аппаратные точки останова.
Круто! А статья про такой способ отладки будет? это же и впрямь очень удобно!
Ессесно.
А можно организовать DEBUG в программе таким образом, чтобы он переводил контроллер в режим тактирования от кнопки с антидребезгом? Совместить два ваших метода?
А по еще одной кнопке — возвращать тактирование в нормальный режим до следующего DEBUG
Чтобы не лепить ещё один контроллер?
Нельзя. Тактирование задается один раз и навсегда фузами. Единственно ты можешь сделать сразу тактирование от кнопки, но тогда тебе придется вслепую этой кнопкой «проматывать» программу вручную до нужного места :)
*OFFTOP*
Давно хотел спросить, а в чем ты схемы рисуешь? Уж очешь добротные получаются =)
Splan
Как я уже говорил эти способы отладки негодны, единственные два годных способа это:
1) Дебажный вывод через UART
2) JTAG/debugWire
Всё остальное колхоз и трата времени.
А если нельзя применить ни то ни другое?
Значит что-то неправильно было продумано изначально.
Какая нибудь 8ми ногая тинька и банально нет адаптера работающего с debug wire.
ну так я не предлагаю ограничиваться jtag или debugwire, можно просто через уарт слать логи.
Я вообще в любую вещь (если совсем не припрёт) делаю возможность перевода девайса в «сервисный режим» чтобы девайс слал логи в юарт. Очень помогает если на боевом девайсе что-то случилось не так
В том и плюс лога, что это почти единственный способ отладки программы, уже ушедшей к юзеру.
Даже в ПК-программировании логи и дебаггер не единственные средства отладки. Хотя и очень важные.
Кроме того, не стоит забывать что сайт ориентирован на начинающих. А они не готовы прямо вот так сразу выложить несколько тыр за dW адаптер.
А я вместо диодов использовал 7сегментик.
Еще круто было бы увидеть подробную статью по отладке через УАРТ.
Я для аппаратной отладки использую маленький девайс — 7-ми сегментный индикатор + PCF8574 (8bit I/O I2C). Подключается 4-мя проводками (2 питание + 2 шина I2C)Использую готовые куски кода для работы с PCF8574. В нужном месте отлаживаемого кода вставляю макрос, например CheckPoint_1, который зажигает «1″. Итого использую до 16 точек 0…9, A…F + еще можно кучу придумать.
У меня примерно тоже, но по уарту или по спи. Банально быстрей и проще чем гонять ииц автомат.
Мужики привет. Меня ОЧЕНЬ сильно заинтересовал по тексту макрос флагов pushf.
1.В каких случаях нужно его использовать?
2.Идет речь сугубо только лишь о регистре SREG?
3.Или что то еще?
4.Я только знаю что входя в прерывание нужно его сохранить в стеке, а выходя извлечь. Это я читал здесь на сайте.
5.Нужно ли так же поступать со SREG входя в подпрограммы?
Раньше я не сохранял sreg перед входом в прерывания постоянно глюки были, пока DIHALT не объяснил что нужно. В общем уточните мое понимание или скиньте ссылку где об этом можно на сайте почитать.
1) Обычно в прерываниях или когда мы не хотим чтобы срег изменился.
2) Нет, там попутно емнип еще и R16 сохраняется
5) Можно, но не обязательно
В меню сайта есть АВР. Учебный курс. Тыкни туда и прочитай первые несколько, одна из них Подпрограммы и прерывания зовется или как то так. Вот там этот момент расписан максимально подробно, с описанием того зачем это надо и что будет если это не сделать.
А что такое ЕМНИП?
Если мне не изменяет память.