Arquiteturas de sistemas embarcados
Prof.MSc.Rodrigo Maximiano Antunes de Almeida
Universidade Federal de Itajubá
Interrupção e Watchdog
Interrupção
Programa
Principal
Interrupção
Rotina de
Programa
Principal
Latência da Interrupção Acontece a
Interrupção da ISRInicio Continua o fluxodo programa
Tempo
Latência da Interrupção Fim da
Interrupção
Quando uma interrupção é gerada, o programa é paralizado e
uma função de interrupção é executada
Conversor AD: quando o resultado da conversão estiver
disponível para leitura.
Porta B: quando algum dos bits congurados como entrada
altera seu valor.
Interrupção
Atenção
A função que irá tratar da interrupção não retorna nem recebe
nenhum valor
Interrupção
1 void Interrupcao(void) interrupt 1 {
2 if (BitTst(PIR1,0)) { /*codigo*/ } //overflow do TIMER1
3 if (BitTst(PIR1,1)) { /*codigo*/ } //comparação do TIMER2 com PR2 4 if (BitTst(PIR1,2)) { /*codigo*/ } //comparação do CCP1
5 if (BitTst(PIR1,3)) { /*codigo*/ } //fim de operação na porta paralela 6 if (BitTst(PIR1,4)) { /*codigo*/ } //fim de transmissão da Serial 7 if (BitTst(PIR1,5)) { /*codigo*/ } //recepção da Serial
8 if (BitTst(PIR1,6)) { /*codigo*/ } //fim de conversão do AD
9 if (BitTst(PIR1,7)) { /*codigo*/ } //leitura/escrita da porta paralela 10 if (BitTst(PIR2,0)) { /*codigo*/ } //comparação do CCP2
11 if (BitTst(PIR1,1)) { /*codigo*/ } //overflow do TIMER3
12 if (BitTst(PIR1,2)) { /*codigo*/ } //condição de Tensão Alta/Baixa
13 if (BitTst(PIR1,3)) { /*codigo*/ } //detecção de colisão no barramento 14 if (BitTst(PIR1,4)) { /*codigo*/ } //fim escrita na memoria flash 15 if (BitTst(PIR1,5)) { /*codigo*/ } //interrupção da USB
16 if (BitTst(PIR1,6)) { /*codigo*/ } //mudança na entrada de comparação 17 if (BitTst(PIR1,7)) { /*codigo*/ } //falha no oscilador
Interrupção
1 BitClr(RCON,7); //desabilita IPEN (modo de compatibilidade) 2 BitSet(PIE1,6); // liga a interrupção para o AD
3 BitSet(PIE1,5); // liga a interrupção para a recepção na serial 4 BitSet(INTCON,5); // liga a interrupção para o timer 0
5 BitSet(INTCON,3); // liga a interrupção para a porta B
6 BitSet(INTCON,7); //habilita todas as interrupções globais 7 BitSet(INTCON,6); //habilita todas as interrupções de periféricos
Interrupção
O watchdog visa aumentar a segurança do projeto.
Funciona como um temporizador
Precisa ter seu contador constantemente reiniciado.
Caso não seja reiniciado no tempo exigido, o watchdog reinicia
o microcontrolador
Interrupção
1 //code char at 0x300003 CONFIG2H = 0x00; // Watchdog controlado por software
2
3 #define CLRWTD() _asm CLRWDT _endasm 4
5 void main(void) interrupt 0
6 {
7 unsigned int i; 8 unsigned char temp; 9 TRISD=0x00;
10 PORTD=0x00;
11 BitSet(WDTCON,0); //liga o sistema de watchdog
12 for(;;) 13 { 14 PORTD++; 15 for(i = 0; i < 10000; i++) 16 { 17 CLRWTD(); 18 } 19 } 20 }
Arquiteturas de sistemas embarcados
Arquiteturas de sistemas embarcados
É sempre interessante denir uma arquitetura para o software
Dependendo dos requisitos do sistema pode-se usar desde uma
programação voltada apenas para a aplicação até um sistema
operacional
Dentre as técnicas mais simples serão apresentadas três
alternativas
One single loop
Interrupt control system
One single loop
One single loop
É a estratégia utilizada até agora na disciplina
Consiste em um loop innito dentro do qual todas as tarefas
são executadas
Apenas as rotinas de inicialização acontecem antes dele
Programação é mais simples
Diculdade de garantir requisições temporais
One single loop
1 void main (void) interrupt 0
2 {
3 //declaração das variáveis 4 int ia, ib, ic;
5 float fa, fb, fc;
6 //inicialização dos periféricos 7 InicializaTeclado();
8 InicializaLCD(); 9 //único loop infinito
10 for(;;)
11 {
12 //chamada das tarefas
13 ia = LerTeclas(); 14 MudaDigito(ia,0);
15 AtualizaDisplay();//tem que ser executado pelo menos a cada 10(ms) 16 DebounceTeclas();
17 }
One single loop
1 void main (void) interrupt 0
2 {
3 //declaração das variáveis 4 int ia, ib, ic;
5 float fa, fb, fc;
6 //inicialização dos periféricos 7 InicializaTeclado();
8 InicializaLCD(); 9 //único loop infinito
10 for(;;)
11 {
12 //chamada das tarefas 13 ia = LerTeclas(); 14 EnviaDados(ia);
15 MudaDigito(ia,0);
16 AtualizaDisplay();//tem que ser executado pelo menos a cada 10(ms) 17 DebounceTeclas();
Interrupt control system
Interrupt control system
Visa resolver o problema das restrições temporais
Apenas alguns sub-sistemas podem ser operados via
interrupção
Os demais sistemas operam no loop principal
Facilita a expansão do sistema, já que as interrupções não
dependem do loop principal
Ótima alternativa para sistemas que tem como requisito o
baixo consumo de energia
Interrupt control system
1 //rotina de tempo via interrupção 2 void Interrupcao(void) interrupt 1 {
3 if (BitTst(INTCON,2)){ //TIMER0: Overflow 4 BitClr(INTCON,2); //limpa a flag
5 ResetaTimer(5000); //5ms
6 AtualizaDisplay(); //tem que ser executado pelo menos a cada 8.3(ms)
7 }
8 }
9 void main(void){
10 int ia;
11 InicializaTeclado(); 12 InicializaDisplay(); 13 InicializaTimer();
14 //inicialização da interrupção
15 BitClr(RCON,7); //desabilita IPEN (modo de compatibilidade) 16 BitSet(INTCON,5); //liga a interrupção para o timer 0
Interrupt control system
Atenção
Interrupt control system
Atenção
Interrupt control system
Atenção
Usar as interrupções apenas para rotinas simples, rápidas e
NECESSÁRIAS.
Programando multitasking de modo eciente
Multitasking
Multitasking é a capacidade de se executar mais de uma tarefa
simultâneamente.
A maioria dos sistemas embarcados (por serem de baixo custo)
não possuem esta caracteristica
A alternativa é discretizar o tempo e permitir que as tarefas
sejam executadas em janelas de tempo, de modo sequêncial.
Se a alternância entre as tarefas for rápida o suciente, o
sistema apresentará o comportamento de multitasking
Programando multitasking de modo eciente
Exemplo de máquina de estados
Inicio
Ler
Teclado
Atualiza
Display
Escreve
Serial
Atualiza
Display
Ler Serial
Atualiza
Display
Programando multitasking de modo eciente
Cada ciclo representa um estado do sistema, a tarefa
atualmente em execução
Apos a fase de inicialização, o sistema entra num ciclo
A transposição da máquina de estados para linguagem C pode
ser feita de modo simples através da estrutura Switch-Case
1 void main(void) interrupt 0{
2 char slot; 3 //Inicializa...
4 for(;;){ //inicio do loop infinito
5 //******************** top-slot ********************** 6 //*********** início da maquina de estado ************
7 switch(slot){
8 case 0:
9 LeTeclado(); slot = 1; break;
10 case 1:
11 AtualizaDisplay(); slot = 2; break;
12 case 2:
13 RecebeSerial(); slot = 3; break;
14 case 3:
15 AtualizaDisplay(); slot = 4; break;
16 case 4:
17 EnviaSerial(); slot = 5; break;
18 case 5:
19 AtualizaDisplay(); slot = 0; break; 20 default:
21 slot = 0; break;
22 }
23 //************ fim da maquina de estado ************** 24 //****************** bottom-slot ********************* 25 } //fim loop infinito (!?)
Programando multitasking de modo eciente
Deve-se notar que foram criadas três areas dentro de cada
ciclo
A maquina de estado
O top-slot
O bottom-slot
O aumento de tarefas se torna mais simples, basta adicionar
outro slot com a função desejada
O bottom e top slots podem ser usados para tarefas que
deveriam ser realizadas em todos os ciclos como a
1 void main(void) interrupt 0{ 2 char slot;
3 //Inicializa...
4 for(;;){ //inicio do loop infinito
5 //******************** top-slot **********************
6 AtualizaDisplay();
7 //*********** início da maquina de estado ************ 8 switch(slot){
9 case 0:
10 LeTeclado(); slot = 1; break;
11 case 1:
12 RecebeSerial(); slot = 2; break;
13 case 2:
14 EnviaSerial(); slot = 0; break; 15 default:
16 slot = 0; break;
17 }
18 //************ fim da maquina de estado ************** 19 //****************** bottom-slot ********************* 20 } //fim loop infinito (!?)
Programando multitasking de modo eciente
Uma boa prática é temporizar os slots
Deste modo cada ciclo tem o mesmo tempo para executar
Isto gera previsibilidade no funcionamento do sistema
1 void main(void) interrupt 0{
2 char slot; 3 //Inicializa...
4 for(;;){ //inicio do loop infinito
5 //******************** top-slot ********************** 6 ResetaTimer(5000); //5 ms para cada slot
7 AtualizaDisplay();
8 //*********** início da maquina de estado ************ 9 switch(slot){
10 case 0:
11 LeTeclado(); slot = 1; break;
12 case 1:
13 RecebeSerial(); slot = 2; break;
14 case 2:
15 EnviaSerial(); slot = 0; break; 16 default:
17 slot = 0; break;
18 }
19 //************ fim da maquina de estado ************** 20 //****************** bottom-slot ********************* 21 AguardaTimer();
22 } //fim loop infinito (!?)
Programando multitasking de modo eciente
Exemplo da mudança de slots no tempo
Top S.1 S.2 S.3 Bottom "vago" 0 5 10 15 20 25 30