П.С. Я без стека отлично обхожусь... Тем более в аврах. Тем более что это просто запись в ОЗУ. Почему бы не использовать другие ячечки памяти? В этом случае проблем с соблюдением уровня стека не возникнет.
Ну, это уже на Нобелевку тянет - во всей программе - ни одного прерывания и ни одного вызова подпрограммы ( они, как известно, используют стек ) ! Проблемы со стеком не возникает, если писа'ть программу внимательно и с ясным пониманием того, что делаешь.
ахтунг! сегодня внезапно напоролся (расслабился я простостой и дружелюбностью протеуса) вообщем если на схему положить потенциометр (RV-POT) и при переносе в арес присвоить ему корпус SIL-3 (что вполне логично - нынче каждый второй подстроичник в таком кузове) то вопреки всякой человеческой логике нога выхода (средняя) станет первым пином в разъеме
вообщем вот так ноги расставятся:
(это просто VR-POT разведенный на схеме по принципу VR_1-J_1; VR_2-J_2; VR_3-J_3) Вообщем будте внимательны
пысы кстати, почему переодически отключается автонумировка элементов? (к каждому элементу вместо номера приписывается вопросительный знак) - как включить нумиратор?
nsl2004 Ну так пройдите программу в отладчике пошагово. .
Так что мы имеем. AVR Program memory Watch Windov AVR CPU Registers AVR EEROM Memory AVR I/O registers AVR Variable AVR Source Code AVR Data memory вот этот похож по размеру на ОЗУ ( 128 байт для Тини 2313 ). Что искать? Беглый просмотр показал что он на 70 % пустой. Если скажем стеки или что токуда то уезжает что надо увидеть? Я еще на Вы с контролерами,подскажите.
Roman Venom писал(а):
nsl2004 Тем более что это просто запись в ОЗУ..
Где эту запись увидеть в окошке Data Memory ?
Цитата:
Почему бы не использовать другие ячечки памяти? В этом случае проблем с соблюдением уровня стека не возникнет.
С удовольствием, но как это сделать, или хотя бы как сформулировать вопрос , что бы найти в Гугле Размещение стека в памяти AVR ? Т.е в каком направление копать. А так спасибо, что помогаете Роман. Уже не так грустно.
AVR Data memory вот этот похож по размеру на ОЗУ ( 128 байт для Тини 2313 ).
Да, это и есть ОЗУ
nsl2004 писал(а):
Что искать? Беглый просмотр показал что он на 70 % пустой. Если скажем стеки или что токуда то уезжает что надо увидеть?
Если стек проинициализирован правильно, то при первой записи в него, данные (адрес, если это прерывание/CALL или байт если по команде PUSH) запишутся в последнюю ячейку ОЗУ, следующие в предпоследнюю (или предпредпоследнюю, если адрес), и т.д.
nsl2004 писал(а):
Где эту запись увидеть в окошке Data Memory ?
Измененные с последнего просмотра данные (было например 0х00, записалось 0хF3) протеус подсвечивает желтым.
Engineer_Keen Если стек проинициализирован правильно, то при первой записи в него, данные (адрес, если это прерывание/CALL или байт если по команде PUSH) запишутся в последнюю ячейку ОЗУ, следующие в предпоследнюю (или предпредпоследнюю, если адрес), и т.д.
Подскажите пожалуйста, где про это можно прочитать? Не подскажете материальчик. Что то рою по запросу типа использование озу в AVR, память AVR и натыкаюсь на ерунду разную. Т.к моя проблема однозначно в этом. Пошаговая отладка показала что расположившиеся в конце значения ползут вверх , забивают всю дата мемори и устройство перестает функционировать. Причем с верху таблицы распологается 8 байтовая переменная и торчит там постоянно. Ее я так понимаю тоже лучше убрать.
С удовольствием, но как это сделать, или хотя бы как сформулировать вопрос , что бы найти в Гугле Размещение стека в памяти AVR ? Т.е в каком направление копать.
Для этого не надо прогугливать весь интернет, достаточно почитать даташиты. Вот что я навскидку нашел в доке на Tiny2313 :
0x0013 RESET: ldi rl6, low(RAMEND); 0x0014 out SPL,rl6 0x0015 sei
Так что для инициализации стека не надо быть семи пядей во лбу. Важно, что сделать это надо сразу же после подачи питания, до sei. Надо следить за указателями собственных данных, чтобы они не зацепили стек. Вылет может быть и не только по переполнению или порче стека: выполнение несуществующей инструкции, запись по несуществующему адресу. Со стеком как раз проблем - минимум : соблюдать аккуратность : сколько положил в стек на входе в п/п, столько и извлек на выходе из нее. Не хулиганить : типа зашел по rjmp, а вышел по ret или наоборот. Впрочем, все эти советы - для программера, пишущего на асме и ясно представляющего себе, что он делает. А когда пишешь на С или всяких извратах с рисованием квадратиков со стрелочками связей, не надо удивляться , что результат будет непредсказуемым. "Я написал вроде правильно, а что там компайлер наваял - неизвестно". А компилятор отвечает : "А мне вообще все по фигу - синтаксические ошибки есть? - нет. А дальше т...сь как хотите". Рискуя прослыть ретроградом, все же считаю : учиться программить все же надо на асме, чтобы прочувствовать архитектуру МК, понять, как выполняется та или другая инструкция. А уж потом, когда почувствуешь себя корифаном и проги захочешь выпускать как горячие пирожки - берись за С с твердой уверенностью, что если он там ( или скорее ты с ним ) накосячили, в результирующем коде сумеешь разобраться. Каждому -свое, как говорили в Освенциме.
PS А стек традиционно размещается в конце памяти, хотя это и не догма. Бывает, что для одного и того же компа, но для разных на нем операционных систем стек размещается по разному.
Ой, кажется, не в свою тему вломился - я Протеус не использую.
А то, что Роман советует вообще не использовать стек ( в т.ч. и прерывания, и подпрограммы ) - жжжесть !
Ну, это уже на Нобелевку тянет - во всей программе - ни одного прерывания и ни одного вызова подпрограммы ( они, как известно, используют стек ) ! Проблемы со стеком не возникает, если писа'ть программу внимательно и с ясным пониманием того, что делаешь.
Вы неправильно меня поняли... Я не использую команды положить/извлечь. Прерывания, подпрограммы естессно присутствуют. Как же без них? И никаких недоразумений со стеком не было... Кстати ещё вот что. Были непонятные баги когда прерывания срабатывали во время операций положить/извлечь в ОЗУ.
Цитата:
А когда пишешь на С или всяких извратах с рисованием квадратиков со стрелочками связей, не надо удивляться , что результат будет непредсказуемым. "Я написал вроде правильно, а что там компайлер наваял - неизвестно". А компилятор отвечает : "А мне вообще все по фигу - синтаксические ошибки есть? - нет. А дальше т...сь как хотите".
Ну вот я начинал с асма, сейчас учу С/С++(пытаюсь, по крайней мере), т.к. появились задачи обработки данных, цифровой фильтрации, а на асме это невыполнимо. И сомневаюсь что компилятор такой дурной, тупее среднего программера на асм. П.С. Так что там с багой?
Jack_A Для этого не надо прогугливать весь интернет, достаточно почитать даташиты. Вот что я навскидку нашел в доке на Tiny2313 :
Спасибо я теперь знаю где почитать. Т.к. даже если бы я прочел пару раз это место, я бы все равно не заподозрил, что это инициализация стека. Просто я к асму даже не прикасался. Прога которую мучаю на баскоме. Я понял очень важную вещь. Что конкретно в моей проге надо как то принудительно зафиксировать то, что распологается в конце ОЗУ. А то оно начинает смещатся и забивает весь ОЗУ ( Дата мемори в Протеусе )
Если это мне то бага на месте. Пробую вручную распределить ОЗУ под переменные !? Может повезет
Повезёт - плохое слово. Так можно часами сидеть... Найди лучше примеры таких прог/попроси чтобы выложили. Как правильно оформлять.
Нет таких прог - это эмулятор DS2413 1-wire. Удача любит удачливых и стремящихся к удаче. Переменные стали как вкопанные и рядком. Сразу стала видна проблема. Как сюда изображение вставить? Разберусь вернусь. Короче в конец озу записывается, наверно стек, и он начинает снизу вверх заполнять Озу . Забивает напрочь переменные все и проц останавливается. Задача остановить полузуна. Т.е я так понимаю стеку надо задать размер. Сделал. И место где распологатся. Вот как сделать это, мне пока не известно. Ищу.
Интересно как без симулятора можно отловить такую ошибку. Протеус рулит. Но проблема осталась, как его остановить и что в этом стеке лежит? Промежуточные значения таймера могут?
И место где распологатся. Вот как сделать это, мне пока не известно. Ищу.
Код:
0x0013 RESET: ldi rl6, low(RAMEND); 0x0014 out SPL,rl6
Вот.
SPL помогло - сделал запись Spl = &HDF - - это нижний край ОЗУ движение остановилось Вроде работает. Но в симуляторе появилось PC=0x0000[AVR CPU] RET address = 0x0000. Не знаете что сие значит? И можно ли это игнорировать?
SPL помогло - сделал запись Spl = &HDF - - это нижний край ОЗУ движение остановилось Вроде работает.
Приведенные выше дампы памяти показывают что стек и до этого был проинициализирован правильно, так как он рос с конца ОЗУ вниз. Другой вопрос почему он рос бесконечно. Нужно смотреть в каком месте программы стек изменялся. Ведь ограничить его никак нельзя, можно только следить чтобы он не переполнился.
nsl2004 писал(а):
Но в симуляторе появилось PC=0x0000[AVR CPU] RET address = 0x0000. Не знаете что сие значит? И можно ли это игнорировать?
Это означает, что в в том месте в стеке где должен был лежать адрес возврата почему-то лежит 0, возврат по этому адресу равносилен сбросу (адрес вектора прерывания "сброс" - 0-я ячейка). Это следствие того, что стек кто-то попортил...
Нужно наверное найти кто бросает в стек, обычно это вызовы подпрограмм, (по call) сохранения данных в стек (по push). Так вот если из подпрограммы не вернуться (по ret) или не забрать данные (по pop), то они станут накапливаться до переполнения стека (ну или ОЗУ "закончится") и в протеусе вы получите ошибку PC=0x0000[AVR CPU] RET address = 0x0000. Что означает что программа получила по ret из стека (или якобы из стека) адрес "0" что является "холодным стартом" и протеус интересуется "Вы сознательно так делаете?"
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 22
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения