Misc

Otimização de código em microcontroladores

Autor: Laura McKinney
Data De Criação: 4 Abril 2021
Data De Atualização: 16 Poderia 2024
Anonim
Otimização de código em microcontroladores - Misc
Otimização de código em microcontroladores - Misc

Contente

O autor concluiu seu projeto de engenharia do último ano com os microcontroladores dsPic, obtendo uma ampla visão desses dispositivos.

O código em linguagem C de um microcontrolador pode exigir otimização em certos aplicativos avançados. Essa otimização de código é praticada para reduzir duas coisas cruciais:

  1. Tamanho do código: Microcontroladores podem armazenar dados e instruções limitados devido ao tamanho limitado de sua RAM. Portanto, o código precisa ser otimizado, para que as instruções disponíveis e a memória de dados possam ser utilizadas da maneira mais eficiente.
  2. Tempos de execução do código: Microcontroladores são dispositivos sequenciais que executam uma instrução de cada vez. Cada instrução de montagem consome um certo número de ciclos de clock para executar a si mesma. Portanto, o código deve ser otimizado para garantir que execute a tarefa necessária com o menor número de ciclos de clock ou instruções de montagem. Quanto menos ciclos de clock um código usa, mais rápido ele é executado. Isso significa que os aplicativos podem ser executados mais rapidamente porque os tempos de processamento são minimizados.

Este artigo apresenta dicas e truques que podem ser empregados para reduzir o tamanho e o tempo de execução de um código de microcontrolador.


O IDE de desenvolvimento MplabX da Microchip será usado para demonstrar exemplos quando apropriado.

Como medir o tempo de execução do código experimentalmente

Para ter uma ideia de quanto tempo seu código realmente leva para ser executado em tempo real, você precisa medi-lo experimentalmente. Um analisador lógico pode ser usado convenientemente para medir o tempo de execução do código e os interessados ​​podem consultar o processo por mim por e-mail. Além disso:

  • Alguns compiladores têm a capacidade de contar os ciclos de clock que um código consumirá.
  • Alguns depuradores, por exemplo, o ICD 3 do microchip, podem medir diretamente o tempo de execução por meio de um cronômetro.

1. Conheça o poder de processamento e o tamanho da memória do seu microcontrolador

Nem sempre é a frequência do clock (Mhz) que dá a imagem real da velocidade de processamento de um microcontrolador, uma medida mais realista é MIPS (mega instruções por segundo) ou o número de instruções que o MCU pode executar em um segundo.

MCUs geralmente variam de 60–70 MIPS na categoria de ponta a 20 MIPS AVRs de 8 bits. Um microcontrolador de alto MIPS é provavelmente mais caro do que um dispositivo de baixo custo, portanto, aqui você tem uma compensação entre custo e velocidade de processamento.


Os microcontroladores têm memória separada para armazenamento de dados e código de programa. O tamanho de ambos pode ser encontrado na folha de dados. Você pode precisar de um MCU com tamanho de memória maior se seu código for substancialmente grande.

2. Escolha de variáveis ​​para otimização no tamanho do código

Os microcontroladores têm memória de dados limitada, geralmente variando de 1 a 4 Kbytes. Nesse caso, é aconselhável escolher o tipo de variável mais apropriado de acordo com o intervalo esperado da data que está sendo armazenada. A tabela abaixo resume essas variáveis:

Resumo das variáveis ​​usadas na linguagem C.

Tipo de VariávelTamanho em BytesAlcance

bool

1

0 ou 1 apenas

Caracteres

1


-128 a 127

int

2

-32.768 a 32.767

int sem sinal

2

0 a 65.535

longo

4

-2.147.483.648 a 2.147.483.647

flutuador

4

Preciso até 6 casas decimais

Duplo

8

Preciso até 15 casas decimais

longo duplo

10

Preciso até 19 casas decimais

Exemplo:

  • Se duas variáveis ​​X e Y devem ser adicionadas e o resultado deve ser armazenado em Z, mas o valor de Z deve ser superior a 65.535 após a adição, então Z pode ser declarado como longo e X e Y podem ser declarados como sem sinal int, também não se espera que os valores de X e Y sejam negativos. Isso salvará 04 bytes na memória de dados que, de outra forma, teriam sido usados ​​se todas as variáveis ​​fossem declaradas tão longas.
  • Duas variáveis ​​X e Y, cujos valores são esperados em números inteiros, devem ser divididos, mas o resultado da divisão pode render um decimal, então X e Y podem ser declarados int e o resultado pode ser declarado um float ou double dependendo de a precisão necessária.

A escolha do tipo de dados pode ser crucial ao declarar matrizes contendo um grande número de elementos.

3. Escolha de variáveis ​​para otimização no tempo de execução do código

  • É um fato estabelecido que cálculos de ponto flutuante demoram mais do que cálculos de ponto fixo. Não use uma variável de ponto flutuante onde um valor decimal não é necessário. Trabalhe com inteiros sem sinal sempre que possível.
  • Variáveis ​​locais são preferidas a variáveis ​​globais. Se uma variável for usada apenas em uma função, ela deve ser declarada nessa função porque o acesso às variáveis ​​globais é mais lento do que as variáveis ​​locais.
  • Um MCU de 8 bits achará uma variável de tamanho de byte único mais rápido para acessar e um MCU de 16 bits achará uma variável de 2 bytes mais fácil de acessar devido ao comprimento do endereço gerado.

4. Otimizando Operações Aritméticas

