Manual

do

Maker

.

com

Tabela de partições no ESP32

Tabela de partições no ESP32

Como já citado por diversas vezes anteriormente, o ESP32 roda um sistema operacional de tempo real. A estrutura de um RTOS é completamente diferente de um sistema operacional convencional, mas no caso do FreeRTOS do ESP32, você conta com um sistema de arquivos, onde pode guardar arquivos de configuração do tipo .ini por exemplo. Mas não só isso; ele conta também com uma tabela de partições, que permite assim ter mais de uma aplicação instalada na flash.

Características da tabela de partições no ESP32

A primeira coisa que você deve saber é que a tabela de partições é gravada no endereço 0x8000 da flash. Seu tamanho é de 0xC00 bytes, suportando até 95 entradas.

Cada entrada na tabela de partições recebe um label (um nome), um tipo (aplicações dados etc), subtipo e o offset one a partição é carregada.

Em breve veremos como programar o ESP32 em outra IDE, daí montaremos o ESP-IDF. Nele, podemos configurar previamente uma tabela de partições pré-definida para, por exemplo, fazer instalação do firmware via OTA. Para isso, usaremos (lá no futuro artigo) o comando tradicional do Linux, make menuconfig.

A aplicação é instalada de qualquer modo no endereço 0x10000.

Uma tabela de partições sem suporte a OTA tem um formato semelhante a esse:

# Espressif ESP32 Partition Table
# Name,   Type, SubType, Offset,  Size
nvs,      data, nvs,     0x9000,  0x6000
phy_init, data, phy,     0xf000,  0x1000
factory,  app,  factory, 0x10000, 1M

No endereço 0x10000 (64K) o label da partição app é chamada "factory" e o bootloader rodará essa aplicação por padrão.

Subi um sketch vazio para mostrar a saída do upload para o ESP32 nos endereços supracitados:

esp32-flashing.png

Como você pode notar, a IDE do Arduino grava a aplicação e o bootloader. Com OTA, a tabela de partição fica mais ou menos assim:

# Espressif ESP32 Partition Table
# Name,   Type, SubType, Offset,  Size
nvs,      data, nvs,     0x9000,  0x4000
otadata,  data, ota,     0xd000,  0x2000
phy_init, data, phy,     0xf000,  0x1000
factory,  0,    0,       0x10000, 1M
ota_0,    0,    ota_0,   ,        1M
ota_1,    0,    ota_1,   ,        1M

Agora repare que existem 3 definições de partições para o tipo app, que se inicia no endereço 0x10000, cada uma delas com 1M. Repare também que temos agora uma partição chamada otadata, que é onde se armazena o firmware transmitido via OTA. O bootloader consulta esse dado pra saber qual aplicação deverá executar. Se essa partição estiver vazia, executa a aplicação que está gravada em factory, como um boot normal.

