"убийственный код" или танцы с бубном возле ATtiny2313

Обсуждаем контроллеры компании Atmel.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 15751
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Доброго времени суток кошачьему сообществу!
Попалась мне нехорошая ситуация - то-ли мозги неверно работают, то-ли "вражьи происки"...
Собралась как-то схемка простенькой мигалки с неплохим алгоритмом, позволяющим
программную память экономить. Отработал я сие дело на 4-х канальном варианте с ATtiny13...
( http://radiokot.ru/forum/viewtopic.php?f=3&t=77399 )
Ну и посчитал, что при банальном увеличении количества каналов до 8 программка будет работать
и на ATtiny2313.
Сказано-сделано: переделал я ту программку под новый МК, предварительно
прогнал в студиевском симуляторе, записал в МК и... тут-то и начались чудеса... :shock:
Вот схемка:
shema.JPG
(186.92 КБ) 547 скачиваний
А программка (исходник) в приложении архивом.
nevers_8ut.rar
собственно исходники и *.hex
(20.21 КБ) 317 скачиваний
(писано на ассемблере).
Суть пакости в следующем - когда программа запускается на исполнение
вроде все нормально, но стоит только подойти участку с ветвлением на "общий фрагмент"
как внезапно "зависает" некоторое количество каналов.
Именно "некоторое" - так как у разных МК разное количество и в разных позициях.
Ни внешним сбросом, ни BOD уровнями пакость не убрать!
НО ... стоит выключить питание, нажать "волшебную кнопу" и снова включить устройство
и о чудо - программа работает в полном объёме и без малейших сбоев! :cry:
Вобщем... пришлось целевую программу рисунка в линейном варианте переделывать,
без этих "общих фрагментов".
Досада, что трассировка результатов никаких не дает - где-то пакость...
То-ли в коде, то-ли в самом МК...
Да и ежли бы код глючный был -то по логике, он бы всегда глючил,
а то ведь после "волшебной кнопы" все работает без замечаний...
А задумка неплохая - сократить код программ рисунка по каждому из каналов,
ну и прочее... (та же симуляция исполнения чужого кода)...
Пока нацарапал сие сообщение - мож у кого какие идейки будут...
Или это случайное стечение обстоятелбств или аппаратный подвох у МК?
Железо платки перепроверено неоднократно, с кварцем - та же бя...,
при тест-замене участка обращения по "зависшим" каналам на "линейный"
они превосходно работают (только угадать какой "заглючит" в данном МК
заранее невозможно - зато ежли глючат,
то стабильно - у каждого МК как собственная "подпись"... :kill: )...
Скоростные характеристики и разрешающая способность ШИМ,
также как и количество одновременно выводимых каналов (мультиплексирование)
не показатель, хотя в тест-исходниках установлено 16 уровней яркости
с самым медленным интервалом.
ММнняяяаа... :dont_know:
Реклама
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

Сообщение ILYAUL »

Что-то на любой файл вываливается это и в любом разделе. На других сайтах того нет.
Вложения
1.jpg
(26.25 КБ) 548 скачиваний
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 330
Зарегистрирован: Чт июн 23, 2011 07:55:51

Сообщение korsaj »

Код не смотрел, но возможно какую-то переменную забыли инициализировать, а в нее в реальном устройстве какая-то пакость записывается при старте.
Мудрый кот
Аватара пользователя
Сообщения: 1811
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Если по схеме, то кнопка точно волшебная. :))
СпойлерИзображение
При такого рода переписывании кода возможно задействуете занятые до этого регистры.
При описанных синдромах, как вариант, нет атомарности изменений регистров/памяти для основной программы и кода в прерывании.
Например, если в основной программе вы меняете содержимое двух сильно связанных байт (двухбайтовое целое, например) в памяти. Изменение значения происходит за две команды. А если после первой МК уйдёт по прерыванию, то что считается из этих ячек в коде прерывания. На время такого рода модификаций надо запрещать прерывания. Это называется "критическая секция/участок" кода.
Вложения
magic_btn.png
(39.47 КБ) 1350 скачиваний
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

