Nesta aula, aprenderemos o que é um firmware e quais são os softwares utilizados para programar um AVR e um PIC (IDEs).

Na aula anterior, aprendemos sobre a arquitetura dos microcontroladores e as características do AVR e do PIC.

Informações básicas

Os dispositivos eletrônicos podem ser divididos em 3 partes: hardware, firmware e software. Mas, não necessariamente, um dispositivo eletrônico possuirá as 3 partes. Vamos entender o que cada termo significa.

Hardware

É a parte física do sistema, que engloba o circuito do dispositivo.

Pegando o exemplo de um computador, o hardware seria a placa mãe (com processador, memórias, circuitos de controle…), a placa de vídeo, o HD etc…

Firmware

O firmware é o código executado por microcontroladores/microprocessadores que realiza um controle baixo nível do hardware. Isto é, o firmware mantém um controle direto com o hardware do equipamento. Além disto, ele é feito para ser executado especificamente em um determinado microcontrolador/microprocessador.

Para entender este último ponto, é só lembrar das últimas aulas onde vimos que o AVR e o PIC possuem muitas diferenças de funcionamento e principalmente diferentes instruções do processador. Então um firmware que executa no AVR não funciona no PIC (apenas com adaptações).

Um detalhe interessante de ser falado é que normalmente o firmware de um dispositivo é armazenado em uma memória ROM (FLASH).

Software

O software é um código que não interage com o hardware diretamente. Por conta disto, ele pode ser executado, sem alterações, em diversos dispositivos com microprocessadores diferentes.

Normalmente se fala de software em sistemas operacionais, pois eles são programas feitos para rodar nestes sistemas operacionais. Entretanto, o sistema operacional pode ser considerado também um software no sentido de poder funcionar em diversas máquinas com microprocessadores diferentes.

Pegando o exemplo de um computador, todos os programas que você executa são softwares: navegador, bloco de notas, calculadora, editor de imagens, jogos etc… Mas todo computador tem um firmware para fazer a gerência e o controle do hardware, que recebe o nome de BIOS.

Firmware

Tendo em vista os conceitos abordados no tópico anterior, fica um pouco mais claro entender que nós iremos desenvolver FIRMWARES para os microcontroladores.

Seria possível desenvolver um software para um microcontrolador, mas, antes, precisaríamos criar um firmware que faria uma abstração do hardware para o software que iríamos desenvolver. Com isto, o software executaria apenas tarefas alto nível.

Por exemplo, um vídeo-game com microcontrolador. O firmware faria a gerência e controle do hardware: tela, joystick, etc. E o software (um jogo no caso) apenas teria as instruções do jogo: desenhar um sprite, executar ação se um botão for pressionado etc.

De todo modo, neste curso abordaremos apenas o desenvolvimento de firmwares. Enfim, vamos entender alguns pontos sobre eles.

Camadas de abstração

Na aula 2, no tópico “Instruções de um microprocessador”, foi apresentado a linguagem Assembly e alguns conceitos de abstração. Agora, veremos estes assuntos com mais detalhe. Veja a imagem abaixo para entender como um código pode ser estruturado em um dispositivo.

Firmware - Niveis de abstração

O Hardware é o nível mais baixo de abstração possível, pois é ele que faz a interação direta com o mundo físico. Acima dele temos o código de máquina que são as instruções interpretadas pela CPU (códigos binários). Só então temos a camada do Assembly, que é a forma mais direta de se programar um dispositivo. Isto porque, os comandos presente em Assembly (LDI, ADD, NOP) são convertidos diretamente em instruções da CPU.

A partir disto, temos as linguagens de programação médio e alto nível. Um código escrito em alguma delas, com exceção da manipulação dos periféricos, pode ser utilizado em diversos microprocessadores/microcontroladores diferentes. Portanto estas linguagens possuem portabilidade e seus códigos podem ser reusados em diferentes plataformas.

Por exemplo, um código em Python deve ser capaz de ser executado em qualquer computador que possua o Python instalado. Mas é claro que, num contexto de firmware, isto se aplica apenas à estrutura geral do código, pois cada microcontrolador possuirá uma forma diferente de interagir com os periféricos.

Quanto maior o nível de abstração da linguagem, menos otimizada ela é. Isto porque, na hora da linguagem ser transcrita para os códigos em Assembly (pelo compilador), algumas redundâncias podem ser adicionadas. Com isto, o código fica mais lento e extenso do que o ideal. E, como algumas linguagens são escritas utilizando outras, como é o caso de uma das implementações do Python (escrito em C), podem aparecer mais redundâncias ainda.

Linguagens recomendadas

É possível desenvolver o firmware para o microcontrolador em diversas linguagens diferentes. Mas, tendo em vista o que foi falado no tópico acima, algumas são mais adequadas que outras.

Como os microcontroladores 8 bits (foco do curso) possuem limitações de velocidade e memória, o caminho preferível é o Assembly ou o C. Há quem defenda a utilização do Assembly em casos gerais, mas programar em C atende perfeitamente bem a grande maioria dos casos.

Um caminho mais adequado para quem precisar fazer um código perfeitamente bem otimizado é programar em C, gerar o código Assembly e depois otimizar o código Assembly removendo as redundâncias.

Por conta disto, iremos trabalhar com C ao longo do curso. Mas nada te impede de criar um código em outra linguagem. Até porque as outras linguagens podem trazer diversas vantagens não encontradas no C.

Estrutura do firmware

Por definição, um firmware possui uma inicialização e um corpo principal. O corpo principal é uma rotina que fica sendo executada repentinamente e o firmware nunca é finalizado.

Esta é outra diferença entre firmware e software, pois o software possui finalização. Por exemplo, uma calculadora física e um software de calculadora: o software de calculadora pode ser fechado a qualquer momento. Já no caso da calculadora física, o firmware fica sendo executado constantemente e a única forma de finalizar ele é desligando o equipamento.

Enfim, a estrutura do firmware está ilustrada no fluxograma abaixo.

Este tipo de estrutura ou arquitetura é chamado de “Super Loop”. A inicialização deve conter instruções que serão executados apenas ao ligar o equipamento, que servem para configurar periféricos e parâmetros internos.

E, o corpo principal deve conter instruções que fazem parte do funcionamento normal do equipamento. Exemplo: ler botões, escrever no display, acionar motor etc. O corpo principal pode seguir a seguinte organização:

  1. Ler status de periféricos/sensores.
  2. Fazer cálculos.
  3. Tomar ação baseado nos cálculos.

Este será o modelo que seguiremos para desenvolver os firmwares nas aulas futuras.

Bootloader

Na aula passada, vimos que a memória de programa do AVR possui um espaço chamado “Boot” conforme a imagem abaixo.

Alguns PICs também possuem um espaço de Boot.

Mapa da memória flash do AVR

O boot nada mais é do que um espaço de memória que é executado logo quando o microcontrolador é energizado. Ou seja, é possível criar um firmware “adicional” para ser armazenado neste espaço de memória. E um código criado neste espaço é chamado de bootloader.

Um exemplo de bootloader é o do Arduino, que basicamente é um algoritmo feito para gravar a memória de programa a partir de comandos na entrada UART do microcontrolador. Acontece que, por padrão, é necessário utilizar os pinos do periférico SPI do AVR para programá-lo. E o bootloader permite que esta gravação seja feita de uma forma mais prática (pela UART).

Este é o motivo de ser interessante existir o boot, já que, neste caso, não precisamos nos preocupar com ele toda vez que formos programar o Arduino. Isto porque, uma vez gravado, o bootloader permanece no espaço de memória dele sem que o programa principal o apague.

Ambiente de Desenvolvimento Integrado (IDE)

Agora que entendemos que vamos desenvolver firmware utilizando a linguagem C, podemos falar sobre os softwares padrões utilizados no caso do AVR e do PIC. Ambos são gratuitos.

AVR

[Atualização em agosto de 2021] Aparentemente, a Microchip resolveu encerrar o Atmel Studio e lançou uma nova plataforma para programar o AVR. Agora, o nome da IDE “oficial” é Microchip Studio. Futuramente atualizarei os posts do site com um tutorial ensinando a utilizá-la. Por enquanto, o site apresenta tutoriais para o Atmel Studio.

No caso do AVR, a IDE utilizada é o Atmel Studio. Portanto, se você deseja aprender a programar o AVR, baixe ele. Em outra aula aprenderemos a utilizá-lo.

Obs.: No próprio site de download, o Atmel Studio é chamado de IDP (Plataforma de Desenvolvimento Integrado).

Conhecendo a IDE Atmel Studio – Aula 4.1.1 – MC

PIC

No caso do PIC, a IDE utilizada é o MPLAB X. Além do MPLAB X, é necessário instalar o compilador a parte. Para o caso dos PIC 8 bits, o compilador que você deve baixar é o XC8.

Portanto, se você deseja aprender a programar o PIC, baixe o MPLAB X e o compilador. Em outra aula aprenderemos a utilizá-lo.

Conhecendo a IDE MPLAB X – Aula 4.1.2 – MC

Observações finais

Esta aula foi mais complementar e serviu para fechar alguns conceitos abordados nas aulas anteriores, para, então, começarmos a programar o AVR/PIC.

Antes de seguirmos adiante com os assuntos do curso, iremos aprender a mexer nas IDEs. Para isto, irei fazer duas aulas diferentes, uma mostrando o Atmel Studio e outra mostrando o MPLAB X.