Executando NuttX em um ESP32 emulado com QEMU

Este post faz parte da série Primeiros Passos com o ESP32 e NuttX

Este artigo compõe a série Primeiros Passos com o ESP32 e o Apache NuttX. Uma série cujo objetivo é apresentar um overview do Sistema Operacional de Tempo Real Apache NuttX e prover instruções para utilizar o Apache NuttX no ESP32.

Caso você esteja iniciando no universo Apache NuttX, é recomendada a leitura deste artigo, no qual Sara Monteiro explica o processo de preparação do ambiente de desenvolvimento e descreve os passos necessários para compilar o Apache NuttX e fazer o upload do firmware para a memória Flash do ESP32.

Neste artigo, como o repositório oficial do QEMU não tem suporte ao ESP32, compilaremos o fork da Espressif do QEMU, configurar o NuttX para funcionar com o emulador e compilar um exemplo para demonstração. Vale notar que, apesar de existir uma variação do QEMU com suporte ao ESP32 desenvolvida pela Espressif, a empresa não oferece suporte oficial ao QEMU.

O que é QEMU ?

QEMU (de Quick EMUlator) é um software open source criado por Fabrice Bellard para a criação de ambientes de virtualização e emulação.

Em emulações, seu principal objetivo é executar sistemas operacionais e aplicações desenvolvidas para outra plataforma de hardware. Por exemplo, executar um software criado para a plataforma ARM em um computador baseado em x86.

Já em virtualizações, o QEMU emula dispositivos e instruções privilegiadas utilizando módulos de kernel (KQEMU ou KVM) e o ambiente de máquina virtual provido pelo sistema operacional. É tipicamente utilizado para executar o sistema Windows em computadores utilizando Linux.

Caso deseje saber mais, visite a página oficial do projeto.

Por quê utilizar QEMU ?

Uma das principais vantagens da utilização do QEMU é a possibilidade de testar um software sendo desenvolvido sem precisar adquirir o hardware necessário para executá-lo.

Além disso, outras vantagens incluem a depuração de problemas sem precisar de um conversor JTAG/Serial e a possibilidade de emulação com mais memória que no módulo físico correspondente.

Instalação

Pré-requisitos

Assumiremos aqui que o ambiente de desenvolvimento com Apache NuttX já esteja configurado conforme o passo a passo descrito no primeiro artigo da série utilizando o sistema Ubuntu 20.04 LTS. Além disso, assegure-se de que os repositórios nuttx e nuttx-apps estejam atualizados.

cd ~/nuttxspace/nuttx
git pull origin master
cd ~/nuttxspace/apps
git pull origin master

Primeiramente, precisamos instalar alguns pacotes necessários para a compilação do QEMU:

sudo apt install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev ninja-build libgcrypt-dev python3

Agora podemos prosseguir com o download do fork da aplicação QEMU. Nesse tutorial, clonaremos o repositório na pasta esp-qemu dentro do diretório home do usuário:

git clone https://github.com/espressif/qemu ~/esp-qemu

Com esses passos, temos tudo o que precisamos para a compilação do QEMU com suporte a processadores com arquitetura Xtensa.

Compilação

Com os arquivos preparados para a configuração e compilação, podemos configurar o sistema de compilação para selecionar as funcionalidades necessárias para o funcionamento do ESP32 (caso deseje saber mais sobre as opções de configurações disponíveis, execute ./configure --help dentro da pasta esp-qemu):

cd ~/esp-qemu
./configure --target-list=xtensa-softmmu \
    --enable-gcrypt \
    --enable-debug --enable-sanitizers \
    --disable-strip --disable-user \
    --disable-capstone --disable-vnc \
    --disable-sdl --disable-gtk

Após o processo de configuração ser concluído, podemos compilar a aplicação para gerar o executável do QEMU com suporte ao ESP32:

ninja -C build

Após concluída esta etapa, será gerado o executável qemu-system-xtensa na pasta build. Com o QEMU instalado, precisamos configurar nosso sistema NuttX para funcionar em conjunto com o QEMU.

Configuração do RTOS NuttX

Agora precisamos configurar a nossa aplicação para ter suporte ao QEMU. Como o emulador requer que as partições da memória estejam em um arquivo só, precisamos habilitar a configuração de fusão dos arquivos binários em apenas um.

Primeiramente, garanta que não exista nenhuma configuração aplicada no sistema NuttX:

cd ~/nuttxspace/nuttx
make distclean