Ох уж эти интернетные схемы. Это я по поводу волшебной кнопы.
Согласен с Kavka, скорее всего наезжаете на используемые уже регистры или память.
Docendo discimus
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 15751
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Наложения регистров нет - прерывание и модификатор используют разные рабочие регистры, кроме того, стоит семафор блокировки смены содержимого буфера уровня яркости на время его модификации и защитное хранение PSW (sreg) на время исполнения кода обработчика ШИМ.
Пошаговая трассировка сомнительного в отношении "наложения" участка проходит безо всяких "фокусов" - невозможно прицепиться ни к какому участку (контроль как за самим кодом, так и за состоянием точек сработки таймера по наложению прерывания и за состоянием выходных выводов)... :cry:
Да и алгоритм для каждого канала одинаков - если ошибка - зависли бы все или одна и та же комбинация на любом кристалле МК, возможно имел бы место вариант с изменением "зависающих" выходов при последующих включениях.
Но , как я уже выше указывал, у каждой из опробованных ИС зависает исключительно своя комбинация каналов (личная подпись для конкретного мк) независимо от количества включений схемы.
Кроме того - после закорачивания выводов питания обесточенного МК и последующего запуска (интервал не более 30 секунд) программа работает нормально, что также косвенно подтверждает правильность кода.
Есть мысль насчет какого-то процесса внутри самого МК при "холодном запуске" с взаимовлиянием группы регистров или нештатных "гонок" длительности тактов таймера и основного генератора и накоплением блокирующего заряда (бред какой-то...) 8)
Программный алгоритм действительно сложный - так о простом и не говорится это не готовая библиотека. Да и на 4-х каналке прототип работоспособен (ATtiny13), хотя это не показатель...
У 4-х канального варианта были выходные ключи на IRFL530...
Кстати... схема не "интернетная" а моя давно придуманная (а по-другому и не собереш - изготовитель это уже с рожденья в МК заложил), да и программка тоже не из сети, а "с потолка" из закромов собственного мозга. А волшебная кнопа появилась как результат макетных пыток. :))
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

BOB51 писал(а):Кроме того - после закорачивания выводов питания обесточенного МК и последующего запуска (интервал не более 30 секунд) программа работает нормально, что также косвенно подтверждает правильность кода.
Как по мне, так это никак не подтверждает правильность кода, а только дает понять, что программа имеет разные входные данные после такого ресета по сравнению с первоначальным включением. Видимо в программе какая то из переменных не инициализируется явно.
Сразу говорю, программу не смотрел, но советую проверить инициализацию каждой переменной.
Ставим плюсы: )
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Видимо в программе какая то из переменных не инициализируется явно. Видимо предполагается, что она не может быть другой при старте.
Скорее всего.
Или ошибка при использовании стека (код пока посмотерть не могу)
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Сообщение HHIMERA »

BOB51 писал(а):Кроме того - после закорачивания выводов питания обесточенного МК и последующего запуска (интервал не более 30 секунд) программа работает нормально, что также косвенно подтверждает правильность кода.
Это как раз и подтверждает неправильность кода... :))
Неинициализированные данные или ошибочное чтение/запись...
"Я не даю готовых решений, я заставляю думать!"(С)
akl
Друг Кота
Сообщения: 4468
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

BOB51 Посмотрел в студии. Не увидел чистку флага OCF0A в TIFR перед входом в ожидание прерываний. Есть непонятный выход из подпрограммы "init_diskan" по RETI ещё до полной подготовки к прерываниям.
Друг Кота
Аватара пользователя
Сообщения: 15751
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

akl писал(а):BOB51 Посмотрел в студии. Не увидел чистку флага OCF0A в TIFR перед входом в ожидание прерываний. Есть непонятный выход из подпрограммы "init_diskan" по RETI ещё до полной подготовки к прерываниям.
TIFR сбрасывается автоматически при исполнении прерывания
( Bit 0 – OCF0A: Output Compare Flag 0 A
The OCF0A bit is set when a Compare Match occurs between the Timer/Counter0 and the data
in OCR0A – Output Compare Register0 A. OCF0A is cleared by hardware when executing the
corresponding interrupt handling vector.
Alternatively, OCF0A is cleared by writing a logic one to
the flag. When the I-bit in SREG, OCIE0A (Timer/Counter0 Compare Match Interrupt Enable),
and OCF0A are set, the Timer/Counter0 Compare Match Interrupt is executed. )

В начале nit_diskan стоит

init_diskan:
ldi tmpd,low (start)
push tmpd
ldi tmpd,high (start) ; загрузка адреса стартового фрагмента запуска сканера дисплея
push tmpd

что дает при первом reti переход на начало модуля start в preparing4.txt (стандартная подстановка адреса возврата).

Касательно волшебной кнопы - это не линия сброса, а закоротка шин питания и общий
т. е. шаманизм не с помощью reset!
Старт со сбоем -> отключение питания до полного его спада -> закоротка кнопой -> интервал ожидания и новое включение...
Какая же очистка данных на выключенном и обесточенном МК?
Да и если код сбойный - то повторное включение в принципе не отличеатся от первичного - такая же скорость наростания питающего напряжения, такой же сигнал сброса и все процедуры запуска программы ...
если наложение имеет место, то не все ли равно - запуск то одинаков... должно и после закоротки проявится...
отличие - возможный разряд внутренних емкостей МК, появившийся в результате какого-то стечения обстоятельств...
Кстати, внешний RESET как раз результата и не дает как и предварительная кнопа перед первым включением (аналогично интервалу ожидания после кнопы более 2-3 минут)...

Ошибки конечно вероятны но... кабы не глюк железа... - слишком большая нагрузка на конвеер выборки команд при одновременном переходе на "общий фрагмент" для всех каналов...

Как-нибудь перенесу алгоритм на mcs51... оно потихоходнее, с упором на акумулятор да и флаг Z не фиксирован... просто "из вредности" - по свободному времени. :roll:
akl
Друг Кота
Сообщения: 4468
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

