Configuração e inicialização de microcontroladores: Um estudo utilizando ARM Cortex-M0+

Por trás da função principal de um programa - main() - existe um conjunto de arquivos e configurações necessários para torná-la o ponto de entrada de um programa. Neste artigo serão apresentados os passos necessários para criar os arquivos de configuração e inicialização de microcontroladores, criando um setup básico para inicializar um microcontrolador (MKL25Z128) com arquitetura ARM® Cortex™-M0+. Para tal, as ferramentas disponibilizadas no GNU ARM Embedded Toolchain serão utilizadas.

 

Neste artigo a inicialização do sistema é definida como sendo a configuração básica para que o sistema possa operar em um estado conhecido. Tal condição é iniciada quando o microcontrolador é energizado, entrando no estado de Reset. Nesta condição, o processador inicia a execução do programa a partir de um endereço especificado numa região de memória chamada de Reset Vector. Considerando isso, cabe apresentar uma breve introdução à arquitetura do ARM® Cortex™-M0+.

 

 

Breve apresentação da Arquitetura

 

O ARM® Cortex™-M0+ faz parte da série de processadores Cortex-M aplicado em microcontroladores de 32 bits. Para este artigo é importante destacar as seguintes características: vetores de Interrupção e mapa de memória. Nesse sentido, as diferenças entre a linha M0 e M0+ não interferem nos temas destacados aqui. Para outras informações consulte o artigo escrito pelo Thiago e a documentação disponibilizada pela ARM.

 

A arquitetura ARM® Cortex™-M0+ apresenta vetores de interrupção com a disposição indicada na Figura 1. Os primeiros 16 endereços deste vetor possuem funções específicas, sendo o restante dependente do microcontrolador. A primeira posição é destinada para indicar o endereço da região de stack. A segunda, para indicar o ponto de entrada da aplicação.

 

Vetores de Interrupção para Inicialização de microcontroladores ARM
Figura 1: Vetores de Interrupção [1].

 

O mapa de memória do processador separa o espaço de endereçamento em múltiplas regiões, sendo representadas por diferentes tecnologias de memória e atributos. O mapa de memória padrão da arquitetura é mostrado na Figura 2. O espaço de endereçamento total é de 4 GB.

 

Mapa de Memória para Inicialização de microcontroladores ARM
Figura 2: Mapa de Memória [1].

 

Os endereços e descrições destas regiões são apresentados na Figura 3. Cabe ressaltar que as regiões CODE, SRAM e external RAM possibilitam armazenar programas.

 

Características das regiões de memória
Figura 3: Características das regiões de memória [1].

 

 

De Olho no Datasheet

 

Embora as regiões de endereçamento estejam delimitadas, cabe a a cada dispositivo indicar os elementos internos de cada região. Isto é, as tecnologias de memória e as funções de cada região. Por exemplo, analisando o datasheet do microcontrolador MKL25Z128 encontram-se as regiões indicadas na Figura 4.

 

Mapa de memória KL25Z
Figura 4: Mapa de memória KL25Z [2].

 

A memória flash tem capacidade de 128 KB e a memória RAM 16 KB. Embora a memória flash seja posicionada no endereço 0, os endereços iniciais são destinados aos vetores de interrupção. Além disso, a partir do endereço 0x0_0400 fica localizada uma região denominada Flash Configuration Fields, de 16 bytes.

 

 

Arquivo de inicialização

 

Um arquivo de inicialização básico consiste na declaração do vetor de interrupções e da definição do ponto de entrada (entry point), isto é, da primeira instrução executada.

 

 

Neste código, o ponto de entrada da aplicação é o Reset_Handler.

 

 

De modo geral, o arquivo de inicialização pode conter diversos estágios antes de realizar a chamada da função main. Por exemplo, realizar a configuração de alguns periféricos e do sistema de clock. O Arquivo completo é mostrado abaixo.

 

 

Na rotina Reset_Handler realizou-se a chamada da função SystemInit disponibilizada no SDK do fabricante. No entanto, esses procedimentos ficam a critério do desenvolvedor, pois os procedimentos podem ser realizados em outro ponto e de outra maneira. 

 

 

Link-edição

 

