Desenvolvendo em C para ARM Cortex-M usando GCC e Make

Em todo projeto que uso algum microcontrolador ARM Cortex-M, o firmware eu construo usando somente GCC, Make e o Eclipse, mas o Eclipse frequentemente uso somente para debug mais simples. O objetivo principal em usar somente o GCC e Make é para manter o desenvolvimento o mais simples possível, dependente do menor número de ferramentas possível e independente do sistema operacional usado no desenvolvimento. É possível desenvolver ou compilar tudo sem utilizar IDE alguma. Nesse tutorial vou mostrar o básico para desenvolvimento desse jeito, e a integração ao Eclipse vou mostrar em um próximo artigo.

 

Dessa maneira é possível usar Linux, Windows ou MinGW no desenvolvimento (e provavelmente em OSX). Eu uso Linux e Windows em máquinas diferentes no dia a dia, mas aqui irei mostrar o setup baseado no Windows.

 

 

Download das ferramentas

 

  • O compilador GCC para ARM (Toolchain) que está disponível no site Launchpad: faça o download da última versão em formato .zip para win32 aqui;
  • O vamos usar o Make que é distribuído junto do projeto MinGW-64 (Ferramentas Unix para Windows) que está disponível no SourceForge: faça o download do x86_64-6-3-0-release-posix-seh-rt_v5-rev1.7z aqui.

 

 

Criando os diretórios para as ferramentas

 

Se já houver um diretório para este fim, pode ser colocado lá também, mas aqui vamos criar tudo na partição C:

  • C:\tools
  • C:\tools\binutils
  • C:\tools\arm-none-eabi-gcc

 

 

 Instalando o GCC para ARM

 

- Descompacte o gcc-arm-none-eabi-5_4-2016q3-20160926-win32.zip em C:\tools:

ARM Cortex-M usando GCC e Make - Instalando o GCC para ARM

 

- Renomeie o diretório descompactado para arm-none-eabi-gcc:

Diretório descompactado para arm-none-eabi-gcc

 

 

Instalando o Make

 

Na verdade o que iremos fazer é somente descompactar o executável mingw32-make.exe em C:\tools\binutils do MinGW-64 baixado, não há a necessidade de descompactar o arquivo inteiro. Abra o .zip com o 7-zip ou outra ferramenta e vá em mingw64\bin para encontrar o mingw32-make.exe:

 

 

E então renomeie o mingw32-make.exe para make.exe (certifique-se de não haver outro make.exe no PATH do sistema. Se houver, pode deixar como mingw32-make.exe, mas será necessário chamar no terminal mingw32-make.exe ao invés de somente make.exe):

 

 

Agora as ferramentas que precisamos estão nos lugares corretos. Vamos colocar os diretórios do ARM GCC e Make no PATH. Lembrando que não é exatamente necessário isto, mas no arquivo Makefile será necessário colocar o caminho completo dos executáveis do ARM GCC, e esse caminho será diferente em cada plataforma que será utilizada no desenvolvimento. Vai da sua escolha, somente tome cuidado para não haver outros executáveis no PATH com o mesmo nome para evitar conflitos.

 

 

Adicionando as ferramentas no PATH do Windows

 

Adicione no PATH em Variáveis de Ambiente > Variáveis de Sistema > Path os diretórios para o Make e ARM GCC que criamos há pouco e clique em OK:

 

Agora abra um cmd para testar o make e o GCC, você deverá ver o seguinte com os comandos make --version e arm-none-eabi-gcc –version:

 

Se a saída estiver OK, as ferramentas estão prontas para serem usadas.

 

 

Projeto de exemplo

 

Vamos assumir uma placa o mais simples possível, como exemplo usando o STMF100C8 para nosso código. Ela tem apenas o microcontrolador e um led e...adivinhe! Sim, vamos piscar esse led:

 

 

 

Download do código e da biblioteca da ST para a família STM32F1

 

Antes de baixarmos o código e a biblioteca, vamos criar um diretório de firmware para manter o mais organizado possível. Nesse diretório colocaremos todas as bibliotecas e os códigos, de forma que outros projetos possam utilizar as mesmas bibliotecas.

 

O diretório será C:\firmware, mas novamente, pode ser criado em outro lugar.

  • O código do projeto exemplo pode ser clonado daqui em C:\firmware;
  • A biblioteca para a família STM32F1 é a STM32CubeF1e pode ser baixada no fim da página aqui. A versão atual é a 1.4.0.

 

Após clonar o código exemplo e descompactar a biblioteca, os diretórios ficarão com o seguinte:

  • C:\firmware\blink-stm32f100
  • C:\firmware\STM32Cube_FW_F1_V1.4.0

 

Vamos testar tudo executando make dentro do diretório blink-stm32f100. Se tudo estiver certo, a saída deverá ser, ao final, as memórias usadas pelo código exemplo, como na imagem:

 

 

 

