GNU ARM Cross-toolchain - Compilação e OpenOCD

GNU ARM Cross-toolchain heap

Introdução

 

Quando é iniciado um novo projeto que faça uso de microcontroladores, surge a necessidade da definição do ambiente de desenvolvimento. Atualmente existem ferramentas comerciais muito boas, tais como IAR, Keil e Code Red, que oferecem um ambiente de desenvolvimento completo, desde um editor de texto até utilitários de depuração, além de ferramentas de acesso ao hardware para gravação, depuração, trace, profiling, etc. Dentre todas as opções disponíveis, qual escolher?

 

Quando um ambiente de desenvolvimento completo é obtido, é fácil perder a noção da sua composição e da função de cada uma de suas partes. O objetivo desse artigo é iniciar uma série para auxiliar a criação de um ambiente de desenvolvimento cross-platform para microcontroladores ARM Cortex-M, fazendo uso de ferramentas GNU, que são open-source.

 

Uma descrição da composição de um toolchain GNU, e do processo de build usando o mesmo, pode ser visto aqui, onde são fornecidos descrições de cada parte que o compõe e conceitos de cross-compiling.

 

O sistema host utilizado é um PC com a distribuição Ubuntu 14.04 64 bits, e o sistema target adotado para esse artigo, sendo que irão ser utilizados outros ao longo da série, é o kit de desenvolvimento STM32F4-Discovery, da Figura 1.

 

Kit didático STM32F4-Discovery
Figura 1 - Kit didático STM32F4-Discovery

 

 

Organização do ambiente de desenvolvimento

 

O seguinte padrão de estrutura de arquivos será respeitado ao longo da série:

 

~/work/
  dl/
  projects/
  tools/
    openocd/
    stm32/

/opt/
  toolchains/
    eabi/

 

Portanto, deve-se criar os seguintes diretórios:

 

$ mkdir -p ~/work/dl ~/work/projects ~/work/tools/openocd ~/work/tools/stm32
$ sudo mkdir -p /opt/toolchains/eabi

 

Também é necessário instalar algumas dependências no sistema host para poder executar os procedimentos do artigo, usando o comando abaixo:

 

$ sudo apt-get install build-essential libusb-1.0-0-dev git

 

 

GNU ARM Cross-toolchain

 

Inicialmente é necessário instalar um cross-toolchain para gerar binários para a plataforma target. Pode-se seguir dois caminhos: utilizar um cross-toolchain pré-compilado ou criar um cross-toolchain customizado. Neste artigo é utilizado o cross-toolchain Sourcery CodeBench Lite Edition, disponibilizado pela Mentor Graphics, que oferece ferramentas otimizadas para a arquitetura ARM. Será adotada a segunda opção em um próximo artigo.

 

Para a instalação do cross-toolchain no sistema host, siga os seguintes passos:

 

$ cd ~/work/dl
$ wget https://sourcery.mentor.com/GNUToolchain/package12774/public/arm-none-eabi/arm-2014.05-28-arm-none-eabi-i686-pc-linux-gnu.tar.bz2
$ cd /opt/toolchains/eabi/
$ sudo tar xjvf ~/work/dl/arm-2014.05-28-arm-none-eabi-i686-pc-linux-gnu.tar.bz2

 

De forma a não ser utilizado o caminho absoluto dos binários do cross-toolchain no shell, o mesmo deve ser adicionado à variável de ambiente PATH. Para isso, pode ser editado o arquivo ~/.bashrc, adicionando a seguinte linha ao mesmo:

 

export PATH=/opt/toolchains/eabi/arm-2014.05/bin:$PATH

 

Para que essa mudança tenha efeito no shell ativo, execute o seguinte comando:

 

$ source ~/.bashrc

 

Execute o seguinte comando para testar a instalação do cross-toolchain:

 

$ arm-none-eabi-gcc -v

 

O comando anterior exibe as configurações utilizadas para a geração do cross-toolchain, dentre as quais podemos destacar a seguinte:

 

--with-newlib: a biblioteca C padrão utilizada é a Newlib

 

Aqui encontram-se listadas as versões de todos os pacotes utilizados para a geração do cross-toolchain.

 

 

Projeto

 

Agora que instalamos um cross-toolchain, é necessário gerar um binário para gravação na memória flash do microcontrolador. Para isso foi criado um projeto no GitHub, que pode ser obtido com o seguinte comando:

 

$ cd ~/work/projects
$ git clone https://github.com/henriqueprossi/stm32f4-discovery-bare-metal.git

 

Ao invés de somente gerar um binário para gravação, é interessante entendermos as funções de cada arquivo do projeto.

 

makefile

 

Este arquivo impõe as regras de criação dos artefatos do projeto, baseado no fluxo apresentado na Figura 2. Basicamente, o mesmo gera os binários finais nos formatos .bin, .hex e .elf, tendo como entrada os arquivos-fonte da aplicação, o arquivo de inicialização e o linker script.

 

Figura 2 - Processo de build
Figura 2 - Processo de build

 

stm32_flash.ld (linker script)

 

A programação para microcontroladores é similar à programação para microcomputadores, no entanto exige atenção a alguns detalhes muito importantes. Um deles é o vetor de interrupção, o qual deve ser alocado obrigatoriamente numa posição específica da memória flash do microcontrolador. No caso da família STM32F4xx, esta posição é 0x08000000.

 

O compilador GCC gera arquivos binários no formato binário ELF, o qual é formado por seções, tais como .text, .data e .bss. O trabalho de alocação dessas seções no arquivo binário executável é responsabilidade do linker, orientado pelas configurações indicadas no linker script, onde o mapa de memória do microcontrolador é particionado entre as memórias disponíveis, tais como RAM e flash.

 

crt.c (startup)

 

Antes de ser executada a aplicação principal, indicada pelo ponto de entrada main, são necessárias algumas inicializações no sistema por estar sendo utilizada uma linguagem de alto nível, tal como C. Esse trabalho é executado pelo arquivo de startup, onde, por exemplo, são inicializadas as seções .bss e .data.

 

stm32f4_vector.c (vetor de interrupção)

 

O vetor de interrupção, que contém ponteiros para funções, indica os pontos de entrada para cada tipo de exceção gerada pelo core ARM Cortex-M4 e pelos periféricos do microcontrolador STM32F4xx.

 

cmsis (drivers)

 

Este projeto fez uso da biblioteca CMSIS implementada pela ST, que foi especificada pela ARM com a finalidade de facilitar a portabilidade entre as aplicações desenvolvidas para microcontroladores da família ARM Cortex-M.

 

main.c (aplicação)

 

A aplicação tem a finalidade simples de inicializar o clock e o timer SystemTick do microcontrolador, além acender os leds de usuário do kit de forma sequencial e apagá-los de uma única vez, o que é executado em loop infinito.

 

Agora que as partes do projeto foram brevemente indicadas, pode-se compilar a aplicação da seguinte forma:

 

$ cd ~/work/projects/stm32f4-discovery-bare-metal/hello_world
$ make

 

Pronto! Alguns binários foram gerados pelo processo. Precisa-se, agora, de uma forma de gravação desses binários na memória flash do microcontrolador. Para isso vai ser utilizado um aplicativo no sistema host chamado OpenOCD.

 

 

OpenOCD

 

O OpenOCD tem a finalidade de depurar, programar e testar dispositivos embarcados. Para isso é necessário um dispositivo, chamado debug adapter, responsável por implementar a comunicação via hardware entre o sistema host e o microcontrolador.

 

O kit STM32F4-Discovery contém uma implementação, na própria placa, de debug adapter, chamada ST-LINK/V2, cuja interface com o sistema host é uma porta USB.

 

Para a instalação do OpenOCD, siga os seguintes passos:

 

$ cd ~/work/dl/
$ wget http://sourceforge.net/projects/openocd/files/openocd/0.8.0/openocd-0.8.0.tar.bz2
$ cd ~/work/tools
$ tar -xjvf ~/work/dl/openocd-0.8.0.tar.bz2
$ cd openocd-0.8.0
$ ./configure --enable-maintainer-mode --enable-stlink --prefix=$HOME/work/tools/openocd
$ make
$ make install

 

Como o OpenOCD faz uso do driver USB do sistema host, pode-se instalar algumas regras do gerenciador de dispositivos udev para que não seja necessário executar esse aplicativo com permissões de superuser.

 

$ cd ~/work/tools/stm32
$ git clone git://github.com/texane/stlink.git
$ cd stlink
$ sudo install -m 644 49-stlinkv2.rules /etc/udev/rules.d/49-stlinkv2.rules
$ sudo udevadm control --reload-rules

 

Da mesma forma que foi feito para o cross-toolchain, o caminho do OpenOCD, abaixo, deve ser adicionado à variável de ambiente PATH do sistema host, no arquivo ~/.bashrc.

 

~/work/tools/openocd/bin

 

