Começando a usar o Renode para emulação de sistemas embarcados

O que é Renode?

Todas as oportunidades de otimização de processos durante o desenvolvimento de sistemas embarcados são bem vindas. Inclusive a emulação de máquinas para antecipar o desenvolvimento do software embarcado quando o hardware não estiver disponível, por ser uma fase inicial do projeto, ou quando seu uso for restrito, como é o exemplo de situações em que não há hardware disponível para todas as equipes trabalharem com ele.

Ao lado do QEMU e gem5, o Renode apresenta-se como mais uma das alternativas para emulação de sistemas. Os recursos disponíveis no Renode direcionam sua usabilidade para o uso com sistemas embarcados (enquanto QEMU é mais voltado para emulação de desktops e gem5 para uso acadêmico), sendo capaz de emular plataformas com núcleos de processamento com arquitetura ARM e RISC-V (x86, também) e, também, periféricos, como sensores e atuadores.

Nesse contexto, o Renode é uma poderosa ferramenta de desenvolvimento de sistemas embarcados, capaz de facilitar e agilizar o desenvolvimento, seja economizando recursos de hardware, ou antecipando problemas nas fases iniciais do projeto.

O objetivo deste tutorial é exercitar, de forma prática, o fluxo de execução mais básico para garantir que um binário de aplicação seja executado com o Renode.

Instalando o Renode

O Renode é distribuído gratuitamente na sua página do GitHub e possui alternativas de instalação para Windows, MacOS e distribuições Linux. Para este tutorial, será utilizada uma máquina Linux e o binário portátil do Renode, sem a necessidade de instalá-lo (na data de escrita deste artigo, a versão mais recente é a 1.15.3):

# baixar
$ wget https://github.com/renode/renode/releases/download/v1.15.3/renode-1.15.3.linux-portable.tar.gz
# descompactar
$ tar xf renode-1.15.3.linux-portable.tar.gz
# executar (você pode usar os argumentos --console --disable-gui ara abrir o renode no terminal atual, sem abrir um novo terminal)
$ exec renode_1.15.3_portable/renode

Também, como estamos tratando de uma máquina emulada que não terá qualquer contato com o mundo real por meio de conexões USB ou GPIO, poderá ser usado o WSL (Subsistema do Windows para Linux), contêineres Docker ou qualquer outro recurso que disponibilize as facilidades do Linux numa máquina Windows.

Preparando o binário a ser executado

O Renode suporta várias plataformas de hardware embarcado (STM, Nordic, Renesas, etc.). Uma lista das CPUs suportadas e das placas podem ser consultadas no GitHub. Desde que se use uma plataforma de hardware e funcionalidades suportadas pelo Renode, o binário em questão pode ser qualquer aplicação.

Vamos preparar um firmware exemplo com base na placa STM32F4 Discovery. Como o foco deste tutorial é o Renode, vamos simplificar o processo de compilação utilizando o core Arduino para a STM32F4 Discovery. Isso irá nos poupar de configurar todo o ambiente de compilação da STM. Além disso, para ficar mais fácil de seguir o tutorial, vamos usar a Arduino CLI, ao invés da Arduino IDE. Dessa forma, basta seguir os comandos listados aqui para preparar o binário.

Antes de tudo, será necessário baixar a Arduino CLI. A documentação oficial é bem direta acerca dos comandos para instalação. Basta executar o comando abaixo para instalar a arduino-cli no seu workspace (a pasta bin será criada pelo script de instalação):

$ curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
Installing in /home/user/workspace/bin
ARCH=64bit
OS=Linux
Using curl as download tool
Downloading https://downloads.arduino.cc/arduino-cli/arduino-cli_1.2.0_Linux_64bit.tar.gz
install.sh: arduino-cli not found. You might want to add "/home/user/workspace/bin" to your $PATH
arduino-cli  Version: 1.2.0 Commit: 9c495211 Date: 2025-02-24T15:57:30Z installed successfully in /home/user/workspace/bin

Tal como o propósito deste tutorial não é preparar um ambiente de compilação complexo; também não é desenvolver um firmware complexo. Dessa forma, um simples hello world será suficiente para testar o Renode.

$ bin/arduino-cli sketch new hello_world

// hello_world.ino
void setup() {
	Serial.begin(9600);
	while (!Serial);
	Serial.println("Hello, World!");
}
void loop() {}