Futuramente veremos como criar nossa própria tabela de partições para o ESP32, mas já tenha em mente que:

  • Espaços entre campos são ignorados.
  • Cerquilhas são comentários (#).
  • Apenas o ponteiro para a primeira partição é fornecida (0x10000). A ferramenta que gerenciará a manipulação se encarrega de apontar o offset para a próxima partição baseada na anterior.
  • Nomes devem conter no máximo 16 Bytes.
  • O campo de partição pode ser especificado como app (0) ou data (1). para outra coisa, pode ser um valor até 254 (0xFE).
  • Se sua aplicação precisar armazenar dados, você pode adicionar um partição entre 0x40 e 0xFE.
  • O bootloader ignora quaçquer partição diferente de dataapp.

Subtipo app

Quando o tipo for app, o campo de subtipo pode ser especificado como factory (0), ota_0 (0x10) e ainda até ota_15 (0x1F).

factory (0) é a partição padrão da aplicação e ela será chamada pelo bootloader sempre, exceto existam dados na partição OTA (se houver uma, claro). Qualquer atualização OTA não sobrescreve a partição factory, de modo que você pode apagar apenas os dados da partição OTA para voltar o comportamento antigo. Isso pode ser muito importante para testar novas versões da sua aplicação.

Se desejar fazer OTA com seu ESP8266, escrevi alguns artigos a respeito. Eles estão concetrados nesse artigo. Não se preocupe, o processo é simples e seguro. Estou discorrendo sobre a tabela de partições apenas para termos conhecimento de causa, que é muito melhor que fazer as coisas às escuras e contar apenas com a sorte.

Se tiver confiança o suficiente na sua atualização, ou se o ESP estiver do seu lado, você pode optar por remover a partição factory.

Se for utilizar OTA, as partições ota_0ota_1 são ambas necessárias. Veremos os detalhes em outro artigo.

Subtipo data

Para data, os subtipos poem ser especificados como ota (0), phy (1), nvs (2). A partição ota é a partição que armazena informações sobre a aplicação que for transferida over-the-air e ela deve ter 0x2000 Bytes de tamanho.

Sobre a phy confesso que não está claro pra mim ainda. Já a nvsé para armazenamento não-volátil, utilizada para armazenar calibrfação de dados. Ele também é usado para armazenar as configurações do WiFi, por exemplo e ela pode ser utilizada para outros dados de aplicação.

A recomendação (pela documentação do ESP-IDF) é que a partição NVS tenha no mínimo 0x3000 Bytes no projeto e se estiver utilizando-a para armazenar muitos dados, utilize o tamanho padrão de 0x6000 Bytes.

Outros tipos de subtypes são reservados para uso futuro, ou seja, ainda tem coisa por implementar no ESP32 e a diversão deve aumentar!

Offset e tamanho

Somente o primeiro offset é requerido para dados, recomendado pela documentação utilizar o endereço 0x10000. Partições com offset em branco serão colocadas após a partição prévia. Deixando em branco também o offset da primeira partição de dados, ela será automaticamente alinhada pela ferramenta de gravação no endereço correto. Especificar um alinhamento errado da partição retornará um erro.

O tamanho dos offsets podem ser especificados como decial, hexadecimal ou multiplicadores de K ou M (1024 e 1024*1024 Bytes).

Gerando a tabela de partições binária

Assim como em qualquer sistema operacional, a tabela de partições é gravada em formato binário. O arquivo .csv que você pode gerar com os parâmetros de partições é apenas uma referência. Fazendo-a pelo ESP-IDF (especificando no menu do make menuconfig), você pode criar a tabela de partições posteriormente com o comando make partition_table. Mas também é possível fazê-lo manualmente:

python gen_esp32part.py --verify input_partitions.csv binary_partitions.bin

E o mais legal é que dá pra converter a tabela em .csv:

python gen_esp32part.py --verify binary_partitions.bin input_partitions.csv

Ou simplesmente mostrar seu conteúdo na saída padrão (vulgo stdout):

python gen_esp32part.py binary_partitions.bin

O parâmetro --verify faz a verificação da tabela durante a conversão para garantir não haver erros. ainda pelo ESP-IDF, você pode gravar a nova tabela de partições com o comando make partition_table-flash. Ou fazer o flashing de tudo, com o comando make flash.

A tabela de partições de qualquer sistema é apenas uma referência para os respectivos endereços de dados e sistema. Gravar uma tabela de partições não apaga quaisquer dados pré-existentes. Para isso, use make erase_flash do ESP-IDF ou se estiver utilizando o esptool.py, utilize o parâmetro erase_flash.

Bem, esse artigo foi criado como precedente do artigo sobre o SPIFFS, o sistema de arquivos da Espressif, que utilizaremos para gravar arquivos dentro do ESP32 como fazemos em qualquer sistema operacional. Se tiver um ESP8266 e deseja gravar arquivos nele também, sugiro esse outro artigo. Hora de escrever sobre o SPIFFS, espero que acompanhe!

Inscreva-se no nosso canal Manual do Maker no YouTube.

Também estamos no Instagram.

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.