Quem recebe o valor retornado por main ()?

34

Eu sei que em computadores, o valor retornado pela main()função é recebido pelo sistema operacional. Mas, o que acontece na main()função de um microcontrolador?

user18118
fonte
7
Eu sempre uso void main () quando estou usando C para microcontroladores PIC. Ao usar compiladores C para microcontroladores, isso realmente não importa. Porque não existe um sistema operacional que execute o (digamos) "main.c". Se houver algo como o RTOS em execução nesse microcontrolador, o sistema operacional será o "main.c".
Abdullah kahraman
4
Não é realmente uma duplicata, mas pelo menos está relacionada: electronics.stackexchange.com/q/30830/4950
PetPaulsen
11
Como a função de inicialização é definida geralmente não cabe a você decidir. O ambiente que você está usando documentará os formulários de função de inicialização suportados. As implementações C hospedadas são necessárias para suportar duas formas de, maincom duas assinaturas diferentes, as quais retornam int. Se você estiver usando uma implementação C independente, essa implementação determinará como você deve escrever a função de inicialização. Você não pode escrever uma voidfunção de retorno apenas porque ela não retorna. O comportamento de não retornar é diferente do tipo de função que influencia as convenções gerais de chamada.
Kaz

Respostas:

42

Em um microcontrolador, main()não é realmente esperado que ele saia, e o comportamento, se o fizer, não está definido - portanto, cabe a quem escreveu o tempo de execução C para o microcontrolador. Eu já vi sistemas que:

  • Tenha um loop implícito main(), para que, se ele sair, ele simplesmente seja chamado novamente.
  • Tenha um loop simples de "pular para si mesmo" que é executado se main()alguma vez sair.
  • Simplesmente execute o restante da memória de código que segue a chamada para main(). Isso é chamado de "fugir para as ervas daninhas".

Eu nunca vi um que realmente faça algo com o valor retornado por main(). Se você realmente se importa com isso, deve dar uma olhada - e possivelmente modificar - o código fonte da biblioteca de tempo de execução C do seu sistema.

Dave Tweed
fonte
11
Você chegou antes de mim. +1 para sincronicidade.
Adam Lawrence
9
O padrão C que define main()um intvalor de retorno obviamente não foi projetado com um microcontrolador sem sistema operacional em mente. Portanto, esse é um comportamento não especificado e tudo pode acontecer, dependendo do seu tempo de execução C, conforme Dave listado.
Ndim
4
C rodando em um microcontrolador sem SO pode ser considerado uma implementação independente, e o padrão C nem exige que um ambiente independente tenha um main(), muito menos defina seu valor de retorno. Isso depende do implementador.
precisa saber é o seguinte
2
@ndim - para dividir os cabelos, void main( void )é um comportamento definido pela implementação , não um comportamento não especificado .
22413 Andrew Andrew
11
@ MichaelEdenfield: De fato. No entanto, todo o código em C é definido em termos de funções, portanto, nunca é possível ter um sistema permanente escrito completamente em C; precisa haver pelo menos um pouquinho da linguagem assembly (ou qualquer outra coisa) que configure um ambiente mínimo para que uma função C possa ser chamada. O nome mais óbvio para essa função é main().
Dave Tweed
5

Um mal-entendido / mito comum é que int mainé a única forma válida especificada pelo padrão. Isso não é verdade.

O padrão C fala de duas implementações: hospedadas e independentes. "Implementação" neste caso significa compilador. Compiladores hospedados compilam para um SO específico e compiladores independentes compilam para um aplicativo bare metal específico. Os sistemas embarcados são quase sempre sistemas independentes - mesmo no caso do RTOS.

As implementações independentes podem usar qualquer formato main(), elas nem precisam ter uma função chamada main. Na maioria das vezes, eles usam o formulário void main (void), pois não faz sentido retornar nada.

O que é importante perceber aqui é que é sempre o compilador que decide a forma main()e nunca o programador.

Autônomas implementações que fazer retorno algo main()são muito questionável. Faz você se perguntar se as pessoas que criaram o compilador realmente lêem o padrão ...

Detalhes aqui .

Lundin
fonte
3

O padrão da linguagem C permite a variação definida pela implementação void main( void )e esta é a forma usual em sistemas embarcados - simplesmente porque não se espera que eles retornem.

Se você observar a configuração do compilador, geralmente há um trecho de código de inicialização, chamado a partir do vetor reset, que executa algumas inicializações básicas (incluindo, por exemplo, a cópia de valores de inicialização em variáveis) antes de chamar main ().

Isso também (geralmente) estará dentro de um loop infinito, ou talvez faça uma redefinição, se main()retornar

Andrew
fonte
0

(Como outras respostas mencionadas) depende do seu conjunto de ferramentas, mas, por exemplo, no GCC main é compilado como outras funções, portanto, seu valor de retorno será armazenado de acordo com as convenções de chamada (no ARM que estou usando não no GCC, ele será colocado em R0 pouco antes do retorno).

Eu acho que é semelhante ao AVR-GCC, então o script personalizado pode usar esse valor após os retornos principais.

kwesolowski
fonte
esta vez perde o ponto
Chris Stratton
Ele enfatiza que quem liga mainpode obter seu valor de retorno. É claro que é ignorado em 99,9% das situações, mas a resposta fornece informações sobre quem pode receber esse valor de retorno.
Kwesolowski