Em seguida, podemos selecionar uma aplicação para ser compilada. Utilizaremos a aplicação NuttShell como exemplo a ser emulado.

./tools/configure.sh esp32-devkitc:nsh

Para a execução no emulador QEMU, precisamos alterar algumas opções de configuração. Acesse o menu de configuração:

make menuconfig

Dentro do menu, navegue para Board Selection e selecione a opção ESP32 binary image for QEMU. Salve e saia do menu.

NuttX QEMU
Figura 1: Seleção da opção de compilação para QEMU no NuttX.

Iremos, agora, gerar a imagem do sistema NuttX com a aplicação NuttShell para ser executada no emulador:

make ESPTOOL_BINDIR=../esp-bins -j

Caso os passos tenham sido seguidos corretamente, a mensagem Generated: nuttx.merged.bin (QEMU compatible) deverá ser exibida no fim da compilação.

Execução de Aplicações

Para executarmos nossa aplicação, precisamos voltar na pasta onde se encontra nosso executável do QEMU e rodá-lo com as configurações corretas para o ESP32:

cd ~/esp-qemu/build
./qemu-system-xtensa -nographic \
    -machine esp32 \
    -drive file=~/nuttxspace/nuttx/nuttx.merged.bin,if=mtd,format=raw

Caso tudo tenha ocorrido com sucesso, a aplicação será executada no terminal em um ESP32 emulado pelo QEMU:

NuttX QEMU
Figura 2: NuttShell sendo executado em um ESP32 emulado pelo QEMU.

Para encerrar a aplicação, aperte Ctrl-A e em seguida a tecla X.

Depuração usando GDB

Podemos também executar o emulador com o servidor do GDB ativo para podermos fazer debug no programa sendo executado. Para isso, precisamos primeiro instalar o GDB para o ESP32:

sudo apt install python2.7 libpython2.7-dev
wget -qO- https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/xtensa-esp-elf-gdb-12.1_20221002-x86_64-linux-gnu.tar.gz | tar -xvz
sudo mv xtensa-esp-elf-gdb/ /opt/xtensa/
echo "export PATH=\$PATH:/opt/xtensa/xtensa-esp-elf-gdb/bin" >> ~/.bashrc
echo "export QEMU_XTENSA_CORE_REGS_ONLY=1" >> ~/.bashrc
source ~/.bashrc

Agora podemos executar o QEMU esperando por uma conexão do GDB para debug:

./qemu-system-xtensa -nographic -s -S \
    -machine esp32 \
    -drive file=~/nuttxspace/nuttx/nuttx.merged.bin,if=mtd,format=raw

A emulação não será iniciada até uma conexão do GDB ser realizada. Para isso, executamos em um outro terminal o seguinte comando para executar o debugger:

xtensa-esp32-elf-gdb ~/nuttxspace/nuttx/nuttx \
    -ex "target remote :1234" \
    -ex "monitor system_reset" \
    -ex "tb app_main"

Com o GDB conectado, é possível adicionar breakpoints e watches para debug. Para continuar a emulação, basta executar o comando continue ou c.

NuttX QEMU
Figura 3: QEMU conectado com GDB executando o NuttShell.

Para uma depuração mais a fundo, não se esqueça de habilitar as opções de debug desejadas no menuconfig do NuttX.

Considerações Finais

Nesse tutorial você viu como instalar e utilizar o QEMU, executar o sistema NuttX em um ESP32 emulado e utilizar ferramentas de depuração no mesmo.

Para saber mais sobre as limitações de emular o ESP32 utilizando o QEMU ou possui alguma dúvida, acesse a wiki do fork.

Referências

Site Oficial QEMU: https://www.qemu.org/

Wiki QEMU Espressif: https://github.com/espressif/qemu/wiki

Documentação ESP-IDF: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-tools.html

Documentação NuttX: https://nuttx.apache.org/docs/latest/index.html

Primeiros Passos com o ESP32 e NuttX

Interpretador LUA com NuttX NuttX: Criando (ou Copiando!) uma Aplicação para o NuttX
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
2 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Matheus Catarino França
Matheus Catarino França
26/02/2024 16:58

Bacana! Funcionou tranquilo.
Isso também me lembrou a possibilidade de emular esp32 com nuttx também no picsimlab (qemu-fork integrado).

Nathan
Nathan
04/07/2023 15:00

Tutorial perfeito Lucas! Parabens, me ajudou bastante aqui!

Home » Software » Executando NuttX em um ESP32 emulado com QEMU

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: