Ассемблер (ASM) для AVR в вопросах и ответах
Demiurg, функция main имеет некую специфичность, из нее некуда выходить в контексте AVR. Сколько раз уже Вам сказали что компилятор компиллит заглушку. Эта заглушка к прерываниям (про которые Вы зачем то говорите) отношения никакого не имеет и никакими заглушками ошибки и тем более сбои МК не заткнуть.
- Реклама
- Сообщения: 1492
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Это структура скомпилированной программы. Я сейчас занят. Так что пока изучите структуру. В принципе по картинке все понятно. Позже отпишусь.
Последний раз редактировалось Demiurg Чт авг 10, 2017 09:33:10, всего редактировалось 1 раз.
если мы говорим о структуре скомпилированной avr-gcc сишной программы, то картинка не [совсем] верна - я приводил выдержки листинга, доказывающие это: после main есть единственная заглушка, а вместо заглушек в неиспользуемых векторах на самом деле генерируется переход на нулевой вектор, т.е. в конечном итоге на reset.Demiurg писал(а):Это структура скомпилированной программы.
разумеется, в самописных программах на ассемблере можно реализовать и такую, и любую иную структуру. просто компилятор Си avr-gcc делает иначе.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 1492
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Я изменил картинку. Обратите внимание. Прямоугольники Прерывание Заглушка Подпрограмма ничем не отличаются. Это все подпрограммы. И заглушка может быть в любом месте. Главное дотянуться командами rjmp и jmp.
Вы показываете картинку того, как в вашем представлении должна выглядеть программа?
Я вам говорю: из-под avr-gcc она выглядит не так!
В вашем представлении нет ничего криминального или плохого, но avr-gcc делает не по-вашему!
Я вам говорю: из-под avr-gcc она выглядит не так!
В вашем представлении нет ничего криминального или плохого, но avr-gcc делает не по-вашему!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
- Сообщения: 1492
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Компилятор может вызывать main, вы знали об этом? То есть, в зависимости от программы, настроек компилятора, после сброса и блока инициализации может быть как переход на main так и вызов.
Так же можно настраивать переходы из незапланированных прерываний.
Так же можно настраивать переходы из незапланированных прерываний.
Demiurg, лично я не понимаю о чем Вы, возможно и другие тоже не понимают. До вмешательства модератора, предлагаю создать тему по компилятору GCC (или хотя бы уйти в Сишную ветку) и там продолжить обсуждение.
----------
А вот по теме, очень хотелось бы понять что Вы имели ввиду. Резюмирую:
FeCat выложил код с точкой зависания.
ARV, указал что эта точка может быть только выходом из функции main.
Оставив в стороне Ваши обвинения в некомпетенции, Вы заявили Main вызван, а стек сорван.. Объясните почему данный код срывает стек. Если можете конечно.
----------
А вот по теме, очень хотелось бы понять что Вы имели ввиду. Резюмирую:
FeCat выложил код с точкой зависания.
ARV, указал что эта точка может быть только выходом из функции main.
Оставив в стороне Ваши обвинения в некомпетенции, Вы заявили Main вызван, а стек сорван.. Объясните почему данный код срывает стек. Если можете конечно.
[uquote="Demiurg",url="/forum/viewtopic.php?p=3159547#p3159547"]Компилятор может вызывать main, вы знали об этом? То есть, в зависимости от программы, настроек компилятора, после сброса и блока инициализации может быть как переход на main так и вызов.
Так же можно настраивать переходы из незапланированных прерываний.[/uquote]
я вам говорю - небо синее, а вы мне - нет, трава зелёная
можно делать что угодно, но avr-gcc делает нечто конкретное, и я на 100% уверен, что знаю, что этот компилятор делает. остальное - домыслы.
Так же можно настраивать переходы из незапланированных прерываний.[/uquote]
я вам говорю - небо синее, а вы мне - нет, трава зелёная
можно делать что угодно, но avr-gcc делает нечто конкретное, и я на 100% уверен, что знаю, что этот компилятор делает. остальное - домыслы.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 1492
- Зарегистрирован: Ср июн 25, 2008 15:19:44
1 - Я давно не писал проекты в gcc. Поэтому, остались остатки впечатлений и разбора дизассемблера. В некоторых моментах был не прав. Признаю. Но! Я зацепился за "выход из main". И "расположенный за main кусок кода". Тот, кто писал и пишет проекты на асме, никогда так не скажет.
Берем первый момент. Выход из main. Компиляторы, в зависимости от условий, могут компилировать два метода. Переход на main, и вызов main. В последнем случае появился в обсуждении срыв стека.
Второй момент. cli и rjmp PC + 0 или PC - 0 (однокуйственно). Это совершенно отдельный кусок кода, который можно рассматривать как отдельную подпрограмму. И не важно, где этот кусок будет находиться. Потому как:
Смотрим на этот кусок кода:
Спор возник из-за того, кто как рассматривает программу. Со стороны си, и оперирование одними понятиями. И со стороны асма, соответственно, оперирование понятиями со стороны архитектуры МК и асма.
Теперь возьмем момент, откуда взялись прерывания и срыв стека. Из-за ошибки программиста, сбоя может возникнуть переход на векторы незапланированных прерываний. Здесь уже варианты, как лучше сделать. И компиляторы могут сделать по разному. Один из методов - переход на глобальное отключение прерываний и глухое зацикливание. Потому как именно такой способ защищает и от срыва стека.
Берем первый момент. Выход из main. Компиляторы, в зависимости от условий, могут компилировать два метода. Переход на main, и вызов main. В последнем случае появился в обсуждении срыв стека.
Второй момент. cli и rjmp PC + 0 или PC - 0 (однокуйственно). Это совершенно отдельный кусок кода, который можно рассматривать как отдельную подпрограмму. И не важно, где этот кусок будет находиться. Потому как:
Код: Выделить всё
main:
bla-bla
rjmp Main
cli
rjmp PC + 0
Код: Выделить всё
Label:
rjmp PC + 0
Теперь возьмем момент, откуда взялись прерывания и срыв стека. Из-за ошибки программиста, сбоя может возникнуть переход на векторы незапланированных прерываний. Здесь уже варианты, как лучше сделать. И компиляторы могут сделать по разному. Один из методов - переход на глобальное отключение прерываний и глухое зацикливание. Потому как именно такой способ защищает и от срыва стека.
не могу поручиться за компиляторы, но логика подсказывает, что если вызов функции компилятор подменяет на переход, то он уж как-то должен и выход из функции оформить так, чтобы никакого срыва стека не было. но в целом это рассуждения из разряда "есть ли жизнь на Марсе".Demiurg писал(а):Компиляторы, в зависимости от условий, могут компилировать два метода. Переход на main, и вызов main. В последнем случае появился в обсуждении срыв стека
будем считать, что разобрались
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 1492
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Внес правку. Думаю, что написал все, хотел сказать.ARV писал(а):...
какие, с вашей точки зрения, этот метод дает преимущества перед тем, который применяет avr-gcc, а так же перед методом "а и хрен с ним!", т.е. когда программист вообще никак не отрабатывает "случайные" прерывания?Demiurg писал(а):Один из методов - переход на глобальное отключение прерываний и глухое зацикливание. Потому как именно такой способ защищает и от срыва стека.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 1492
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Самый простой способ ставить reti на все незадействованные прерывания. Пусть даже и случилось прерывание, но и ничего не произойдет.ARV писал(а):...
Имхо, для поиска ошибок, т.е. для облегчения отладки, все-таки лучше реагировать на прерывание каким-то "нехорошим" образом, чтобы как минимум можно было понять, что происходит нечто непредусмотренное. в случае с reti понять, что что-то не так, будет гораздо сложнее...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Не понимаю как такое прерывание может произойти и как могут помочь RETI. Незапланированных прерываний быть не должно. Но в крайнем случае лучше сделать прерывание по умолчанию и например завешивать там программу или как то семафорить об этом. И то это может быть полезным только на этапе отладки.Demiurg писал(а):Пусть даже и случилось прерывание, но и ничего не произойдет.
А установка RETI - это всего лишь некая традиция. С таким же успехом можно заполнить другими командами или даже директивами. Очень многие считают, что данное заполнение таблицы векторов неудачный метод. Лучше применять директиву .ORG с метками, которым присвоено значения разработчиком.
- Сообщения: 1492
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Самый правильный способ заполнения таблицы векторов следующий:
Это таблица для ATMEGA8535. Этот же способ работает и для МК с объемом памяти выше 8 кБ. У этих МК векторы двухсловные. Если мы тупо забьем командами reti, то вляпаемся в смещение адресов. Применяя ORG, мы впаковываемся в таблицу.
Создается такая таблица просто. Берем заголовочный файл на конкретный МК. Копируем таблицу векторов. И заменяем EQU на ORG. Шаблон я вам дал.
Применяя такую таблицу, мы страхуемся от незапланированных прерываний. Но не избавляемся от них. А это уже другая история.
Код: Выделить всё
.cseg
.org 0x0000
rjmp Reset
;====== INTERRUPT VECTORS ============
.org INT0addr ; External Interrupt 0
reti
.org INT1addr ; External Interrupt 1
reti
.org OC2addr ; Timer/Counter2 Compare Match
reti // rjmp Proc_Int_BAM // reti
.org OVF2addr ; Timer/Counter2 Overflow
reti
.org ICP1addr ; Timer/Counter1 Capture Event
reti
.org OC1Aaddr ; Timer/Counter1 Compare Match A
reti
.org OC1Baddr ; Timer/Counter1 Compare Match B
reti
.org OVF1addr ; Timer/Counter1 Overflow
reti
.org OVF0addr ; Timer/Counter0 Overflow
reti
.org SPIaddr ; SPI Serial Transfer Complete
reti ; rjmp SPI_Transfer_Int
.org URXCaddr ; USART, RX Complete
reti
.org UDREaddr ; USART Data Register Empty
reti
.org UTXCaddr ; USART, TX Complete
reti
.org ADCCaddr ; ADC Conversion Complete
reti // rjmp ADC_Complete
.org ERDYaddr ; EEPROM Ready
reti
.org ACIaddr ; Analog Comparator
reti
.org TWIaddr ; Two-wire Serial Interface
reti
.org INT2addr ; External Interrupt Request 2
reti
.org OC0addr ; TimerCounter0 Compare Match
rjmp Sys_Timer_Comp
.org SPMRaddr ; Store Program Memory Read
reti
;-------------------------------------------------------------------------
.org INT_VECTORS_SIZE ; size in words
;===================
Создается такая таблица просто. Берем заголовочный файл на конкретный МК. Копируем таблицу векторов. И заменяем EQU на ORG. Шаблон я вам дал.
Применяя такую таблицу, мы страхуемся от незапланированных прерываний. Но не избавляемся от них. А это уже другая история.
в чем страховка-то? я не понимаю желания уберечь неверно работающую программу от еще более неверной работы... reti никак не поможет при отладке, даже затруднит её, имхо. а в отлаженной программе никаких внеплановых прерываний быть не должно.Demiurg писал(а):мы страхуемся от незапланированных прерываний
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 1492
- Зарегистрирован: Ср июн 25, 2008 15:19:44
reti как заглушка незапланированных прерываний ничего не делает. Просто происходит переход по вектору и выход из прерывания без каких-либо действий.ARV писал(а):reti никак не поможет при отладке, даже затруднит её, имхо. а в отлаженной программе никаких внеплановых прерываний быть не должно.
Затычка nop-ами, к примеру, как некоторые делают, или, если вообще вектор не указан как-либо, 0xFF приведет к последовательному перебору до ближайшего вектора или куска программы. А это гораздо опаснее. Смоделируйте в симуляторе для интереса.
Код: Выделить всё
.cseg
.org 0x0000
rjmp Reset
;====== INTERRUPT VECTORS ============
.org INT0addr ; External Interrupt 0
// reti // В этом месте будет 0xFFFF
.org INT1addr ; External Interrupt 1
// reti // В этом месте будет 0xFFFF
Можно и нужно симулировать различные ситуации при разработке устройств. Разработчик должен учитывать любые ситуации. И методы борьбы с ними. Не стесняйтесь пользоваться симулятором AVR-Studio. Это единственный инструмент, который показывает реальную работу МК. Протеус и иже с ними даже рядом не стоял в сравнении со студией. Так как студия - продукт производителя микроконтроллеров AVR/
Никакой симулятор никогда не покажет реальную работу. И может хватит уже общаться в тоне просветленного учителя? Можете не верить, но про разные методы отладки программ знаете не только Вы.Demiurg писал(а): Не стесняйтесь пользоваться симулятором AVR-Studio. Это единственный инструмент, который показывает реальную работу МК.
Лучше поясните по некие незапланированные прерывания, это как?



