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 é Bootloader?
O Bootloader é um programa inicializador e 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:
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
Feito isso agora pode-se utilizar a opção: Sketch -> Upload Using Programmer
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:
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:
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:
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 Bootloader
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.
Há, outra dúvida, uma vez gravado o bootloader ele fica permanente mesmo q envio outras aplicações para o mesmo?
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
Como saber se o bootloader foi gravado no atemega328 ? Tem como gravar o mesmo na propria IDE ?
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
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.
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
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?
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
Muito bem explicado, simples que é essencial para o aprendizado de iniciantes como eu.
Valeu Matheus, parabéns!
Olá, Garcia!
Que bom que curtiu! 😀
Abraços!
Diogo – Equipe MakerHero
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.
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
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
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?
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.
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?
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!
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 !
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