Customizando para seu próprio projeto

 

Há poucas coisas que devem ser alteradas para customizar o código para sua própria placa ou microcontrolador, vou explicar como fazer para micros STM32 e  usando da biblioteca da ST. Mas para outro micro é quase a mesma coisa, sendo que o que deve ser alterado é:

 

Linker:

 

O STM32F100C8 tem 64KB de FLASH e 8KB de RAM. A memória flash começa no endereço 0x08000000, e a RAM começa em 0x20000000 (confira no datasheet/manual do microcontrolador para ter certeza dos endereços, sempre). Esses dois endereços e o tamanhos respectivos de cada tipo de memória são basicamente as coisas que serão alteradas no projeto usando outro STM32F1, mas com diferentes configurações de memória. Quase sempre há um arquivo linker (.ld) pronto para cada microcontrolador na biblioteca ST aqui.

 

No caso específico do STM32F100C8, a STM32CubeF1 não tem um linker pronto, mas tem para STM32F100CB, então foi só copiar o linker para o diretório do projeto e alterar as linhas das configurações de memória e endereços:

 

 

Arquivo Startup:

 

O arquivo .s é onde reside as primeiras instruções do firmware e é responsável por pelas primeiras chamadas das funções, como por exemplo a SystemInit (no caso do uso das libs da ST) para setup dos clocks e __libc_init_array para inicialização das variáveis estáticas. E não menos importante, é nele que estão descritos os nomes das funções de interrução (Interrupt Service Routine – ISR), que através do linker serão colocadas no local correto da memória flash, o isr_vector. Para o STM32F100C8, usei o startup_stm32f100xb.s sem a necessidade de alterá-lo, copiando da biblioteca da ST aqui.

 

Arquivo Makefile:

 

Neste projeto exemplo, do começo até a linha 70 do arquivo Makefile, estão as instruções para detecção do sistema operacional e outras flags gerais, não é necessário alterar nada nesta parte ao menos que você queira, ou se o compilador não está no PATH ou tem executável com um nome diferente por exemplo.

 

- Na variável CFLAGS, basicamente são setados as flags para o compilador de qual será o processador (-mcpu=cortex-m3) e as flags que são necessárias para a biblioteca (-DSTM32F100xB e -DUSE_HAL_DRIVER). Na maioria das vezes, alterar essas flags é o suficiente para um outro microcontrolador.

 

- Em ASMFLAGS, junto com a flag -mcpu, é possível passar algum parâmetro específico para o assembler, ou seja, a interpretação de arquivos assembly.

 

- Em LDFLAGS é onde informamos onde o script de linker que será usado está, utilizando a flag -T: -T./linker/STM32F100XB_FLASH.ld.

 

- Em INCLUDEPATHS, precisamos adicionar o caminho de todos os headers (.h) que serão utilizados no código com #include.

 

- Em C_SRC, é preciso colocar o caminho completo de todos os arquivos .c utilizados no projeto, por exemplo, se você quer usar o módulo A/D deste microcontrolador, é preciso colocar o caminho completo do arquivo stm32fxx_hal_adc.c que está no diretório da biblioteca ST relativo ao projeto, e também remover o comentário da linha “#define  HAL-ADC_MODULE_ENABLED” no arquivo stm32f1xx_hal_conf.h.

 

- Em s_SRC, todo arquivo em assembly será adicionado, neste projeto só o arquivo startup (startup_stm32f100xb.s) é adicionado.

  

Otimização:

 

Na frente de debug: e release: estão mais algumas flags que são concatenadas à CFLAGS e uma delas é a configuração de otimização de código do projeto. Neste caso está -Og, que é o melhor nível de otimização para debug, mas é possível colocar o nível que quiser, basta olhar no manual do GCC para detalhes. É possível setar uma otimização diferente para debug e release, e então quando executar o make é preciso passar o parâmetro debug ou release na linha de comando: “make debug” ou “make release”.

 

 

Considerações finais

 

Por fim, estes são os principais pontos que podem ou devem ser alterados no arquivo Makefile, não vou explicar cada ponto dele pois o intuito deste tutorial é uma introdução prática ao desenvolvimento independente de IDE e com ferramentas open-source.

 

No próximo post irei abordar a integração ao Eclipse para debug e para desenvolvimento usando ele também, continuando com o projeto independente.

 

Se houver alguma crítica, sugestão, problema com o guia ou atualização, é só comentar!

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.

2
Deixe um comentário

avatar
 
1 Comment threads
1 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Bruno AlmeidaEmerson Beserra Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Emerson Beserra
Visitante
Emerson Beserra

Ola, a casa oficial do GNU ARM fica aqui agora: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm

Bruno Almeida
Visitante
Bruno

Olá Emerson! Obrigado pelo toque!