As informações sobre as regiões de memória destacadas anteriormente são utilizadas durante o processo de compilação em um estágio chamado link-edição. Especificamente, este processo é caracterizado por distribuir os objetos gerados na etapa de compilação nas regiões de memória indicadas no arquivo. Assim, deve-se especificar a localização da seção de código (.text), dados (.data), pilha (.stack), entre outras.

 

Antes disso, é necessário definir o ponto de entrada no vetor de interrupções usando a diretiva ENTRY.

 

 

Em seguida são definidos os tipos de memória presentes no microcontrolador e o respectivo espaço de endereçamento. Isso é feito a partir da diretiva MEMORY.

 

 

Após esta definição é necessário especificar ao linker quais seções serão combinadas nas regiões de memória indicadas. Para tal, utiliza-se a diretiva SECTION.

 

 

A definição das regiões de memória para este projeto são apresentadas abaixo na Figura 5 e declaradas no script abaixo.

 

Regiões de memória indicadas no linker.
Figura 5: Regiões de memória indicadas no linker.

 

 

 

Compilando o programa

 

Foi dito que o processo de compilação de um programa é realizado por etapas, sendo ao fim realizado o processo de link-edição. A seguir são apresentados os comandos para compilação e montagem dos objetos.

 

Para programas em C o seguinte procedimento é executado. O parâmetro '-c' indica que o linker não será utilizado. O resultado disso é um arquivo objeto.

 

 

Para programas em Assembly o seguinte procedimento é executado. O parâmetro '-c' indica que o linker não será utilizado. O resultado disso é um arquivo objeto.

 

 

Por fim, utiliza-se o utilitário ld para realizar a link-edição de todos os módulos e gerar o arquivo final.

 

 

O resultado disso pode ser visto com o utilitário objdump.

 

Automação do processo com Makefiles

 

Antes de iniciar este tópico, cabe lembrar que um tutorial completo sobre Makefiles é apresentado pelo Lincoln Uehara neste artigo.

 

Este projeto foi criado na IDE Kinetis e possui a seguinte organização:

 

Estrutura do Projeto.
Figura 6: Estrutura do Projeto.

 

Os arquivos de include foram obtidos do pacote de software CMSIS. Os arquivos do microcontrolador MKL25Z4 foram obtidos no SDK do Kinetis. No entanto, os arquivos startup_MKL25Z4.S e o linker foram alterados para atender aos abjetivos deste artigo.

 

A automatização do processo de compilação é mostrada abaixo em que o caminho para o compilador é definido a partir de uma variável de ambiente. O toolchain (GNU ARM Embedded Toolchain) pode ser obtido neste link.

 

 

O procedimento executado também pode ser visto na Figura 7. Cada arquivo fonte passa por um procedimento, gerando um arquivo objeto. Por fim, os arquivos objetos são transformados em uma imagem final.

 

Procedimento para gerar o programa.
Figura 7: Procedimento para gerar o programa.

 

 

Conclusão

 

Neste artigo foram apresentadas as etapas para construção de uma aplicação simples, considerando a construção do arquivo utilizado pelo linker e a definição de uma rotina de inicialização. Com essas ferramentas é possível alterar outras configurações de memória e inicialização do dispositivo. Outra aplicação pode ser a criação de sistemas de bootloader como mostrado no artigo do Marcelo Jo.

 

 

Saiba mais

 

ARM Cortex M0+

Introdução ao Makefile

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

GNU Cross-toolchain - Processo de build

 

 

Referências

[1] Cortex-M0+ Technical Reference Manual;

[2] KL25 Sub-Family Reference Manual.

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.

Fernando Deluno Garcia
Fascinado por computação, especialmente na interface entre hardware e software, me engajei na área de sistemas embarcados. Atuo com desenvolvimento de sistemas embarcados e sou docente da Faculdade de Engenharia de Sorocaba.Para mais informações: https://about.me/fdelunogarcia

1
Deixe um comentário

avatar
 
1 Comment threads
0 Thread replies
1 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Xavier Albornoz Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Xavier Albornoz
Membro
Xavier Albornoz

Parabéns Fernando !!! Vc fez um "tutorial" exatamente como um dia planejo fazer para o mundo KEIL ... voltado para os NXPs da vida. PA-RA-BÉNS !!!