Antes de compilar o firmware, usaremos a Arduino CLI para baixar os pacotes necessários para dar suporte à STM32F4, lembrando também de anotar o nome da placa (FQBN, ou Fully Qualified Board Name) que será o alvo da compilação (i.e. STMicroelectronics:stm32:GenF4)

$ bin/arduino-cli core install STMicroelectronics:stm32 --additional-urls https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json
Downloading index: package_index.tar.bz2 downloaded
Downloading index: package_stmicroelectronics_index.json downloaded
Downloading packages...
STMicroelectronics:xpack-arm-none-eabi-gcc@14.2.1-1.1 downloaded
STMicroelectronics:xpack-openocd@0.12.0-6 downloaded
STMicroelectronics:STM32Tools@2.3.0 downloaded
STMicroelectronics:CMSIS@5.9.0 downloaded
STMicroelectronics:STM32_SVD@1.18.0 downloaded
STMicroelectronics:stm32@2.10.1 downloaded
Installing STMicroelectronics:xpack-arm-none-eabi-gcc@14.2.1-1.1...
Configuring tool....
STMicroelectronics:xpack-arm-none-eabi-gcc@14.2.1-1.1 installed
Installing STMicroelectronics:xpack-openocd@0.12.0-6...
Configuring tool....
STMicroelectronics:xpack-openocd@0.12.0-6 installed
Installing STMicroelectronics:STM32Tools@2.3.0...
Configuring tool....
STMicroelectronics:STM32Tools@2.3.0 installed
Installing STMicroelectronics:CMSIS@5.9.0...
Configuring tool....
STMicroelectronics:CMSIS@5.9.0 installed
Installing STMicroelectronics:STM32_SVD@1.18.0...
Configuring tool....
STMicroelectronics:STM32_SVD@1.18.0 installed
Installing platform STMicroelectronics:stm32@2.10.1...
Configuring platform....
Platform STMicroelectronics:stm32@2.10.1 installed
$ bin/arduino-cli board listall | grep "Board Name\|STM32F4"
Board Name               	FQBN
Generic STM32F4 series   	STMicroelectronics:stm32:GenF4

Finalmente basta compilar o firmware (ou sketch), passando como argumentos o nome da placa (obtido anteriormente), uma pasta de artefatos de compilação (build) para armazenar os binários em um local conveniente (e não em um caminho arbitrado pela Arduino CLI) e o código fonte:

$ bin/arduino-cli compile --fqbn STMicroelectronics:stm32:GenF4 --build-path hello_world/build/ hello_world/hello_world.ino
Sketch uses 10772 bytes (2%) of program storage space. Maximum is 524288 bytes.
Global variables use 1128 bytes (0%) of dynamic memory, leaving 129944 bytes for local variables. Maximum is 131072 bytes.

Finalmente, no caminho hello_world/build/hello_world.ino.elf estará o binário que usaremos com o Renode.

Fluxo básico de execução de um binário

O fluxo de execução mais simples para um binário no Renode pode ser resumido nos seguintes passos:

  • Criar uma máquina
  • Carregar a descrição da plataforma de hardware
  • Carregar um binário para execução
  • Configurar analisador para monitorar aplicação
  • Iniciar aplicação

Uma máquina é a abstração do Renode para um dispositivo. Será a instância que vai rodar a emulação. Com o terminal do Renode aberto (vide instruções na seção “Instalando o Renode”), você pode gerenciar a criação de máquinas da seguinte forma (documentação com maiores detalhes sobre gerenciamento de máquinas):

# criar uma máquina com nome genérico
(monitor) mach create
(machine-0) 
# não há periféricos nessa máquina, apenas o barramento do sistema
(machine-0) peripherals
Available peripherals:
  sysbus (SystemBus)
  │

Apenas a máquina não é suficiente para executar a emulação, pois ela é um receptáculo vazio para o dispositivo que queremos simular. Podemos popular essa máquina manualmente com diversos periféricos, como CPU, memórias, temporizadores etc. Esse trabalho de descrever a plataforma manualmente seria a tarefa de uma pessoa que está querendo desenvolver uma plataforma do zero, que pretende testar suas customizações. Mas não precisamos fazer isso aqui.

O Renode conta com um formato de arquivo com extensão .repl (Renode platform) que consiste na descrição de todos os periféricos que uma plataforma (máquina) deve conter. Na página do Github do Renode (renode/platforms) podemos encontrar descrições para diversas CPUs e placas.

