Jump to content

    

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

Коллега задал вопрос, на который я однозначно ответить не смог. Если в Main нет бесконечного цикла, то при выходе куда попадет? Еще и код возврата передаёт же. Его и проверить можно, или как? 

Сам сейчас не имею времени для изучения. Потом попробую. Или кто точно ответит. 

Share this post


Link to post
Share on other sites

Интересно. 

Там в примере код возврата EXIT_SUCCESS.  Где анализируется? 

Share this post


Link to post
Share on other sites

А кто его знает? :)

В гуглях наверняка есть, это же стандартные сишные дела, которые встроены в любую библиотеку, поставляемую компилятором к любому камню.

Они наверняка существуют чуть ли не античных времен, когда был создан С ))

 

Share this post


Link to post
Share on other sites
31 минуту назад, mcheb сказал:

что  я встречал это while(1)

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

Share this post


Link to post
Share on other sites
25 минут назад, ViKo сказал:

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

Вопрос: а зачем?

Логично было бы наоборот - выпилить все эти функции из финальной прошивки, все равно никогда не вызываются ))

Share this post


Link to post
Share on other sites

Например, представим устройство, которое включается, что-то делает и выключается.
Вопрос "зачем" ограничивает.

Итак, "есть ли жизнь после Main"?

https://ru.cppreference.com/w/cpp/language/main_function

https://ru.cppreference.com/w/cpp/utility/program/exit

Share this post


Link to post
Share on other sites
14 minutes ago, ViKo said:

Например, представим устройство, которое включается, что-то делает и выключается.
Вопрос "зачем" ограничивает.

Итак, "есть ли жизнь после Main"?

Ничего не понятно - зачем вообще выпускать из main? Более того практически везде стоят оси и поэтому такое поведение кода попросту невозможно :mda:

В противном случае вопрос получается риторический, ответ на такой вряд ли удасться найти )

Share this post


Link to post
Share on other sites
void Reset_Handler(void)
{
	unsigned long *pulSrc, *pulDest;

	enable_fpu();

	// Инициализация стека
	for(pulDest = &_susrstack; pulDest < &_estack;) *(pulDest++) = 0xCCCCCCCC;

	// Инициализация данных в секции .data
	pulSrc = &_sidata;
	for(pulDest = &_sdata; pulDest < &_edata;) *(pulDest++) = *(pulSrc++);

	// Обнуление данных в секции .bss
	for(pulDest = &_sbss; pulDest < &_ebss;) *(pulDest++) = 0;

	// Вызов функции main
	main();
}

У меня такой стартап. При выходе из main() вернемся в Reset_Handler.

Попытка выйти из Reset_Handler приведет к краху стека.

Можно или так сделать:

void Reset_Handler(void)
{
	. . .
	// Вызов функции main
	main();
  	while(1);
}

или так:

void Reset_Handler(void)
{
	. . .
	// Вызов функции main
	while(1) main();
}
void Reset_Handler(void)
{
	. . .
  	// Вызов функции main
	main();
  	while(1) NVIC_SystemReset();
}

Но выход из main() в МК не имеет смысла.

Share this post


Link to post
Share on other sites

Помню, на ассемблере, как закончится программа, так процессор дальше топает по пустой памяти до конца. Потом с нуля начинает новую жизнь.

Надо думать, на C такого не будет? Нечто удержит программный счетчик в рамках, или остановит его.

Share this post


Link to post
Share on other sites
14 минут назад, ViKo сказал:

так процессор дальше топает по пустой памяти до конца

Даже если там нет валидных опкодов?

Share this post


Link to post
Share on other sites
Цитата

System termination
This illustration shows the different ways an embedded application can terminate in a
controlled way:

image.png.e2a4a491a563449b5bd63c9fa52e363d.png

An application can terminate normally in two different ways:
● Return from the main function
● Call the exit function.
Because the C standard states that the two methods should be equivalent, the system
startup code calls the exit function if main returns. The parameter passed to the exit
function is the return value of main.
The default exit function is written in C. It calls a small assembler function _exit that
will:
● Call functions registered to be executed when the application ends. This includes
C++ destructors for static and global variables, and functions registered with the
standard function atexit. See also Setting up the atexit limit, page 106.
● Close all open files
● Call __exit
● When __exit is reached, stop the system.
An application can also exit by calling the abort or the _Exit function. The abort
function just calls __exit to halt the system, and does not perform any type of cleanup.
The _Exit function is equivalent to the abort function, except for the fact that _Exit
takes an argument for passing exit status information.

If you want your application to do anything extra at exit, for example resetting the
system (and if using atexit is not sufficient), you can write your own implementation
of the __exit(int) function.
The library files that you can override with your own versions are located in the
arm\src\lib directory. See Overriding library modules, page 122.

Это отрывок из IAR-овской доки EWARM_DevelopmentGuide.ENU.pdf.

 

Share this post


Link to post
Share on other sites
20 минут назад, ViKo сказал:

Надо думать, на C такого не будет?

Чудес не бывает. Даже на сях. 

56 минут назад, adnega сказал:

При выходе из main() вернемся в Reset_Handler.

Попытка выйти из Reset_Handler приведет к краху стека.

В общем случае reset_handler вызывает cstartup, cstartup делает инициализацию и вызывает main(), после вызова main() в cstartup обычно стоит пустой цикл.

Share this post


Link to post
Share on other sites
17 минут назад, SSerge сказал:

Это отрывок из IAR-овской доки EWARM_DevelopmentGuide.ENU.pdf.

Хорошая дока. А целиком можете выложить?

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