Pra que serve um Bootloader? – Arduino UNO 19

Quem nunca escreveu um blink para o seu Arduino não é mesmo? E é realmente fácil programar o Arduino pelo IDE Arduino utilizando comunicação serial. Quando gravamos nosso Arduino um item muito importante entra em ação: o Bootloader. Nesse post vamos conhecer melhor as funcionalidades do Bootloader para o ATmega328 o microcontrolador, coração, do nosso querido Arduino.

O que é um bootloader

O Bootloader é um programa inicializador. Seu objetivo geralmente é de preparar o hardware para o funcionamento correto da nossa aplicação e/ou aplicar atualizações dessa aplicação. No caso do Arduino quando o ligamos a energia, ou pressionamos o botão de reset, o primeiro programa a ser executado é o Bootloader. O principal objetivo desse pequeno programa inicial no Arduino é de verificar e receber um novo Sketch do Arduino IDE desenvolvido no seu computador, e grava-lo na memória do microcontrolador. Isso ocorre facilmente pela porta serial USB do Arduino. Sem o Bootloader isso não seria possível, teríamos que recorrer a um hardware programador para o ATmega328. Nos tópicos abaixo vamos verificar as opções que temos para realizar um upload de sketch para nosso Arduino bem como as funcionalidades de dois Bootloaders utilizados para o ATmega328.

As formas de programar um Arduino

Há três formas de programar o ATmega328: utilizando o protocolo de alta voltagem Parallel Programming, utilizando ISP (In System Programmer) e o Self Programming. Nesse post vamos abordar um pouco dos dois últimos métodos que são os mais utilizados por nós Makers. O protocolo de alta voltagem Parallel Programming é mais aplicado na indústria quando se tem uma grande quantidade de microcontroladores a serem gravados simultaneamente.

ISP – In System Programmer

Para utilizar o ISP é preciso um programador, hardware dedicado ou microcontrolador programado para esse fim, esse programador vai se comunicar via SPI (Serial Peripheral Interface) com o ATmega328, enviar os dados do programa e o ATmega328 irá receber isso e gravar em sua memória flash. Esse processo já está implementado dentro do chip do ATmega328 então não é necessário ter um Bootloader gravado no chip de antemão. Na imagem abaixo um exemplo utilizando o programador USBasp com as conexões ISP conectadas ao socket do gravador:

Gravador ICSP Arduino

Para enviar os dados do programa utilizando esse esquema ao programador com a IDE do Arduino você primeiro deve selecionar o tipo do programador: Tools -> Programmer -> USBasp

Menu IDE Arduino USBasp

Feito isso agora pode-se utilizar a opção: Sketch -> Upload Using Programmer

Menu IDE Arduino USBasp

Essa opção ira gravar seu sketch do Arduino IDE utilizando o USBasp, ou seu programador ISP selecionado na opção anterior. Você pode até mesmo utilizar um outro Arduino como programador ISP, mas isso é assunto para um outro post. 

Self Programming – Bootloader

Self Programming como o próprio nome já diz é a forma em que o próprio microcontrolador se programa. Sem precisar de um hardware dedicado ele utiliza recursos e periféricos próprios para receber dados de uma nova programação e gravá-la. Mas pra isso o microcontrolador tem de saber que periféricos, recursos inicializar e implementar um protocolo para receber e gravar essa nova programação. Quem faz o Self Programming é o famoso Bootloader, que sabe e implementa como receber e gravar novos programas na memória flash de seu próprio ATmega328.

O ATmega328 possui 32Kbytes de memória flash no seu chip para armazenamento de programas e pode-se configurar essa memória em duas seções:

Diagrama de blocos memória

A seção de memória da Aplicação (Application Flash Section) é aonde será armazenada o sketch do seu Arduino, e a seção Boot Flash é aonde ficará armazenada a programação do Bootloader. Essa configuração em seções ainda possibilita que o ATmega328 ative a funcionalidade de RWW (Read While Write) na seção de aplicação, essa funcionalidade possibilita que o código do Bootloader grave a programação na memória flash de forma mais rápida. Por exemplo: sem essa funcionalidade a CPU do ATmega328 leria uma instrução de armazenamento em memória e a CPU teria que ficar em espera até que o processo de armazenamento terminasse, para assim poder ler e executar a próxima instrução, sendo que a memória estaria ocupada. Com o RWW a CPU consegue ler a instrução de armazenamento executa-la e ficar livre para ler e executar a próxima instrução na sessão de Boot Flash, porque foi definido que estamos executando código de outra sessão, que está livre, e não estamos necessariamente usando a mesma memória já que estão divididas em sessões.