Como ficou definido que vamos emular a placa STM32F4, podemos consultar sua descrição de plataforma, tanto da CPU (stm32f4.repl), quanto da placa (stm32f4_discovery.repl). Usaremos a descrição da placa. Portanto, com a máquina criada, podemos carregar a plataforma da STM32F4 com o seguinte comando (documentação sobre descrição de plataformas):

# já que esse .repl está no repositório do Renode, conseguimos acessá-lo assim, caso contrário, teríamos que passar o caminho do .repl
(machine-0) machine LoadPlatformDescription @platforms/boards/stm32f4_discovery-kit.repl
# visualize os periféricos conectados nessa plataforma (como são muitos periféricos, a saída abaixo contém só alguns periféricos)
(machine-0) peripherals
Available peripherals:
  sysbus (SystemBus)
  │  	 
  ├── cpu (CortexM)
  │   	Slot: 0
  │  	 
   ├── dma1 (STM32DMA)
  │   	<0x40026000, 0x400263FF>
  │  	 	 
  ├── flash (MappedMemory)
  │   	<0x08000000, 0x081FFFFF>
  │  	 
   ├── gpioPortA (STM32_GPIOPort)
  │   │   <0x40020000, 0x400203FF>
  │   │   
  │   ├── UserButton (Button)
  │   │  	 
  │   ├── externalButton (Button)
  │   │  	 
  │   └── externalLed (LED)
  │      	  
  ├── sram (MappedMemory)
  │   	<0x20000000, 0x2003FFFF>
  │  	 
  ├── timer1 (STM32_Timer)
  │   	<0x40010000, 0x400103FF>
  │  	  
  └── usart1 (STM32_UART)
    	<0x40011000, 0x400110FF>

Com uma máquina instanciada e apropriadamente descrita com a plataforma de interesse, basta carregar o binário para execução (usaremos o binário preparado na seção “Preparando o binário a ser executado”).

# ou sysbus LoadBinary para carregar binários (.bin)
(machine-0) sysbus LoadELF @hello_world.ino.elf

Uma vez carregado, o binário não é executado automaticamente. Para isso, é necessário executá-lo com o comando “start”.

(machine-0) start
Starting emulation…

Esperávamos que a mensagem “Hello, World!” fosse impressa, mas nada aconteceu no terminal. Isso se deve porque devemos, antes de executar a aplicação, configurar um componente analisador (do Renode) para monitorar aplicação. Para essa placa, o print está conectado à USART1, então é nesse periférico que o analisador deve estar. Assim, conseguiremos obter a saída esperada do nosso firmware:

(machine-0) showAnalyzer sysbus.usart1
(machine-0) start
Starting emulation…
Hello, World!

Ainda assim, é um pouco cansativo ter que executar todos esses comandos para testar o firmware. Não se precoure, pois o Renode também conta com um outro tipo de arquivo com extensão .resc (Renode script) para auxiliar nisso.

No arquivo .resc você pode listar uma sequência de comandos que devem ser executados para configurar a emulação e ele é específico da sua bancada de testes (documentação com detalhes sobre a sintaxe do script Renode). Veja abaixo o script que sintetiza os comandos que executamos anteriormente:

using sysbus
$name?="stm32f4_disco"
mach create $name
machine LoadPlatformDescription @platforms/boards/stm32f4_discovery-kit.repl

sysbus LoadELF @hello_world.ino.elf

showAnalyzer sysbus.usart1

start

Salve o arquivo (e.g. script.resc) e basta passá-lo como argumento quando for chamar o Renode:

$ exec renode_1.15.3_portable/renode script.resc
	# daqui em diante, tudo aparecerá automaticamente
	(monitor) i $CWD/script.resc
Starting emulation...
(stm32f4_disco)
Hello, World!

Isso conclui o fluxo básico de execução de um binário.

Conclusão

Neste tutorial, aprendemos o básico para começar a usar o Renode para emulação de sistemas embarcados. Sua interface intuitiva facilita o acesso aos seus recursos e aliado à sua excelente documentação oficial torna o Renode numa poderosa ferramenta que agregará no seu arsenal de pessoa desenvolvedora de sistemas embarcados. A tendência é que, com sua popularização, a ferramenta se torne mais e mais acessível, com um suporte rico para diversas plataformas de hardware, como microcontroladores, sensores etc.

Referências

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
0 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Home » Hardware » Ferramentas de Desenvolvimento » Começando a usar o Renode para emulação de sistemas embarcados

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste:
Nenhum resultado encontrado.