Страница 1 из 3

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

Добавлено: Вс фев 10, 2013 21:48:13
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:

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

Добавлено: Вс фев 10, 2013 22:04:39
ILYAUL
Что-то на любой файл вываливается это и в любом разделе. На других сайтах того нет.

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

Добавлено: Вс фев 10, 2013 22:21:22
korsaj
Код не смотрел, но возможно какую-то переменную забыли инициализировать, а в нее в реальном устройстве какая-то пакость записывается при старте.

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

Добавлено: Пн фев 11, 2013 05:31:13
Kavka
Если по схеме, то кнопка точно волшебная. :))
СпойлерИзображение
При такого рода переписывании кода возможно задействуете занятые до этого регистры.
При описанных синдромах, как вариант, нет атомарности изменений регистров/памяти для основной программы и кода в прерывании.
Например, если в основной программе вы меняете содержимое двух сильно связанных байт (двухбайтовое целое, например) в памяти. Изменение значения происходит за две команды. А если после первой МК уйдёт по прерыванию, то что считается из этих ячек в коде прерывания. На время такого рода модификаций надо запрещать прерывания. Это называется "критическая секция/участок" кода.

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

Добавлено: Пн фев 11, 2013 06:07:41
pyzhman
Ох уж эти интернетные схемы. Это я по поводу волшебной кнопы.
Согласен с Kavka, скорее всего наезжаете на используемые уже регистры или память.

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

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

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

Добавлено: Пн фев 11, 2013 07:47:20
ibiza11
BOB51 писал(а):Кроме того - после закорачивания выводов питания обесточенного МК и последующего запуска (интервал не более 30 секунд) программа работает нормально, что также косвенно подтверждает правильность кода.
Как по мне, так это никак не подтверждает правильность кода, а только дает понять, что программа имеет разные входные данные после такого ресета по сравнению с первоначальным включением. Видимо в программе какая то из переменных не инициализируется явно.
Сразу говорю, программу не смотрел, но советую проверить инициализацию каждой переменной.

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

Добавлено: Пн фев 11, 2013 07:56:06
ploop
Видимо в программе какая то из переменных не инициализируется явно. Видимо предполагается, что она не может быть другой при старте.
Скорее всего.
Или ошибка при использовании стека (код пока посмотерть не могу)

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

Добавлено: Пн фев 11, 2013 08:26:24
HHIMERA
BOB51 писал(а):Кроме того - после закорачивания выводов питания обесточенного МК и последующего запуска (интервал не более 30 секунд) программа работает нормально, что также косвенно подтверждает правильность кода.
Это как раз и подтверждает неправильность кода... :))
Неинициализированные данные или ошибочное чтение/запись...

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

Добавлено: Пн фев 11, 2013 08:49:26
akl
BOB51 Посмотрел в студии. Не увидел чистку флага OCF0A в TIFR перед входом в ожидание прерываний. Есть непонятный выход из подпрограммы "init_diskan" по RETI ещё до полной подготовки к прерываниям.

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

Добавлено: Пн фев 11, 2013 10:48:28
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:

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

Добавлено: Пн фев 11, 2013 11:05:15
akl
TIFR сбрасывается автоматически при исполнении прерывания
Совершенно верно. Но флаги, в реалии, могут установиться еще до разрешения прерывания и вызвать несанкционированное прерывание после sei.
что дает при первом reti переход на начало модуля start в preparing4.txt (стандартная подстановка адреса возврата).
и принудительное sei

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

Добавлено: Пн фев 11, 2013 11:33:51
ploop
Касательно волшебной кнопы - это не линия сброса, а закоротка шин питания и общий
т. е. шаманизм не с помощью reset!
Это как раз ожидаемо - reset не очищает ОЗУ и РОН. А закоротка питания - очищает (и то не всегда). Так что ошибка чисто программная.

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

Добавлено: Пн фев 11, 2013 11:48:13
HHIMERA
BOB51 писал(а): Какая же очистка данных на выключенном и обесточенном МК?
Да и если код сбойный - то повторное включение в принципе не отличеатся от первичного - такая же скорость наростания питающего напряжения, такой же сигнал сброса и все процедуры запуска программы ...
если наложение имеет место, то не все ли равно - запуск то одинаков... должно и после закоротки проявится...
отличие - возможный разряд внутренних емкостей МК, появившийся в результате какого-то стечения обстоятельств...
Не знаю... я не собираюсь ломать глаза и мозг в вашем коде...
Это может быть переменная, массив, неполная/ошибочная инициализация периферии...
Кстати, внешний RESET как раз результата и не дает как и предварительная кнопа перед первым включением (аналогично интервалу ожидания после кнопы более 2-3 минут)...
Правильно... ваша прога изначально заточена под "по сбросу всё у мну ОК"... а это не всегда так...
По первому включению или после воздействия "волшебной кнопки" состояние памяти и регистров одно, а по пересбросу уже другое...
Смотрите даташит на предмет состояния регистров по включению и по сбросу... может на что и наткнётесь...
кабы не глюк железа...
Та не... этот камень уже жёван-пережёван...

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

Добавлено: Пн фев 11, 2013 12:00:03
BOB51
Первый сброс с аппаратной инициализацией регистров он и есть первый сброс -
что до нажатия кнопика, что после (ведь кнопа действует при выключенном и полностью снятом питании).
Т.е. стартовые условия запуска программы абсолютно одинаковые ( старт по включению питания) - а вот исполнение различное. 8)

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

Добавлено: Пн фев 11, 2013 12:04:53
ploop
Старт при включении питания не гарантирует правильных состояний РОН и памяти. Программа должна быть самодостаточна, и запускаться после reset, сама себя корректно инициализируя. Если же reset используется как кнопка, то там уже известная логика висит, и всё равно можно всё это продебажить.

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

Добавлено: Пн фев 11, 2013 12:33:19
BOB51
Речь идет о стартовом состоянии РСФ.
Начальное содержимое РОН и используемой части ОЗУ жестко контролируется на участках начальной инициализации разночтение при запуске исключено. На тестовом фрагменте - начальный участок всегда выполняется однозначно, сбойный (спорный) фрагмент идет чуток попозже.
Самое оригинальное - пошагово в симуляторе никаких проблем ни с наложением ни со стеком ни с прерываниями по таймеру.
В вышевыложенных архивах файлы проекта под studio 4.19 с настроенным режимом симуляции(контрольные точки останова, карта памяти данных) - кому интересно можно глянуть как это работает. :)
Пока будем считать эту тему как информацию об обнаруженной некорректности.
Прийдется более детальные целевые тесты сочинять - а это времени требует.
:beer:

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

Добавлено: Пн фев 11, 2013 13:13:57
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
?

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

Добавлено: Пн фев 11, 2013 13:20:17
Engineer_Keen
:idea: может хитрая задержка 8 тактов, 5 слов...

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

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