Jump to content

    

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

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

stop: jump stop

 

Edited by gridinp

Share this post


Link to post
Share on other sites

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

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

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

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

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

Share this post


Link to post
Share on other sites
1 hour ago, Arlleex said:

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

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

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

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

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites
15 minutes ago, Arlleex said:

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

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

 

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

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

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

Share this post


Link to post
Share on other sites
2 часа назад, Forger сказал:

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

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

 

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

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites
6 hours ago, sigmaN said:

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

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

Share this post


Link to post
Share on other sites
On 11/15/2019 at 1:59 PM, ViKo said:

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

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

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

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

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

main.PNG

Share this post


Link to post
Share on other sites
1 час назад, svss сказал:

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

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

Share this post


Link to post
Share on other sites
1 час назад, svss сказал:

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

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

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

Share this post


Link to post
Share on other sites
1 hour ago, ViKo said:

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

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

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

pure_main.PNG

Share this post


Link to post
Share on other sites
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, по крайней мере компилятор должен так формировать), проблем вроде нет, счетчик команд шлепает себе и шлепает. Рано или поздно вернется на исходную позицию.

Share this post


Link to post
Share on other sites
7 minutes ago, Vlad_G said:

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

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

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now