O que acontece se houver um erro de tempo de execução em um programa? A execução do programa será interrompida? Existe alguma maneira de obter o Arduino para me dizer qual é o erro?
O que acontece se houver um erro de tempo de execução em um programa? A execução do programa será interrompida? Existe alguma maneira de obter o Arduino para me dizer qual é o erro?
Respostas:
Primeiro, vamos ver alguns exemplos do que pode dar errado.
void setup() {
int status;
pinMode(13, OUTPUT);
digitalWrite(13, status);
}
Conforme apontado por Edgar Bonet nos comentários, variáveis locais como status
no código acima não são implicitamente inicializadas pelo compilador C ++. Portanto, o resultado do código acima é indeterminado. Para evitar isso, certifique-se de sempre atribuir valores às suas variáveis locais.
As coisas são um pouco diferentes com variáveis globais e estáticas:
Variáveis globais e estáticas são garantidas para serem inicializadas em 0 pelo padrão C.
Isso significa que você não deve se preocupar em inicializá-los para 0 no seu código. De fato, você realmente deve evitá-lo, pois a inicialização pode desperdiçar memória. Inicialize-os apenas com valores diferentes de 0.
int array[10];
int v = array[100];
array[-100] = 10;
O primeiro problema aqui é que você não sabe o que será designado para v, mas o pior é que você não sabe o que errou com a atribuição para a posição -100 de array
.
void doSomething( void ) {
for (int i = 0; i < 1000; i++);
}
void setup ()
{
void (*funcPtr)( void );
funcPtr = &doSomething;
funcPtr(); // calls doSomething();
funcPtr = NULL;
funcPtr(); // undefined behavior
}
A primeira chamada para funcPtr()
realmente será uma chamada para doSomething()
. Chamadas como a segunda podem levar a um comportamento indefinido.
Bem, você pode ficar sem memória RAM, por exemplo. O quê mais. De qualquer forma, acho que seu programa continuará sendo executado, provavelmente não da maneira que você pretendia.
Em sistemas de computadores, problemas como esses geralmente são tratados em vários níveis:
Os Arduinos têm apenas uma proteção limitada do compilador e provavelmente nada mais. A boa notícia é que eles não são multitarefas; portanto, o único programa afetado é o seu. De qualquer forma, qualquer um desses erros levará a um comportamento errático.
As suposições são todos os problemas que afirmei acima são problemas de tempo de execução.
O que acontece se houver um erro de tempo de execução em um programa?
O programa continuará e o que acontecerá dependerá dos efeitos colaterais do erro de tempo de execução. Uma chamada para o ponteiro de função nula provavelmente fará o programa pular para um local desconhecido.
A execução do programa será interrompida?
Não, continuará como se nada extraordinário tivesse acontecido, provavelmente fazendo o que você não pretendia. Pode redefinir ou agir de forma irregular. Pode transformar algumas entradas em saídas e queimar um sensor ou dois (mas isso é altamente improvável ).
Existe alguma maneira de obter o Arduino para me dizer qual é o erro?
Acho que não. Como eu disse anteriormente, os mecanismos de proteção não estão lá. Não há suporte de tempo de execução do idioma, nem sistema operacional, nem verificações de hardware para acesso à memória fora dos limites (o carregador de inicialização também não conta). Você só precisa ter cuidado com o seu programa e provavelmente definir suas próprias redes de segurança.
O motivo da falta de proteção é provavelmente porque os controladores do Arduino são muito baratos, têm pouca memória e não devem executar nada muito importante (sim, parece haver um aviso de isenção de responsabilidade do AVR em algum lugar para você não usar os MCUs normalmente usados por Arduino em sistemas de suporte à vida).
Não há exceções de tempo de execução. Há apenas comportamento indefinido.
Realmente, não há exceções em tudo . Se você tentar executar uma operação inválida, seus resultados serão desconhecidos.
Não há verificação de tempo de execução, exceto o que você implementa. Seu programa está sendo executado em hardware bare-metal. É o equivalente à área de trabalho da execução no anel 0 o tempo todo, porque o ATmega não possui anéis .
Há um mecanismo que pode obter o MCU de um estado irregular e é o cronômetro do watchdog . Se você estiver implementando algum código que será executado repetidamente em um loop, que não será executado por mais tempo do que um tempo fixo, você pode definir esse período como período de observação e ativar o timer.
Então, você deve reiniciar repetidamente o timer no loop. Se o seu código congelar em algum loop de condição que nunca terminará, o cão de guarda contará como zero e, eventualmente, redefinirá o MCU.
Dessa forma, você está perdendo dados, mas se você executar o AVR WDT no modo de interrupção, poderá armazenar alguns dados antes de redefinir o MCU.
Portanto, o timer do watchdog pode proteger seu código de loops intermináveis não desejados ocasionais.
Documentation: AVR132: Usando o timer de watchdog aprimorado
Você precisaria de um depurador de hardware para algo assim. Mas geralmente você verá que o programa não está se comportando conforme o esperado e precisará examinar essa seção do código para identificar o problema.
Uma maneira comum / rápida / fácil de fazer isso é adicionar instruções de impressão para imprimir os valores das variáveis ou qualquer outra coisa, para que você saiba que o programa chega a esse ponto no código sem problemas. Isso ajudará você a isolar ainda mais o problema.
Acredito que o VisualMicro tenha alguma funcionalidade de depuração incorporada.
Eu diria que a CPU do AVR não possui nenhuma ferramenta de detecção ou recuperação de erros. Pode simplesmente parar ou continuar ignorando o erro e as consequências. Como disse sachleen, você deve adicionar algumas instruções de depuração em seu programa que imprimem dados no meio de uma operação, para testar se está funcionando. Se você usar um emulador ou definir pontos de interrupção, poderá encontrar facilmente um problema.
O Arduino será reiniciado (ou seja, será reiniciado setup()
e loop()
).