sistemas reativos – interrupções em microcontroladores

27
– Sistemas Reativos – Interrupções em microcontroladores (baseado no Atmega328p – Arduino Uno) Noemi Rodriguez [email protected] Adriano Branco [email protected]

Upload: others

Post on 27-Apr-2022

10 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Sistemas Reativos – Interrupções em microcontroladores

– Sistemas Reativos –

Interrupções em microcontroladores

(baseado no Atmega328p – Arduino Uno)

Noemi [email protected]

Adriano [email protected]

Page 2: Sistemas Reativos – Interrupções em microcontroladores

Interrupção no Microcontrolador

● Mecanismo para interromper a execução do programa principal.

– Desvia a execução para um endereço especial.

– Retorna para a execução principal exatamente no local que foi interrompido.

● Amplamente utilizado em microcontroladores e CPUs convencionais.

● Equivale a um evento primário em sistemas reativos.

Page 3: Sistemas Reativos – Interrupções em microcontroladores

Tipos

● Externa– Pinos digitais – INT0, INT1

– Barramento – PC0, PC1, PC2

● Interna– Temporizadores e Watchdog Time-out

– Interface de comunicação – USART, SPI, TWI

– Outros – Conversor A/D, EEPROM

Page 4: Sistemas Reativos – Interrupções em microcontroladores

Execução da interrupção

Execuçãoda rotinaprincipal

Execuçãoda rotina deinterrupção

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

101 102 103 104

Evento de Interrupção

PC = 101

PC = 9

PC → Program Counter

Page 5: Sistemas Reativos – Interrupções em microcontroladores

Mudança de contexto

Execuçãoda rotinaprincipal

Execuçãoda rotina deinterrupção

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

101 102 103 104

Evento de Interrupção

PC = 101

PC = 9

Registador A = 10

Registador A = -5

Registador A = -5

Page 6: Sistemas Reativos – Interrupções em microcontroladores

Mudança de contexto

Execuçãoda rotinaprincipal

Execuçãoda rotina deinterrupção

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

101 102 103 104

Evento de Interrupção

PC = 101

PC = 9

Registador A = 10Salva A → Temp

Registador A = -5

Recupera A ← TEMPRegistador A = 10

Page 7: Sistemas Reativos – Interrupções em microcontroladores

Mudança de contexto

● No ponto de vista do microcontrolador – No início de uma interrupção, o programa deve

salvar os registradores de interesse.

– No final da interrupção, o programa deve restaurar os registradores de interesse.

● Suporte do compilador AVR-GCC – Ao utilizar o suporte de interrupção do AVR-

GCC, o compilador providencia a manutenção dos registradores.

– ISR(xxx_vect){ …... }

Page 8: Sistemas Reativos – Interrupções em microcontroladores

1 Reset 2 External Interrupt Request 0 (pin D2) (INT0_vect) 3 External Interrupt Request 1 (pin D3) (INT1_vect) 4 Pin Change Interrupt Request 0 (pins D8 to D13) (PCINT0_vect) 5 Pin Change Interrupt Request 1 (pins A0 to A5) (PCINT1_vect) 6 Pin Change Interrupt Request 2 (pins D0 to D7) (PCINT2_vect) 7 Watchdog Time-out Interrupt (WDT_vect) 8 Timer/Counter2 Compare Match A (TIMER2_COMPA_vect) 9 Timer/Counter2 Compare Match B (TIMER2_COMPB_vect)10 Timer/Counter2 Overflow (TIMER2_OVF_vect)11 Timer/Counter1 Capture Event (TIMER1_CAPT_vect)12 Timer/Counter1 Compare Match A (TIMER1_COMPA_vect)13 Timer/Counter1 Compare Match B (TIMER1_COMPB_vect)14 Timer/Counter1 Overflow (TIMER1_OVF_vect)15 Timer/Counter0 Compare Match A (TIMER0_COMPA_vect)16 Timer/Counter0 Compare Match B (TIMER0_COMPB_vect)17 Timer/Counter0 Overflow (TIMER0_OVF_vect)18 SPI Serial Transfer Complete (SPI_STC_vect)19 USART Rx Complete (USART_RX_vect)20 USART, Data Register Empty (USART_UDRE_vect)21 USART, Tx Complete (USART_TX_vect)22 ADC Conversion Complete (ADC_vect)23 EEPROM Ready (EE_READY_vect)24 Analog Comparator (ANALOG_COMP_vect)25 2-wire Serial Interface (I2C) (TWI_vect)26 Store Program Memory Ready (SPM_READY_vect)

ATmega328InterruptVector

ATmega328InterruptVector

Page 9: Sistemas Reativos – Interrupções em microcontroladores

Vantagens e desvantagens

● Orientado a eventos● Manutenção de contexto● Máquina de estado● Tempo de resposta● Longas execuções● Execução da Interrupção x Tarefas do usuário● Etc...

Page 10: Sistemas Reativos – Interrupções em microcontroladores

Usando uma interrupção

● Preparação– Configurar pinos

– Configurar interrupção

– Habilitar a interrupção

● Tratador– Função a ser executada na interrupção

Page 11: Sistemas Reativos – Interrupções em microcontroladores

INT0 e INT1

● Pinos digitais: D2 e D3

● Configurar como input e, se necessário, o pull-up.

● Pode-se configurar o tipo de transição:

– LOW to trigger the interrupt whenever the pin is low,

– CHANGE to trigger the interrupt whenever the pin changes value

– RISING to trigger when the pin goes from low to high,

– FALLING for when the pin goes from high to low.

Page 12: Sistemas Reativos – Interrupções em microcontroladores

INT0 – AVR-GCC

Preparação INT0:

• DDRD = 1<<PD2; // Set PD2 as input (INT0)

• GICR = 1<<INT0; // Enable INT0

• MCUCR = 1<<ISC01 | 1<<ISC00; // Trigger INT0 on rising edge

• sei(); //Enable Global Interrupt

Tratador INT0

● ISR(INT0_vect){ // Tratador Int0

...

}

Page 13: Sistemas Reativos – Interrupções em microcontroladores

INT0 – Arduinohttps://www.arduino.cc/en/Reference/AttachInterrupt

Preparação INT0:

• // Set pin 2 as input (INT0) on rising edge

• attachInterrupt(digitalPinToInterrupt(2), myHandler, RISING);

Tratador INT0

● void myHandler(){ // Tratador Int0

}

Comandos especiais

● interrupts (); ou sei (); => Enable interrupts

● noInterrupts (); ou cli(); => Disable interrupts

Page 14: Sistemas Reativos – Interrupções em microcontroladores

Cuidados com as otimizações do compilador

● Otimizações durante a compilação pode simplificar o código e até remover trechos aparentemente desnecessários.

● Cuidado especial no contexto da interrupção.

char X;

void myHandler(){ X = PORTB; …. código que não usa o X … PORTB = 20;}

char X;

void myHandler(){ X = PORTB; …. código que não usa o X … PORTB = 20;}

Page 15: Sistemas Reativos – Interrupções em microcontroladores

Volatile

● Força a geração do código quando for escrever na variável.

● Muito importante no contexto da interrupção.● Definição interna para PORTB

– (*(volatile uint8_t *)((0x18) + 0x20))

● Como fazer com X?volatile char X;

