Prévia do material em texto
SISTEMAS EMBARCADOS II Ementa: Microcontroladores. Arquitetura de microcontroladores. Ferramentas de Desenvolvimento. Interface. Desenvolvimento de Software para sistemas embarcados. Controladores Lógico Programáveis - Confiabilidade de sistemas com microcontrolador. Aplicações. Introdução a sistemas de tempo real. Bibliografia básica: OLIVEIRA, André Schneider de; ANDRADE, Fernando Souza de.Sistemas Embarcados - Hardware e Firmware na Prática. Editora Saraiva. São Paulo. 06/2010. Ciências Exatas. Livro digital/recurso online [Minha Biblioteca]. D'AMORE, Roberto.VHDL - Descrição e Síntese de Circuitos Digitais, 2ª edição. Grupo GEN. Rio de Janeiro. 04/2012. Ciências Exatas. Livro digital/recurso online [Minha Biblioteca]. COSTA, Cesar da.Projetos de Circuitos Digitais com FPGA. Editora Saraiva. São Paulo. 06/2014. Ciências Exatas. Livro digital/recurso online [Minha Biblioteca]. Bibliografia complementar: SOUZA, David José de; SOUSA, Daniel Rodrigues de.Desbravando o Microcontrolador PIC18 - Ensino Didático. Editora Saraiva. São Paulo. 06/2012. Ciências Exatas. Livro digital/recurso online [Minha Biblioteca]. SOUZA, David José de.Desbravando o PIC - Ampliado e Atualizado para PIC 16F628A. Editora Saraiva. São Paulo. 06/2009. Ciências Exatas. Livro digital/recurso online [Minha Biblioteca]. STEVAN JR., Sergio Luiz; SILVA, Rodrigo Adamshuk.Automação e Instrumentação Industrial com Arduino - Teoria e Projetos. Editora Saraiva. São Paulo. 06/2015. Ciências Exatas. Livro digital/recurso online [Minha Biblioteca]. CAPUANO, Francisco Gabriel.Sistemas Digitais - Circuitos Combinacionais e Sequenciais. Editora Saraiva. São Paulo. 06/2014. Ciências Exatas. Livro digital/recurso online [Minha Biblioteca]. GUIMARÃES, Alexandre de Almeida.Eletrônica Embarcada Automotiva. Editora Saraiva. São Paulo. 06/2007. Ciências Exatas. Livro digital/recurso online [Minha Biblioteca]. Questão 1 - As interrupções são muito utilizadas no mundo dos microcontroladores e dos microprocessadores. Um exemplo típico são nossos microcomputadores PC. Sempre que pressionamos uma tecla, uma interrupção é gerada para o microprocessador, solicitando o tratamento desta. Assim, o PC não é obrigado a varrer constantemente o teclado em busca de uma tecla. Porém é claro que para que isso seja feito, “alguém ou alguma coisa” deve fazer esta varredura por ele. Isso é feito por um microcontrolador dedicado, interno em todos os teclados de PC. Assim temos a geração de uma interrupção no processamento central por parte de um “periférico”. Porém, para utilizar interrupções, é necessário que o projetista compreenda o ciclo de ações implementadas pelo microcontrolador a partir do momento em que uma interrupção aciona o microcontrolador. Desta forma, apresente todos os passos implementados pelo microcontrolador desde o momento em que uma interrupção ocorre, explicando cada um desses passos. . 1. Detecção da Interrupção Monitoramento de Sinais O microcontrolador conta com circuitos especializados que acompanham mudanças em sinais externos. Essas alterações podem ser identificadas por transições de nível lógico, seja na borda de subida ou descida, conforme configurado para detectar eventos específicos. Geração do Sinal de Interrupção Assim que ocorre um evento pré-determinado, o sistema gera automaticamente um sinal de interrupção, que é enviado ao módulo de controle interno para processamento imediato. 2. Reconhecimento e Validação Verificação de Habilitação O controlador de interrupção analisa se a fonte do sinal está devidamente habilitada no sistema, descartando qualquer solicitação não autorizada. Avaliação de Prioridade Se houver múltiplas interrupções simultâneas, o sistema determina qual delas deve ser atendida primeiro, com base em um critério de prioridade previamente estabelecido. Confirmação de Validade Após a validação, o controlador notifica o processador, sinalizando que há uma interrupção legítima aguardando tratamento. 3. Suspensão da Execução do Código Principal Desativação Temporária Para evitar conflitos e controlar possíveis interrupções aninhadas (caso permitidas), o microcontrolador pode temporariamente desabilitar novas interrupções ou ajustar as máscaras de prioridade. Salvamento do Contexto Antes de interromper a execução do código principal, o sistema armazena o estado atual do processador, incluindo: · Registradores de propósito geral · Contador de programa (PC) · Registradores de status e flags · Outros registradores críticos do sistema Esses dados, geralmente armazenados na pilha, garantem que a execução possa ser retomada corretamente após o atendimento da interrupção. 4. Transição para a Rotina de Serviço de Interrupção (ISR) Busca na Tabela de Vetores Cada fonte de interrupção possui um endereço associado na tabela de vetores. O sistema consulta essa tabela para localizar o endereço da ISR correspondente. Atualização do PC O contador de programa (PC) é então atualizado para apontar para a rotina de serviço de interrupção, desviando temporariamente o fluxo de execução do programa para o tratamento adequado. 5. Execução da ISR Tratamento Específico A ISR (Interrupt Service Routine) contém as instruções necessárias para lidar com a interrupção, realizando tarefas como: · Leitura e processamento de dados de dispositivos periféricos · Interpretação e manipulação de sinais · Atualização de estados internos e controle de hardware Otimização e Brevidade Para evitar impactos no desempenho geral do sistema, a ISR deve ser eficiente, evitando operações demoradas e liberando o processador o mais rápido possível para retomar a execução normal. 6. Restauração do Contexto Recuperação de Dados Ao concluir a ISR, o sistema restaura todas as informações salvas anteriormente, incluindo: · Todos os registradores alterados durante a interrupção · O contador de programa (PC), garantindo que a execução retorne exatamente ao ponto onde foi interrompida Retorno Seguro Esse processo assegura que o sistema volte ao estado original antes da interrupção, permitindo que o código principal continue sua execução sem inconsistências. 7. Retorno à Execução Normal Reativação das Interrupções Com o contexto restaurado, o microcontrolador reativa as interrupções temporariamente desabilitadas, respeitando as configurações de prioridade e máscara. Continuidade do Fluxo de Execução O processador retoma a execução do programa principal a partir do ponto exato onde parou, garantindo a continuidade das operações sem prejuízos ao funcionamento do sistema Questão 2 - Considere que um aluno de Sistemas Embarcados II deseja realizar um pequeno programa para compreender a comunicação serial USART de um microcontrolador STM32VL Discovery. a) Faça o fluxograma do projeto de um microcontrolador que faça a leitura do estado de um led acionado por um botão, e envie a palavra “ON” quando o led estiver aceso. b) Desenhe o frame da palavra “ON” considerando uma comunicação Serial com as configurações 19200/8-N-2, em transmissão RS-232. Frame para "O" (0x4F) Campo Valor Start 0 D0 1 D1 1 D2 1 D3 0 D4 1 D5 1 D6 1 D7 0 Stop 11 Frame para "N" (0x4E): Campo Valor Start 0 D0 0 D1 1 D2 0 D3 1 D4 1 D5 1 D6 0 D7 0 Stop 11 c) Determine o Bef e o Overhead. O overhead pode ser determinado subtraindo a quantidade total de bits pela quantidade de bits realmente utilizados. Para um único caractere, temos 11 bits, porém 8 bits utilizados efetivamente. Dessa forma, o overhead é: Overhead = 11 - 8 = 3 bits Para determinar a porcentagem de overhead, utilizamos a relação entre os bits extras e o total de bits: Overhead percentual = 3/11 ≈ 27,27% Bits efetivos (BEF): 8 bits por caractere Overhead: 3 bits por caractere, correspondendo aproximadamente a 27,27% do total. Questão 3 - Um engenheiro pretende realizar a comunicação entre dois microcontroladores e dois diferentes periféricos, contando com o seguinte sistema representado em hardware Represente o comportamento de todos os pinosdo master ao longo de uma comunicação do master 1 com o slave 2 para escrita de 1 byte. A Tabela 1 representa o byte presente no registrador de saída de cada dispositivo no momento do início da transmissão. Despreze os intervalos de transição de sinal. Dispositivo Byte Master 1 10011100 Master 2 01010101 Slave 1 10100101 Slave 2 00111100 Ciclo de Clock Borda de Clock MOSI (Master Out Slave In) 1 Subida 1 1 (meio) Descida 1 2 Subida 0 2 (meio) Descida 0 3 Subida 0 3 (meio) Descida 0 4 Subida 1 4 (meio) Descida 1 5 Subida 1 5 (meio) Descida 1 6 Subida 1 6 (meio) Descida 1 7 Subida 0 7 (meio) Descida 0 8 Subida 0 8 (meio) Descida 0 Questão 4 - Considere um sistema com múltiplos microcontroladores se comunicando por meio de uma rede zigbee. Um determinado microcontrolador informa o valor de temperatura lido em uma determinada caldeira, que deve ser devidamente escrito em um display conectado a outro microcontrolador da mesma rede. Após alguns erros de controle, um determinado engenheiro percebeu que a informação escrita no display era consideravelmente diferente daquela enviada originalmente (vide Tabela 1, das últimas dez medições realizadas). Escreva qual serviço do Kernel de um RTOS é capaz de solucionar este problema e explique como é realizada a solução. Temperatura enviada (ºC) Temperatura Display (ºC) 098 099 099 000 100 109 099 098 098 000 100 102 102 104 O serviço de Message Queue (fila de mensagens) em um RTOS é a solução ideal para garantir que as leituras transmitidas por um microcontrolador cheguem ao outro sem inconsistências. Utilizando essa estrutura, cada valor de temperatura é enviado de maneira atômica — ou seja, indivisível — e na ordem correta, evitando a corrupção ou mistura de dados. Logo na inicialização do sistema, uma fila de mensagens é configurada com espaço suficiente para armazenar as leituras de temperatura, assegurando um fluxo contínuo de dados entre os microcontroladores. Sempre que o sensor de temperatura realiza uma nova medição, a tarefa correspondente adiciona o valor à Message Queue. Esse processo ocorre de forma assíncrona, permitindo que o microcontrolador responsável pela exibição processe os dados independentemente do momento da aquisição. Já o microcontrolador encarregado da interface gráfica opera em um loop contínuo, aguardando a chegada de novos valores na fila de mensagens. Assim que uma nova leitura é recebida, o sistema captura a informação e a envia para o display, garantindo uma atualização precisa e em tempo real. Embaixo exemplo de pseudocódigo em que se utiliza uma Message Queue para garantir a integridade dos dados de temperatura transmitidos entre dois microcontroladores (um que faz a leitura da temperatura e outro que exibe no display), em um ambiente de RTOS: // Criação da Fila (no código de inicialização do sistema) // TamanhoMáxFila: quantidade de mensagens que a fila pode armazenar // TamanhoDado: tamanho (em bytes) de cada mensagem (por ex.: sizeof(int)) queueTemperatura = criarFila(TamanhoMáxFila, TamanhoDado); // --------------------------------------------------------------------- // Tarefa: Leitura de Temperatura (Microcontrolador A) void tarefaLeituraTemperatura() { inicializarSensor(); while (1) { int tempAtual = lerSensorTemperatura(); // Função de leitura do sensor enviarMensagem(queueTemperatura, &tempAtual); // envia a temperatura para a fila; função pode bloquear se fila estiver cheia aguardar(intervaloLeitura); // Delay ou bloqueio RTOS (ex. vTaskDelay) } } // --------------------------------------------------------------------- // Tarefa: Recepção e Exibição de Temperatura (Microcontrolador B) void tarefaExibirTemperatura() { inicializarDisplay(); while (1) { int tempRecebida; // Espera até receber uma nova temperatura (bloqueia se a fila estiver vazia) if (receberMensagem(queueTemperatura, &tempRecebida)) { // Se recebeu com sucesso, exibe no display atualizarDisplay(tempRecebida); } aguardar(intervaloExibicao); // Delay ou bloqueio RTOS } } Questão 5 - Dois microcontroladores estão operando como mestre e devem realizar uma comunicação I²C para dois periféricos, um sensor de temperatura que escreve informações no microcontrolador que requisitou e um painel de LCD que lê informações do microcontrolador que requisitou. Considere que, simultaneamente, um microcontrolador faça uma requisição para leitura do sensor de temperatura (end. 0xA0) enquanto o segundo microcontrolador realiza uma operação de escrita no painel de LCD (end. 0x9F). Faça um diagrama de tempo representando o processo de arbitragem da comunicação realizada, apontando qual dos microcontroladores ganha o processo de arbitragem. No protocolo I²C (Inter-Integrated Circuit), a comunicação ocorre por meio de um barramento compartilhado, que utiliza duas linhas: SDA (Serial Data Line) e SCL (Serial Clock Line). Quando múltiplos dispositivos mestres tentam acessar o barramento ao mesmo tempo, entra em ação um mecanismo de arbitragem que garante que apenas um mestre continue a transmissão, evitando conflitos. Cenário de Comunicação Neste exemplo, temos dois microcontroladores operando como mestres e dois periféricos configurados como escravos: · O Mestre 1 (M1) inicia uma requisição de leitura ao sensor de temperatura localizado no endereço 0xA0. · O Mestre 2 (M2), simultaneamente, tenta enviar dados para um painel LCD no endereço 0x9F. Cada dispositivo escravo possui um endereço de 7 bits, seguido de um bit adicional que indica a operação: 1 para leitura e 0 para escrita. · Endereço do Sensor de Temperatura: 0xA0 → 10100000 (binário) · Endereço do Painel LCD: 0x9F → 10011111 (binário) Processo de Arbitragem · Condição de Start: Inicialmente, ambos os mestres identificam que o barramento está livre e iniciam simultaneamente a condição de START, forçando a linha SDA para nível baixo (LOW) enquanto a SCL permanece em nível alto (HIGH). · Transmissão de Endereço e Comparação Bit a Bit: Os dois mestres começam a transmitir os endereços dos dispositivos-alvo. Como o barramento I²C segue um modelo open-drain, qualquer dispositivo pode forçar a linha SDA para o nível LOW, mas nenhum pode impô-la diretamente para HIGH. Durante esse processo, cada mestre monitora constantemente a linha SDA enquanto envia os bits do endereço correspondente. Detecção de Conflito e Perda da Arbitragem A arbitragem ocorre de forma bit a bit. Se um mestre transmite um 1 e percebe que a linha SDA está em 0 (porque outro mestre impôs esse nível), ele reconhece que perdeu a arbitragem e imediatamente interrompe a transmissão. No caso analisado, essa disputa acontece no terceiro bit da transmissão (10100000 vs. 10011111). O Mestre 1 (M1) envia um 1, enquanto o Mestre 2 (M2) transmite um 0. Como o nível LOW sempre prevalece, o Mestre 2 (M2) vence a arbitragem e assume o controle do barramento. Questão 6 - Descreva cada instrução do código abaixo da linguagem Assembly do ARM e explique a função que o código executa. (x, y e z estão mapeados na memória) 0x00 inicio: ldr r1,x 0x04 0x08 0x0C 0x10 loop: ldr cmp subgt sublt r2,y r1,r2 r1,r1,r2 r2,r2,r1 0x14 0x18 0x1C bne str .end loop r1,z Linha 0x00 – inicio: ldr r1, x Carrega no registrador R1 o valor que está armazenado na posição de memória associada à variável x. Linha 0x04 – ldr r2, y Carrega no registrador R2 o valor que está armazenado na posição de memória associada à variável y. Linha 0x08 – loop: cmp r1, r2 Compara os valores contidos em R1 e R2. Essa instrução atualiza os flags de condição do processador (por exemplo, se R1 é maior, menor ou igual a R2). Linha 0x0C – subgt r1, r1, r2 Se a condição "gt" (greater than – maior que) estiver satisfeita, ou seja, se R1 for maior que R2, subtrai o valor de R2 de R1 e armazena o resultadoem R1. Linha 0x10 – sublt r2, r2, r1 Se a condição "lt" (less than – menor que) estiver satisfeita, ou seja, se R2 for menor que R1, subtrai o valor de R1 de R2 e armazena o resultado em R2. Linha 0x14 – bne loop Se os valores em R1 e R2 ainda não são iguais (branch if not equal – desvio se não forem iguais), desvia a execução de volta para o rótulo loop, reiniciando o processo de comparação e subtração. Linha 0x18 – str r1, z Quando R1 e R2 se tornam iguais, essa instrução armazena o valor de R1 (que neste ponto representa o Máximo Divisor Comum) na posição de memória associada à variável z. Linha 0x1C – .end Indica o fim do código. Questão 7 - O trecho do programa a seguir é um exemplo de função que calcula o n-ésimo termo da sequência de Fibonacci, dada por (1,1,2,3,5,8,13,21,...), na qual cada termo subsequente corresponde à soma dos dois termos anteriores (com exceção dos dois primeiros termos, 1 e 1). O valor de entrada é n (n>0) e o valor de saída é x, que é o n-ésimo termo. (n e x estão mapeados na memória) 0x00 0x04 inicio: ldr r0,n cmp r0,0x01 @Carrega o valor de n no registrador r0 @Compara r0 com 0x01 0x08 0x0C beq sub termo1 r0,r0,0x01 @Desvia para termo1 caso positivo @r0 = r0 - 0x01 0x10 0x14 0x18 0x1C 0x20 loop: cmp mov mov mov r0,0x01 beq r1,0x01 r2,0x01 r3,0x01 fim @r1 = 0x01 @r2 = 0x01 @r3 = 0x01 @Compara r0 com 0x01 @Desvia para fim caso positivo 0x24 0x28 0x2C 0x30 sub add mov mov r0,r0,0x01 r3,r1,r2 r2,r1 r1,r3 @r0 = r0 - 0x01 @r3 = r1 + r2 @r2 = r1 @r1 = r3 0x34 0x38 termo1 : b mov loop r3,0x01 @desvia para loop @r3 = 0x01 0x3C 0x40 0x44 fim: str nop nop r3,x @armazena o valor de r3 em x @nenhuma operação @nenhuma operação Para n = 4, pede-se: a) Realize a execução do programa, indicando, para cada ciclo de relógio: 0x00: ldr r0, n ; r0 ← n da memória 0x04: cmp r0, #1 0x08: beq termo1 0x0C: sub r0, r0, #1 0x10: cmp r0, #1 0x14: beq fim 0x18: mov r1, #1 0x1C: mov r2, #1 0x20: mov r3, #1 0x24: cmp r0, #1 0x28: beq fim 0x2C: sub r0, r0, #1 0x30: add r3, r1, r2 0x34: mov r2, r1 0x38: mov r1, r3 0x3C: b 0x24 ; (loop incondicional) 0x40: mov r3, #1 ; termo1: 0x44: str r3, x ; fim: salva r3 em x nop nop i) O estágio de cada instrução utilizando a técnica de pipeline (veja o exemplo), com a seguinte legenda: B=busca, D=decodificação, X=execução. ii) O endereço de instrução armazenado no registrador PC (hexa) iii) Os valores dos registradores r0, r1, r2 e r3 (decimal) ao final do ciclo de relógio · Ciclo 3: · ldr r0,n executa (X) → r0 = 4. · r1, r2, r3r1,\,r2,\,r3r1,r2,r3 ainda indefinidos ou 0 (depende do simulador, mas não importa). · Ciclo 6: · sub r0,r0,#1 executa → r0=3. · Ciclo 9: · mov r1,#1 executa → r1=1. · Ciclo 10: · mov r2,#1 executa → r2=1. · Ciclo 11: · mov r3,#1 executa → r3=1. · Ciclo 14: · sub r0,r0,#1 executa → r0=2. · Ciclo 15: · add r3,r1,r2 → r3=1+1=2. · Ciclo 16: · mov r2,r1 → r2=1. · Ciclo 17: · mov r1,r3 → r1=2. · Ciclo 18: · b 0x24 (branch tomado) → PC salta para 0x24, pipeline sofre flush. · Registradores inalterados aqui (r0=2, r1=2, r2=1, r3=2). (Ocorrerão 2 ciclos “vazios” de flush. Depois prossegue…) · Ciclo 25: · sub r0,r0,#1 → r0=1. · Ciclo 26: · add r3,r1,r2 → r3=2+1=3. · Ciclo 27: · mov r2,r1 → r2=2. · Ciclo 28: · mov r1,r3 → r1=3. · Ciclo 29: · b 0x24 (branch tomado de novo) → flush, r0=1, r1=3, r2=2, r3=3. (Mais 2 ciclos de flush…) · Ciclo 34–35: · cmp r0,#1 e em seguida beq fim → agora sim dá desvio tomado, mais flush. · Próximo(s) ciclos: · finalmente str r3,x executa → guarda 3 em memória. (Utilize a tabela seguinte para escrever sua resolução) b) Quantos ciclos de relógio são necessários para executar o trecho de programa utilizando a técnica de pipeline? E se não fosse utilizado o pipeline? · Temos 26 instruções efetivamente processadas. · “Aquecimento” inicial do pipeline = 2 ciclos (para encher os 3 estágios). · 3 branches tomados 2x · 26+2 +6 = 34 vezes (b) Sem pipeline 26x3 = 78 vezes Ciclos de Relógio 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 Instruções 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C 0x20 0x24 0x28 0x2C 0x30 0x34 0x38 0x3C 0x40 0x44 Registradores PC r0 r1 r2 r3 image1.png image2.jpeg image3.png image4.png image5.png