Перейти к содержанию
    

Куда в микроконтроллере возвращается функция Main?

вообще-то обычно стартовый код на ассемблере, который вызвает main, прилагается в исходнике, там и можно посмотреть для конкретного процессора, что после возрата идёт. Обычно стоит что-то вроде

stop: jump stop

 

Изменено пользователем gridinp

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Определяю выход из main() нештатным поведением приложения.

Отсюда строю логику программы так, чтобы эта нештатная ситуация была соответственно обработана.

@adnega предложил на первой странице вполне годные варианты. Я в 99% случаев использую бесконечный цикл в ResetHandler-е.

Вообще у меня или RTOS крутится, или while(1) {...} с событийно-ориентированным подходом.

Поэтому все что ниже этого while() приведет к останову программы, а следом и к сбросу процессора внешним WDT.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, Arlleex said:

Определяю выход из main() нештатным поведением приложения.\

Перед запуском RTOS (в main) сбросьте SP в изначальное положение, в вершину стека (некоторые RTOS это сами и так делают).

Так и стек прерываний сэкономите и выход из функции запуска RTOS обратно в main будет в принципе невозможен.

А любая попытка это сделать приведет к однозначному hardfault, а там вешайте свой бесконечный цикл и ждите "собаку".

Не стоит кормить паранойю ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

@Forger, я не так сильно заморочен проблемами бытия после выхода из main(), чем эффективной ловлей багов в других местах...

А сам себе в ногу я не стреляю и палки в колеса не вставляю, чтобы из main() выходить явно:prankster2:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 minutes ago, Arlleex said:

А сам себе в ногу я не стреляю и палки в колеса не вставляю, чтобы из main() выходить явно:prankster2:

Никто в этом и не обвиняет. Я озвучил вовсе не свое решение, а уже существующее.

 

зы. В свое время в PICах делал еще и так: все свободное место в прошивке спец. утилитой "забивал" командой "GOTO 0". 

Тут можно заранее "забить" весь стек аналогичной командой или чем, что вызовет скажем однозначный HF.

Шутки шутками, но в этом все же есть доля здравого смысла.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Forger сказал:

Никто в этом и не обвиняет...

Так я и не имел ввиду какие-то обвинения:smile:

 

2 часа назад, Forger сказал:

В свое время в PICах делал еще и так: все свободное место в прошивке спец. утилитой "забивал" командой "GOTO 0"...

Делаю и сейчас так. Забиваю неиспользуемую Flash опкодом SVC n. Некоторое время назад мелькала тут тема с этой идеей; идеологически с ней согласился и юзаю...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По теме - если возврат в resethandler (или куда там еще у кого) не предполагается - то у сишных функций аттрибут noreturn надо ставить - и стек не будет использоваться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На сколько я помню, реализация библиотеки Си для AVR имеет после main() бесконечный цикл. Возврат в ResetHandler не производится, потому как из него и не происходит вызова. Вместо вызова делается просто jmp куда надо - т.е. на начало стартап кода, который подготавливает Си окружение и прыгает в main().

Убрать из main бесконечный цикл и посмотреть в отладчике что будет дальше не составляет никаких проблем. Более того - этим способом можно посмотреть даже на то, что происходит ДО main. Нужно только поставить брэйкпоинт на reset handler и шагать по инструкциям.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 hours ago, sigmaN said:

можно посмотреть даже на то, что происходит ДО main.

Инициализация глобальных и локальных статических переменных, вызов конструкторов глобальных объектов (для С++ кода), копирование кода RAM-функций из флеша в ОЗУ. Может ещё что-то пропустил.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 11/15/2019 at 1:59 PM, ViKo said:

Вопрос к тем, кто копает глубже. 

Вот, копнул IAR (release build проекта)

На выходе из  main() помещена инструкция NOP, а после неё - константы..

Стало быть, возвращаемое никем не анализируется и наступает крах

(ну, если обработчик прерываний настроить, очевидно пойдём по вектору)

main.PNG

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, svss сказал:

Стало быть, возвращаемое никем не анализируется и наступает крах

Так у вас же бесконечный цикл, ничего не возвращается из main. А если без него, как скомпилируется?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, svss сказал:

Вот, копнул IAR (release build проекта)

На выходе из  main() помещена инструкция NOP, а после неё - константы..

На представленном скриншоте нет ничего касающегося выхода из main() или того, что будет выполняться после. От слова "совсем". Не несите чепуху, учите ассемблер.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, ViKo said:

А если без него, как скомпилируется?

Да, картина поменялась. После пуска срабатывают точки останова 1 2 3 3 3 3 ..

Судя по всему IAR "понимает" присутствие while(1) и не добавляет код вокруг "_exit" : уровень оптимизации этого проекта - "high".

pure_main.PNG

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 11/15/2019 at 5:01 PM, ViKo said:

Пишет на ассемблере

Попробовал PIC16F887, компилятор Микроэлектроника microC PRO for PIC 7.2.0.

Сделать goto на ... в С не дает, говорит, что неправильно это, пришлось изменить в оболочке программатора - заменил код goto на_начало_main на код goto на_...

Вернулся на начало, проинициализировался, выдал результат и далее по кругу. Для верности надо бы осциллографом посмотреть - время выполнения в обоих вариантах. 3FFF не соответствует ни одному коду (команда addlw имеет код 3EFF, по крайней мере компилятор должен так формировать), проблем вроде нет, счетчик команд шлепает себе и шлепает. Рано или поздно вернется на исходную позицию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 minutes ago, Vlad_G said:

3FFF не соответствует ни одному коду

В этом семействе 3FFF означает пустую ячейку FLASH, стертую.

Чтобы избежать хождения по пустой флэши, используйте соотв. утилиты, которые на основе исходной HEX прошивки формируют новую, где все пустые ячейки заполняются какой-нить однозначной командой, в данном случае, например, NOP или GOTO 0

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...