TIFR сбрасывается автоматически при исполнении прерывания
Совершенно верно. Но флаги, в реалии, могут установиться еще до разрешения прерывания и вызвать несанкционированное прерывание после sei.
что дает при первом reti переход на начало модуля start в preparing4.txt (стандартная подстановка адреса возврата).
и принудительное sei
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Касательно волшебной кнопы - это не линия сброса, а закоротка шин питания и общий
т. е. шаманизм не с помощью reset!
Это как раз ожидаемо - reset не очищает ОЗУ и РОН. А закоротка питания - очищает (и то не всегда). Так что ошибка чисто программная.
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Сообщение HHIMERA »

BOB51 писал(а): Какая же очистка данных на выключенном и обесточенном МК?
Да и если код сбойный - то повторное включение в принципе не отличеатся от первичного - такая же скорость наростания питающего напряжения, такой же сигнал сброса и все процедуры запуска программы ...
если наложение имеет место, то не все ли равно - запуск то одинаков... должно и после закоротки проявится...
отличие - возможный разряд внутренних емкостей МК, появившийся в результате какого-то стечения обстоятельств...
Не знаю... я не собираюсь ломать глаза и мозг в вашем коде...
Это может быть переменная, массив, неполная/ошибочная инициализация периферии...
Кстати, внешний RESET как раз результата и не дает как и предварительная кнопа перед первым включением (аналогично интервалу ожидания после кнопы более 2-3 минут)...
Правильно... ваша прога изначально заточена под "по сбросу всё у мну ОК"... а это не всегда так...
По первому включению или после воздействия "волшебной кнопки" состояние памяти и регистров одно, а по пересбросу уже другое...
Смотрите даташит на предмет состояния регистров по включению и по сбросу... может на что и наткнётесь...
кабы не глюк железа...
Та не... этот камень уже жёван-пережёван...
"Я не даю готовых решений, я заставляю думать!"(С)
Друг Кота
Аватара пользователя
Сообщения: 15751
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Первый сброс с аппаратной инициализацией регистров он и есть первый сброс -
что до нажатия кнопика, что после (ведь кнопа действует при выключенном и полностью снятом питании).
Т.е. стартовые условия запуска программы абсолютно одинаковые ( старт по включению питания) - а вот исполнение различное. 8)
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Старт при включении питания не гарантирует правильных состояний РОН и памяти. Программа должна быть самодостаточна, и запускаться после reset, сама себя корректно инициализируя. Если же reset используется как кнопка, то там уже известная логика висит, и всё равно можно всё это продебажить.
Друг Кота
Аватара пользователя
Сообщения: 15751
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Речь идет о стартовом состоянии РСФ.
Начальное содержимое РОН и используемой части ОЗУ жестко контролируется на участках начальной инициализации разночтение при запуске исключено. На тестовом фрагменте - начальный участок всегда выполняется однозначно, сбойный (спорный) фрагмент идет чуток попозже.
Самое оригинальное - пошагово в симуляторе никаких проблем ни с наложением ни со стеком ни с прерываниями по таймеру.
В вышевыложенных архивах файлы проекта под studio 4.19 с настроенным режимом симуляции(контрольные точки останова, карта памяти данных) - кому интересно можно глянуть как это работает. :)
Пока будем считать эту тему как информацию об обнаруженной некорректности.
Прийдется более детальные целевые тесты сочинять - а это времени требует.
:beer:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

я бы добавил в файл "hard_set8ut.txt" в самое начало cli, в конце очистил бы флаги прерываний таймера и только после этого sei
и еще, зачем так делать?

Код: Выделить всё

      clr mrak
      com mrak
чем оно отличается от обычного

Код: Выделить всё

ser mrak
?
В чем сакральный смысл загрузки в стек адреса метки и последующим переходом на нее по команде reti?

Код: Выделить всё

  ldi tmpd,low (start)
   push tmpd
   ldi tmpd,high (start) ; загрузка адреса стартового фрагмента запуска сканера дисплея
   push tmpd
....

   reti 
Почему нельзя написать

Код: Выделить всё

rjmp start
....
start:
sei
?
Ставим плюсы: )
Друг Кота
Аватара пользователя
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Сообщение Engineer_Keen »

:idea: может хитрая задержка 8 тактов, 5 слов...
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

в общем про загрузку в стек догадался - для сокращения объема программы. один и тот же код используется и в прерывании и в инициализации.
видимо автор нашел повторяющиеся куски кода и решил не оформлять их в функцию, а просто добавить в повторяющийся код метку "прерывания" (тут экономия за счет исключения команд rcall и ret, увеличивается скорость вызова, уменьшается объем памяти). Но поскольку из прерывания всегда выходит по reti - выкрутился и добавил в стек адрес точки, куда нужно вернуться после этапа инициализации. таким образом экономится память. Вопрос целесообразности применения такой оптимизации в программе для работы со светодиодами остается открытым.
Кстати говоря, код изобилует комментариями, которые все же привносят ясность. Но я считаю, так писать нельзя. Мне кажется автор где-нибудь сам и запутался, где-то что-нибудь не учел и все.
Ставим плюсы: )
Ответить

Вернуться в «AVR»