Como dito anteriormente, o makefile do projeto gera diversos arquivos binários, sendo que será utilizado o arquivo build/hello-world.bin, no formato raw, para gravação. Inicialmente, conecte o kit didático na porta USB do sistema host. Em seguida, execute o comando abaixo:

 

$ openocd -s ~/work/tools/openocd/share/openocd/scripts -f board/stm32f4discovery.cfg

 

Uma vez que o OpenOCD está sendo executado, no modo servidor, o mesmo fica aguardando conexões de clientes, por meio dos canais Telnet e GDB. Neste artigo é utilizada a conexão Telnet. Portanto, numa outra instância de shell, execute o seguinte comando:

 

$ sudo telnet localhost 4444

 

A partir desse momento temos acesso ao hardware do microcontrolador, de forma que podemos apagar o conteúdo de sua flash e gravar uma nova imagem na mesma. Para isso, execute os comandos abaixo:

 

> reset halt
> flash erase_sector 0 0 last
> flash write_bank 0 /home/henrique/work/projects/stm32f4-discovery-bare-metal/hello_world/build/hello-world.bin 0
> reset run

 

Obs.: O comando flash write_bank deve receber como argumento o caminho completo do binário a ser gravado. Portanto, altere o mesmo de forma a conter o nome de usuário correto.

 

Pronto! Acabamos de programar a flash do microcontrolador e a aplicação já está sendo executada!

Outros artigos da série

GNU ARM Cross-toolchain – Configurando stack e heap >>
NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Henrique Rossi
Engenheiro eletricista com ênfase em eletrônica e pós-graduado em Engenharia de Software. Comecei um mestrado, mas o interrompi. Especialista na área de sistemas embarcados, com mais de 12 anos de experiência em desenvolvimento de firmware (sistemas baremetal e baseados em RTOS) e Linux Embarcado. Atualmente sou administrador do site Embarcados, trabalho num fabricante de Set-Top Box e atuo como consultor/desenvolvedor na área de sistemas embarcados.
recentes antigos mais votados
Notificar
Matheus Quick
Visitante
Matheus Quick

Pretendo futuramente estudar a fundo isto

Paulo Bernardo
Visitante
Paulo Bernardo

Ola Henrique,

Quando eu executo o comando make ocorre o seguinte erro: comment image

Tiago Martins da Silva
Visitante
Tiago Silva

Ola Henrique,

Eu possuo a placa STM32 VL Discovery, estou bem no inicio da aprendizagem.
Estou acompanhando o passo a passo do seu artigo, cheguei na parte de projeto e nao sei se a minha placa é compatível com o apresentado no artigo, o microcontrolador utilizado na placa é o STM32F100RB. Poderia por favor esclarecer essa dúvida?
Caso não seja compatível, as mudancas necessárias são muito grandes ara que funcione?

Muito obrigado pela serie de artigos, antecipadamente agradeco pela ajuda.

Vinicius Maciel
Visitante
vinifr

Ola Henrique,

Quando executo o comando "openocd -s ~/work/tools/openocd/share/openocd/scripts -f board/stm32f4discovery.cfg"

Ocorre esse erro:

Open On-Chip Debugger 0.8.0 (2015-09-10-21:47)
Licensed under GNU GPL v2

Runtime Error: embedded:startup.tcl:47: Can't find openocd.cfg
in procedure 'script' at file "embedded:startup.tcl", line 47
Error: Debug Adapter has to be specified, see "interface" command
in procedure 'init'

Vinicius Maciel
Visitante
vinifr

Deixa pra lá, resolvi.

trackback

[…] Lembre-se que no primeiro post da série GNU ARM Cross-toolchain foi apresentada a organização do ambiente de desenvolvimento […]

trackback

[…] GNU ARM Cross-toolchain – Compilação e OpenOCD […]

trackback

[...] passos para instalação do servidor GDB, o OpenOCD, foram listados no primeiro post da série GNU ARM Cross-toolchain. Caso não tenha seguido esses passos, execute-os antes de dar [...]

trackback

[...] apresentada na segunda parte deste artigo. Caso não tenham sido realizados os passos listados no primeiro artigo da série, é interessante que esses sejam executados de forma a tirar maior proveito dos conceitos [...]

trackback

[...] GNU ARM Cross-toolchain – Compilação e OpenOCD [...]

trackback

[...] host, um PC, é necessário gravá-lo no dispositivo target e executá-lo. Isso foi feito no primeiro artigo desta série, e é o que ocorre na fase de produção de um produto. O microprocessador busca e executa as [...]