Bootloader – Código Fonte

Se você ficou curioso para ver como é o código do Bootloader, saiba que ele está mais próximo do que você pensa. O código fonte e arquivos .hex para upload das diferentes versões do Bootloader vem junto com o Arduino IDE na pasta:

arduino-1.8.7/hardware/arduino/avr/bootloaders

Eu estou usando a versão 1.8.7, lembrando que se você estiver usando outra versão o nome da pasta vai estar diferente. Nesse postvamos dar destaque as pastas:

arduino-1.8.7/hardware/arduino/avr/bootloaders/atmega
arduino-1.8.7/hardware/arduino/avr/bootloaders/optiboot

Essas duas versões de Bootloader podem ser utilizadas no ATmega328 e são baseados no trabalho de Jason P. Kyle (stk500boot.c). Sendo assim implementam parte do protocolo STK500 da Atmell. O STK500 é um protocolo que consiste em uma serie de comandos e respostas, todas elas em ASCII padrão, para troca de dados e execução de tarefas, esse protocolo que é utilizado para que o Arduino IDE e o Bootloader se entendam e façam o upload corretamente do seu sketch.

bootloaders/atmega

Essa versão do Bootloader foi utilizada nas primeiras versões do Arduino:

Versões Placas Arduino

Ele implementa parte do protocolo STK500, seguem algumas características:

  • Utiliza baixa taxa de transmissão serial: 57600;

  • Ao inicializar realiza o blink do led 13 somente uma vez;

  • Lê e escreve da EEPROM;

  • Ocupa 1950 bytes do Boot Flash Section;

Depois de compilado, gerando o arquivo ATmegaBOOT_168_atmega328.hex, o Arduino IDE ira realizar o upload e configurar as seções de Boot Flash para 2048 bytes, sobram ainda 98 bytes para eventuais melhorias e funcionalidades, e o Application Flash fica com 30720 bytes para armazenar seus sketches.

bootloaders/optiboot

Essa é a versão de Bootlaoder padrão, ela já vem embarcada de fábrica nos ATmega328P dos Arduino UNO. O Optiboot, como o próprio nome sugere, é uma versão otimizada do Bootloader, e foi baseada também na versão bootloaders/atmega que comentamos acima. Ela tem somente o necessário para realizar o upload do sketch, é uma versão bem enxugada do STK500. Seguem algumas características:

  • Utiliza alta taxa de transmissão serial: 115200;

  • Taxa de transmissão mais alta logo temos o upload do sketch mais rápido;

  • Menor timeout entre entrada do Bootloader e salto para aplicação;

  • Ao inicializar realiza o blink do led 13 três vezes;

  • Ocupa míseros 502 bytes do Boot Flash Section;

  • Com leitura e escrita da EEPROM habilitada ocupa 736 bytes;

Depois de compilado, gerando o arquivo optiboot_atmega328.hex, o Arduino IDE ira realizar o upload e configurar as seções de Boot Flash para 512 bytes, sobram ainda 10 bytes, e o Application Flash fica com 32256 bytes para armazenar seus sketches.

O Optiboot também implementa escrita e leitura da memória EEPROM, mas nesse caso ela ocupa mais espaço, assim tendo que configurar o Boot Flash section para 1024 bytes deixando livre 31744 bytes, mesmo assim gastando metade do armazenamento do bootloaders/atmega.

O Optiboot tem uma comunidade ativa de desenvolvimento e utiliza o Github como plataforma para sugestões de melhorias e relatos de erros: https://github.com/Optiboot/optiboo

Processo de Boot

Os dois bootloaders mencionados acima utilizam mais ou menos o mesmo fluxo, ou ideia de fluxo, para realizar o boot e verificar se há um novo programa a ser feito o upload:

Fluxograma sequência de boot

Assim que o microcontrolador recebe energia, ou é resetado, executa-se o código no endereço  do Boot Flash section. Esse código inicializa o output do pino 13, para dar aquele blink rápido quando ligamos a placa, a UART e verifica se está recebendo via serial algum comando do protocolo STK500, caso ele receba algum comando implementado ele executa o comando, transfere os dados e manda as respostas do protocolo. Caso ele não receba nenhum comando, e ele fica em loop lendo a serial por comandos por algum tempo, então ele salta para o endereço do Application Flash Section e executa nosso sketch.

Prós e Contras

Utilizar um Bootloader tem muitas vantagens, a primeira e um dos motivos ao qual eu costumo creditar o sucesso da plataforma Arduino é a facilidade de programação do microcontrolador sem necessidade de um hardware externo programador, o Arduino já vem com todos os recursos para realizar a programação, e o Bootloader é uma ferramenta de software essencial.

Em contrapartida, como nem tudo são flores, perdemos aquele espaço que é do  Boot Flash section que só servira para o Bootloader.

Conclusões sobre o Bootloader

Não há dúvidas que o Bootloader é útil. E é importante ao Maker conhecer e estudar essa peça de software. Eu recomendo que comece seus estudos com o bootloaders/atmega. Na minha opinião ele é mais fácil de se entender e customizar. O Optiboot tem alguns truques para minimizar ao máximo seu tamanho e necessita de uma compreensão maior e estudo da arquitetura AVR.

Caso seu projeto precise de opções de boot customizadas. Você pode customizar seu Bootloader, por exemplo, para realizar atualizações da sua aplicação remotamente via WiFi utilizando o ESP32.

Caso seu projeto precise de mais espaço de armazenamento aqueles 512 bytes podem fazer a diferença. Em um caso desses você pode optar por embarcar sua solução sem Bootloader para ganhar espaço.

Tudo depende daquilo que se pretende alcançar com seu projeto. Conhecendo suas ferramentas fica fácil tomar a decisão e implementar sua solução. Gostou? Deixe seu comentário logo abaixo.

Faça seu comentário

Acesse sua conta e participe

19 Comentários

  1. Há, outra dúvida, uma vez gravado o bootloader ele fica permanente mesmo q envio outras aplicações para o mesmo?

    1. Olá!

      Sim, ele fica permanente a menos que use o procedimento de gravação de um novo bootloader.

      A gravação dos sketches através da IDE do Arduino não altera o bootloader.

      Abraços!
      Vinícius – Equipe MakerHero

  2. Como saber se o bootloader foi gravado no atemega328 ? Tem como gravar o mesmo na propria IDE ?

    1. Olá!

      Uma forma é colocar um LED no pino 19 do atmega328 (equivalente ao pino 13 do Arduino Uno).
      Ao alimentar o atmega, se ele piscar 3 vezes, há o bootloader gravado.

      É possível sim gravar na própria IDE, mas você precisa de um programador externo (que pode ser até outro Arduino).
      Aqui você pode conferir instruções de como é o procedimento: https://www.arduino.cc/en/Tutorial/BuiltInExamples/ArduinoISP

      Abraços!
      Vinícius – Equipe MakerHero

  3. Olá Matheus!!!!

    Tenho um dispositivo (adaptador redragon Ga 250) que conecto um mouse e um teclado nele, e do dispositivo conecto no USB do console PS4, para poder jogar qualquer jogo com mouse e teclado. O dispositivo funciona corretamente com um teclado USB conectado nele. Tenho um arduíno Leonardo que emula um teclado USB, fiz um teste no notebook e no PS4 e os dois reconhecerão o arduino como teclado e funcionou corretamente como teclado ou mouse.

    Minha dúvida e o seguinte, por que o dispositivo não está reconhecendo meu arduíno como teclado, sendo que no Notebook e PS4 reconhece?

    Andei pesquisando e me falaram que preciso programar sem esse Bootloader o arduino para poder ser reconhecido.

    desde já agradeço.

    Carlos Antonio de Mello Junior
    1. Olá Carlos,

      Provavelmente você terá que utilizar um programador externo para programar sem o bootloader, caso o bootloader seja a fonte do erro.

      É possível utilizar outro Arduino utilizando o exemplo Arduino as ISP.
      Neste link você pode ver como fazer as conexões: https://www.arduino.cc/en/Tutorial/BuiltInExamples/ArduinoISP
      E neste outro aqui, como programar usando um programador externo: https://www.arduino.cc/en/Hacking/Programmer

      Abraços!
      Vinícius – Equipe MakerHero

  4. Agradecida pela explicação.
    porém tenho uma inquietação.. eu tenho uma placa arduino UNO e gostaria de introduzir um programa num outro chip pela mesma placa e depois usa-lo para outro circuito fora da placa. Como facobpara conectar o novo chip a placa do adjunto e transferir o programa para este chip?

  5. Bom dia !
    Como fazer o arduino MEGA se portar como um controlador de jogos? Ou seja quando liga-lo a uma porta USB em
    um computador, ele sera reconhecido como um controlador de jogos (joystick) e nao como um arduino >

    Obrigado,

    Jeovan

  6. Muito bem explicado, simples que é essencial para o aprendizado de iniciantes como eu.
    Valeu Matheus, parabéns!

    1. Olá, Garcia!

      Que bom que curtiu! 😀

      Abraços!
      Diogo – Equipe MakerHero

  7. Muito obrigado por suas dicas, pena que não deu nenhum exemplo de como fazer atualizações de uma aplicação remotamente via WiFi utilizando o ESP32.

    1. Olá Edilson,

      Esse é um tutorial introdutório. Atualizações de uma aplicação remotamente via WiFi utilizando o ESP32 seria um tutorial vai avançado.

      Abraço!
      Rosana – Equipe MakerHero

  8. Matheus, Boa tarde, primeira das muitas duvidas que tenho, rsrsrs.
    Estou envolvido em um projetinho pessoal (simulador aeronaltico e que precizarei de muitas IO´S, até o momento serão 7 leonardos (precizo de 42 portas analogicas para os comandos proporcionais , mais um monte de botoes onoff , um Mega e um uno, perfazendo um total de 9 boards. entao la vai meu primeiro problema.
    Todos os leonardos sao reconhecidos como joystics, porem todos tem o mesmo nome, e pra atrapalhar o pid e vid mudam , exemplo, o 1 de agora não sera o 1 de um proximo boot do pc, eles mudar de vid entre si… então como faco para que o leonardo 1 seja renomeado e sempre reconhecido por exemplo joy-01, joy-02 assim por diante.
    Essa e a primeira depois te mando mais…. kkkk

  9. Preciso realizar a atualização de firmwares através de um cabo serial (rx,tx,gnd). Há algum bootloader específico para tal aplicação?

    1. Olá Gabriel,

      em geral o Bootloader padrão que vem no ATMega328 já está preparado pra isso.
      Conecte os pinos do serial em um conversor serial para usb e utilize a IDE do Arduino ou a IDE de sua preferência.

      1. Primeiramente, muito obrigado, Matheus, pela resposta imediata!

        Testei e não funcionou. A ligação está da seguinte maneira:
        Rx_CaboSerial—->Tx do Atmega
        Tx_CaboSerial—->Rx do Atmega
        GND_Cabo_Serial—–>Gnd do Atmega

        Estou usando o Atmega em uma pcb que possui um max232 para realizar a comunicação via serial; acredito que talvez o problema esteja na falta de resetar o microcontrolador, o que faz com que esse não entre no “modo bootloader”.

        O que você acha? Além disso, seria possível realizar a ligação desse cabo serial diretamente em um Arduino Uno (tx e rx) para verificar se realmente o bootloader é capaz de permitir esse tipo de atualização de firmware?

        1. Olá Gabriel,

          acho que é isso mesmo, a sua sacada sobre o reset. Faça o reset manualmente e tente fazer o upload.

          Sobre a ligação em um UNO, nunca testei pessoalmente, mas teoricamente é pra funcionar como funciona em um “Arduino” standalone. Os pinos de RX e TX estão na trilha direto no ATMega328, então teoricamente seria a mesma coisa.

          Qualquer coisa estamos ai.
          Abraços!

  10. Há algum vídeo que demonstra o procedimento de upload de programa aplicativo sem uso de bootloader ? Sabe como é, MEMÓRIA ainda é tudo em programas de controle industrial !

    1. Olá Wanderly,
      segue um vídeo sobre a utilização do mesmo esquema mostrado no post do ISP do Arduino: https://youtu.be/nsDfsj-385w