void myFunction(){ X = PORTB; ….

Page 16: Sistemas Reativos – Interrupções em microcontroladores

Pin change interrupt (PCINT)

● Uma única interrupção para um grupos de pinos da mesma porta.

● Qualquer alteração em um pino gera uma interrupção do tipo PCINTx. (CHANGE mode)

● Precisa ler a porta e identificar qual foi o pino (comparar com a última interrupção).

● É possível “mascarar” somente alguns bits da porta.● Não tem suporte de attachInterrupt(). ● Grupos de pinos

– ISR (PCINT0_vect) pin change interrupt for D8 to D13– ISR (PCINT1_vect) pin change interrupt for A0 to A5– ISR (PCINT2_vect) pin change interrupt for D0 to D7

Page 17: Sistemas Reativos – Interrupções em microcontroladores

Facilitadorhttp://playground.arduino.cc/Main/PinChangeInterrupt

● Executa a configuração para um pino por vez

void pciSetup(byte pin){ // enable pin *digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin)); // clear any outstanding interrupt (Interrupt Flag) PCIFR |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group (Interrupt Control) PCICR |= bit (digitalPinToPCICRbit(pin)); }● Usar a mesma rotina para tratar um grupo

– pciSetup(7); e pciSetup(8); => ISR (PCINT0_vect)

– pciSetup(A0); => ISR (PCINT1_vect)

Page 18: Sistemas Reativos – Interrupções em microcontroladores

Agendador de tarefas

● Possíveis problemas se a rotina do usuário estiver dentro da chamada da interrupção.

– Longa execução

– Bloqueios

● Como fazer para a rotina do usuário não ficar dentro da chamada da interrupção???

– “Agendador de tarefas” - Task Scheduler

– Fila de execução.

– Comando “post” para incluir tarefa.

Page 19: Sistemas Reativos – Interrupções em microcontroladores

Tarefa Interrupção – Parte A

● Refazer a parte das chaves da tarefa 3, event_driven.ino, agora usando interrupções no lugar do loop.

● Para os botões do MultiFunction Shield deve-se usar a interrupção de Pin Change A1..A3 (PCINT1_vect).

Page 20: Sistemas Reativos – Interrupções em microcontroladores

Tarefa Interrupção – Parte BTarefa Extra

● Refazer a parte dos temporizadores da tarefa 3, event_driven.ino.

● Utilizar o serviço de timers disponibilizado na aula. TimerService (.h e .c)

● Esse serviço usa interrupções internamente para executar callbacks do usuário.

Page 21: Sistemas Reativos – Interrupções em microcontroladores

Tarefa Interrupção – Parte CTarefa Extra

● Alterar o controle de execução da Tarefa 3 (já com o uso de interrupções) para agendar as execuções fora da rotina de interrupção, usar o componente Scheduler.

● Esse componente controla a execução das tarefas (callback) solicitadas de forma a ficarem fora da rotina de interrupção.

Page 22: Sistemas Reativos – Interrupções em microcontroladores

Biblioteca TimerServiceIncluir TimerService.h e TimerService.C

● Implementa #MAX_TIMERS timers.● Utiliza um float para programar tempos em

segundos, com precisão de milisegundos.● Permite até 2.147.483,648 segundos => 24,86

dias.● Quando finalizar o tempo, irá executar a função

passada como Callback.● Pode ser cancelado.● Pode ser consultado se está ativo ou não.

Page 23: Sistemas Reativos – Interrupções em microcontroladores

Biblioteca TimerServiceDetalhes em TimerService.h

    /* Instantiate TimerService  */

    TimerService();

    /* Initialize internal timer ­ must be called in setup() */

    void init();

    /* Set the timer delay ­ starts immediately     * id: Timer id ­   0 .. (MAX_TIMERS­1)     * dl: Counter in seconds (float point) ­ precision in milliseconds     * cb: Callback function to be called when the timer fired */

    boolean set(uint8_t id, float dl, cbTimer cb);

    /* Return true if the time is running, otherwise returns false     * id: Timer id ­   0 .. (MAX_TIMERS­1)  */

    boolean isRunning(uint8_t id);

    /* Clear the timer counting and the cb function registration.     * id: Timer id ­   0 .. (MAX_TIMERS­1)  */

    void stop(uint8_t id);

Page 24: Sistemas Reativos – Interrupções em microcontroladores

Exemplo TimerService

TimerService myTimer; // Cria objeto Timer

void led2(){ // Callback a ser executada digitalWrite(led2Pin, digitalRead(led2Pin)^1);}

void setup() { myTimer.init(); // Inicializa o objeto Timer // Configura o Timer0 com 5seg para execuar led2 myTimer.set(0,5.0,led2); }void loop(){}

Page 25: Sistemas Reativos – Interrupções em microcontroladores

Biblioteca SchedulerIncluir Scheduler.h e Scheduler.c

● Implementa uma lista com a quantidade #MAX_SLOTS de slots para tarefas.

● A callback de uma tarefa deve ser inserida num slot específico.

● O loop do scheduler deixa a CPU no modo Sleep até que aconteça uma interrupção de timer ou pinos.

● O loop “varre” a lista a procura de slot ativos e executa uma Callback por vez. A execução da tarefa libera o slot.

● A sequência de execução é a ordem dos slots e não a ordem de inserção.

● Não é possível inserir tarefas em slots ainda ocupados.● Se não existir tarefas pendentes, o loop volta para o

estado Sleep.

Page 26: Sistemas Reativos – Interrupções em microcontroladores

Biblioteca SchedulerDetalhes em Scheduler.h

/* Instantiate Scheduler */Scheduler();

/* Post a Task in a specific slot. Return false if exists a task. * slot: Slot id * cb: Callback function */boolean post(uint8_t slot, cbTask cb);

/* Initialize internal slots ­ must be called from setup() */void init();    /* Main schedule loop. Must be called from loop(). * Executes all pending tasks and goes to sleep mode. * The system awake on any interruption. */void loop();

Page 27: Sistemas Reativos – Interrupções em microcontroladores

Exemplo Scheduler

Scheduler taskCtl; // Cria objeto Scheduler

void led2(){ // Callback a ser executada digitalWrite(led2Pin, digitalRead(led2Pin)^1);}

void setup(){ taskCtl.init(); // Inicializa objeto Scheduler // Posta a task led2 para execução no slot 0 taskCtl.post(0,led2); }

void loop(){ // Executa as tasks pendentes ou “dorme” até uma interrupção taskCtl.loop(); }