ÍNDICE DE CONTEÚDO
Quando você faz o download da SDK para esp8266 da Espressif, o bootloader disponibilizado é apenas no formato binário (boot_v1.7.bin) no qual impossibilita qualquer tipo de otimização.
O objetivo do nosso bootloader é apenas checar e carregar um dos dois binários na flash, no qual carregará primeiro o binário no endereço 0x81000, se não conseguir tentará carregar o binário no endereço 0x01000, se as duas tentativas falharem, então ficará em um loop piscando um led configurado no GPIO14.
O código fonte está bem comentado, então não vi a necessidade de descrever todos os detalhes do funcionamento, ate mesmo por que é pouco código.
Objetivo do Bootloader para ESP8266
Para que possamos ter um bootloader simples, rápido e costumável, esse bootloader foi criado com o objetivo principal era padronizar alguns produtos da Bintechnology, no qual segue a seguinte estrutura:
Quando o ESP8266 inicializar o nosso bootloader vai sempre tentar carregar a aplicação APP2 (0x81000) que é a aplicação normal (nosso caso MODBUS/MQTT) com as funcionalidades do produto, onde que alterando uma flag que fica armazenada na RAM do RTC que por sua vez não é zerado quando for executado um Reset via software, então após Reset o nosso bootloader vai verificar essa flag setada pelo APP2 e vai carregar o APP1 (0x01000) que tem o proposito apenas de atualizar firmware (FOTA) através de uma aplicação Windows que carregar o novo firmware no endereço 0x81000, ou seja, atualizando o APP2, se acaso a atualização falhar e a placa for reiniciada o nosso bootloader não conseguirá carregar o APP2, e por isso carregará novamente o APP1 e ficará nesse modo até que o novo firmware no endereço 0x81000 for carregado com sucesso.
Processo de boot do esp8266
Quando o esp8266 é alimentado um firmware em ROM verifica os GPIO0, GPIO2, e GPIO15 e decide como inicializará:
- GPIO0=0,GPIO2=1,GPIO15=0 -> boot pela UART, modo atualização de firmware;
- GPIO0=1,GPIO2=1,GPIO15=0 -> boot pela FLASH, carregará o nosso bootloader;
Existem outros modos, mas não são necessários mencionar.
Como o firmware em ROM carrega o nosso bootloader
Após os GPIOs devidamente configurados para dar boot pela flash, o firmware em ROM verificará os primeiros 8bytes da flash endereço 0x00000 onde é necessário que exista um cabeçalho em um formato especifico da Espressif, por isso o nosso binário de bootloader que estará nesse endereço precisa obedecer esse formato no qual será descrito a seguir:
É importante mencionar que existe um pino especial para inicializar um modo de teste GPIO1 (UART TX), esse pino nunca pode ser inicializado com algum tipo de pulldown, senão o esp8266 entrará no modo “chip_test_mode”
Requisitos
toolchain xtensa-lx106-elf (v4.8.2)
não precisa da SDK para compilar o projeto
dados do cabeçalho:
flash_mode = 0:QIO
flash_clk_div = 0:80m/2
flash_size_map = 2:1024 KB (512 KB + 512 KB)
Observação
As duas aplicações APP1 e APP2 são baseadas na SDK 3.0.0.
Além do cabeçalho do bootloader cada aplicação tem seu próprio cabeçalho
Nesse caso é importante lembrar que flash_size_map=2 faz com que APP2 seja
no endereço 0x81000, no arquivo main.c do bootloader você pode alterar esse endereço se acaso você utilizar outro tamanho de flash.
Outra coisa importante é que a partir da SDK 3.0.0 é necessário configurar
a tabela de partições através da função “void ICACHE_FLASH_ATTR user_pre_init(void)”
e dentro dela chamar system_partition_table_regist(esp_patition_table,
sizeof(esp_patition_table)/sizeof(esp_patition_table[0]),
FLASH_SIZE_8M_MAP_512_512))
Todos os detalhes estão nas documentações da SDK
Você encontra o codigo fonte do bootloader no meu Gitihub: https://github.com/ezequieldonhauser/ESP8266_BOOTLOADER
Ezequiel, tudo bem? Esse bootloader me parece tudo que preciso. Estou usando a biblioteca HttpUpdater para atualizar meus sketches no ESP. Funciona muito bem, através do uploade de um .bin através do WebServer, que eu aciono através de http request. O problema é que se houver falha no momento da atualização, eu perco a função OTA, porque ela está dentro do sketch e não numa partição restrita e não editável. Eu precisava de mais informações sobre o seu projeto, porque só sei programar ESP pela interface do Arduino ou usando Lua/ESPlorer. Não sei por onde começar e não sei como… Leia mais »
Opa Então, esse projeto é bem simples unica coisa que voce precisa é do GCC pra compilar ele, esta descrito no REDME do projeto o nome e versao da toolchain utilizada. Sobre o projeto, oque ele faz é bem simples tbm, voce vai gravar ele no endereço zero da flash, quando ele for carregado ele vai decidir qual dos binarios carregar, APP1, ou APP2, voce pode alterar esses detalhes pra sua aplicação, no arquivo main.c voce encontra os endereços dos binarios, voce pode colocar eles onde quiser. Como ele decide qual binario executar? tem uma struct de dados que é… Leia mais »
Parabéns pelo conteúdo, realmente impressionante
Olá Ezequiel, parabéns pela publicação
fiquei com uma dúvida sobre o o cabeçalho, lá aparecem 4 bytes de flags mas você lista 5 flags
E9 (fixo)
02 (numero de partições)
Mas ai aparecem esses 3 flags
flash_mode = 0:QIO
flash_clk_div = 0:80m/2
flash_size_map = 2:1024 KB (512 KB + 512 KB)
Como essas 3 informações compõem os outros dois bytes (00 00)
Obrigado
Opa, então eu deixei dessa forma por que geralmente sempre vai ficar 00 00 mas na pratica ficaria da seguinte forma: flash_mode= 0: QIO 1: QOUT 2: DIO 3: DOUT flash_clk_div= 0 : 80m / 2 1 : 80m / 3 2 : 80m / 4 0xf: 80m / 1 flash_size_map= 0 : 512 KB (256 KB + 256 KB) 1 : 256 KB 2 : 1024 KB (512 KB + 512 KB) 3 : 2048 KB (512 KB + 512 KB) 4 : 4096 KB (512 KB + 512 KB) 5 : 2048 KB (1024 KB + 1024 KB)… Leia mais »
Perfeito, muito obrigado e novamente parabéns pelo artigo
[]s