As operações aritméticas podem ser otimizadas das seguintes maneiras.

  1. Use tabelas de consulta de valores pré-calculados em vez de avaliar um Seno ou qualquer outra função trigonométrica ou qualquer outra operação cujo resultado possa ser conhecido de antemão no código.
  2. No caso de uma tabela de consulta de seno já estar armazenada na memória, um cosseno pode ser avaliado avançando o ponteiro da matriz equivalente a 90 graus.
  3. Entre as quatro operações aritméticas, a divisão e a multiplicação levam mais tempo de processamento; na prática, pode ser na faixa de centenas de microssegundos ou mais no caso de valores de ponto flutuante.
  4. Use instruções de mudança de bit em vez de divisão e multiplicação. Uma instrução de deslocamento para a direita 3 serve para dividir por 23 onde, como uma instrução de deslocamento para a esquerda, 1 servirá para multiplicar por 21.

5. Use um microcontrolador compatível com DSP para cálculos intensivos

Alguns microcontroladores têm uma unidade de processamento DSP diferente da ALU convencional embutida em sua arquitetura. Este mecanismo DSP é projetado para realizar cálculos aritméticos muito rapidamente no menor número de ciclos de clock (um na maioria dos casos), muitas vezes mais rápido que a ALU.

As instruções que um processador DSP pode realizar mais rápido do que uma ALU são:

  • Instruções de deslocamento e rotação de bits.
  • Multiplicações, divisões e outras operações aritméticas.
  • Avaliando Sines e outras funções trigonométricas.
  • Todas as operações DSP, como FFT, DFT, convolução e filtragem FIR.

Usar o mecanismo DSP de um microcontrolador requer que:

  • Bibliotecas DSP separadas são incorporadas ao projeto.
  • Os nomes das funções são diferentes da biblioteca matemática padrão da linguagem C. A documentação dessas bibliotecas e funções pode ser obtida no site dos respectivos fabricantes.
  • O mecanismo de DSP utiliza um tipo de variável diferente 'fracionário'. Aprenda a usar variáveis ​​de tipo fracionário antes de prosseguir com as funções da biblioteca dsp.

Observe que as funções da biblioteca matemática padrão não invocarão o mecanismo DSP porque elas são traduzidas em instruções de montagem da ALU.

6. Trabalho com interrupções

Use interrupções para executar funções específicas, como:

  • Lendo valores ADC.
  • Envio e recebimento da UART.
  • Atualizando registros de ciclo de trabalho PWM.
  • Comunicação CAN ou I2C.

As interrupções atenderão a essas funções rapidamente em comparação com a execução delas no corpo principal por meio de uma chamada de função ou código embutido.

As interrupções também serão disparadas apenas quando necessário, enquanto se codificado no corpo principal, o código será executado em cada iteração do loop while (1).

7. Use os melhores compiladores disponíveis

Os compiladores podem implementar automaticamente algumas das otimizações discutidas acima enquanto traduzem o código da linguagem C para a linguagem assembly, se configurados corretamente. Procure por opções de otimização em seu compilador e, se possível, atualize para versões profissionais de compiladores porque eles são otimizadores de código mais poderosos.

8. Use declarações condicionais de forma inteligente

  • Ao usar uma série de instruções if-else, mantenha a condição mais provável primeiro. Dessa forma, o MCU não terá que varrer todas as condições após encontrar a condição verdadeira.
  • Uma instrução switch-case é geralmente mais rápida do que um if-else.
  • Use instruções if-else aninhadas no lugar de uma série de instruções. Um bloco if-else com muitas instruções pode ser dividido em sub-ramos menores para otimizar para a condição de pior caso (última).

9. Use funções embutidas

As funções que devem ser usadas apenas uma vez no código podem ser declaradas como estáticas. Isso fará com que o compilador otimize essa função para uma função embutida e, portanto, nenhum código de montagem será traduzido para a chamada de função.

  • Uma função pode ser declarada inline usando a palavra-chave 'estática' com ela.

10. Use Loops Decrementados

Um loop decrementado irá gerar menos código de montagem em comparação com um loop incrementado.

Isso ocorre porque em um loop de incremento, uma instrução de comparação é necessária para comparar o índice do loop com o valor máximo em cada loop para verificar se o índice do loop atinge o valor máximo. Ao contrário, em um loop de decremento, essa comparação não é mais necessária porque o resultado decrementado do índice do loop definirá o sinalizador de zero em SREG se chegar a zero.

Dado que o loop deve iterar cem vezes, reduzir uma instrução do loop evitará que ele seja executado cem vezes, de modo que o impacto provavelmente será mais significativo quando o loop tiver que iterar muitas vezes.

Empacotando

Essas dicas podem ser úteis, mas sua verdadeira aplicação e potência dependem da habilidade do programador e do comando que ele possui em seu código. Lembre-se de que o tamanho do programa nem sempre determina os tempos de execução, algumas instruções podem consumir mais ciclos de clock do que outras, portanto, mais uma vez, as habilidades do programa devem fazer sua parte.

Este artigo é preciso e verdadeiro, de acordo com o melhor conhecimento do autor. O conteúdo é apenas para fins informativos ou de entretenimento e não substitui aconselhamento pessoal ou consultoria profissional em questões comerciais, financeiras, jurídicas ou técnicas.

Recomendado

Nós Recomendamos

EcoStruxure Power Monitoring Expert: Análise de um engenheiro
Computadores

EcoStruxure Power Monitoring Expert: Análise de um engenheiro

O autor é um engenheiro de gerenciamento de in talaçõe onde a ver ão mai recente do Power Monitoring Expert foi implementada com uce o.O Eco truxure ™ Power Monitoring Expert (PME)...
Mais de 100 legendas engraçadas do Instagram para meninas
Internet

Mais de 100 legendas engraçadas do Instagram para meninas

Cheeky Kid é um cibernauta que pa a muito tempo navegando na web, obtendo informaçõe infinita e e divertindo com entretenimento e diver ão.Nem toda a menina ão feita de aç...