Sistemas Embarcados: Programação do LPC2478 usando o gcc

| Laboratório de Processadores Programação do LPC2478 usando o arm-elf-gcc Parte 1: Configuração do ambiente |

- Configurando o ambiente de programação
- Procedimentos de instalação no Windows
- Procedimentos de instalação no Linux
- Criação de um projeto aplicativo
- Compilação e Instalação do projeto

### Introdução

Neste semestre vamos usar um novo tipo de microprocessador, radicalmente diferente da arquitetura 8051 vista em semestres anteriores. Trata-se do LPC2378 da NXP com core tipo ARM7-TDMI. A arquitetura ARM (Advanced Risc Machine) é um processador RISC de 32 bits com um pipeline de 3 estágios, que permite executar uma instrução de 32 bits a cada ciclo de clock.

A sigla TDMI (Thumb Debugger Multiplier Instruction set) representa um conjunto de intruções alternativo (Thumb mode) de 16 bits. Processadores tipo ARM7-TDMI podem executar estes dois conjuntos de instruções: ARM ou Thumb. No modo ARM todas as instruções são tem 4 bytes. No conjunto de instruções Thumb a maioria das instruções é de 2 bytes.

O LPC2378 tabém tem várias interfaces incorporadas:

- 512K Bytes de Memória Flash programável no sistema através da porta serial.
- 64K Bytes de RAM
- Quatro UARTs (Portas seriais) compatíveis com o 16550, uma delas com sinais de controle de fluxo e uma com IrDA.
- Interface de rede ETHERNET MAC com DMA.
- Interface USB2.0 (USB device)
- Interface USB2.0 (USB host)
- Interfaces SPI e I2C.
- Interfaces para cartão de memória SD/MMC
- Duas interfaces CAN
- Conversores A-D e D-A de 10 bits.
- PWM
- Quatro temporizadores (Timers).
- Relógio de tempo real RTC
- Interface para memória externa SDRAM (64 MBytes de SDRAM no kit)
- Muito mais coisas: ver manual

### Configurando o ambiente de programação

Existem vários compiladores e ambientes de desenvolvimento de software para este tipo de microprocessadors. Dentre eles podemos destacas tres sistemas. Dois ambientes integrados para Windows, incluido editor de texto compilador C, assembler, simulador e debugger: o da IAR e o da Keil. Estes são sistemas comerciais, com prossiblidades de se obter amostras grátis limitadas. Existe também a opção baseada em software livre, com o conjunto de ferramentas GNU-Gcc para a arquitetura ARM.

- IAR A IAR oferece pacotes completos de desenvolvimento na ambiente Windows incluindo compilador c/c++, assembler, simulador e debugger.
- Keil O Keil é outro ambiente completo de desenvolvimento de software para ARM com bom suporte aos processadores da NXP. Tambem é software proprietário, só para Windows.
- CrossWorks é um ambiente de desenvolvimento baseado no GCC que pode funcionar em Windows ou em Linux. É um programa comercial, disponibilizando amostras limitadas válidas por 30 dias.
- arm-elf-gcc O gcc é um conjunto de compiladores distribuído como software livre, podendo funcionar em vários sistemas operacionais.

Eu vou descrever aqui a configuração do gcc. Este sistema tem duas vantagens muito importantes para o nosso ambiente acadêmico:

- É software livre (Licença GNU-GPL ou LGPL). Isto significa que pode-se copiar, instalar, usar ou modificar estes programas sem infringir nenhuma lei.
- O arm-elf-gcc é multiplataforma, podendo ser configurado para funcionar em diversos sistemas operacionais, incluindo o Linux, Windows e McInitosh.

### Ferramentas necessárias para programar para ARM usando o gcc

O pacote arm-elf-gcc pode ser obtido em

http://www.mikrocontroller.net/articles/ARM_GCC_toolchain_for_Linux_and_Mac_OS_X

Este pacote tem as ferramentas básicas para compilar e depurar programas para ARM, incluindo os seguintes programas:

arm-elf-gcc Compilador C
arm-elf-g++ Compilador C++
arm-elf-as Assembler.
arm-elf-ld Linker/loader
arm-elf-objcopy Copia convertendo formatos de código objeto

O pacote tambem inclui os arquivos `#include` e as bibliotecas básicas da linguagem C.

Para o desenvolvimento e teste dos programas para ARM algumas ferramentas adicionais também são necessárias:

- Um editor de texto adequado para escrever programas em linguagem C.
- O programa lpc21isp.c para carregar programas na memória Flash do microprocessador. Esta cópia local foi modificada em relação a outras versões do lpc21isp.c que se encontram na Internet. A modificação serve para incluir o suporte ao LPC2478.
- O programa gnu make para automatizar as etapas da compilação dos programas. Na maioria das distribuições de Linux o make ja vem incluído. No Windows o make vem como parte do pacote mingw ou junto com o devcpp.

O procedimento de instalação das ferramentas difere um pouco dependendo do sistema operacional.
Instalação do arm-gcc para Windows

Uma versão compilada para windows encontra-se em
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index.html#winarm
Neste site existem programas exemplo e explicações sobre o pacote WinARM. O link

Para poder compilar os programas deste tutorial, eu fiz algumas modificações no pacote WinARM:

- O Programador de Flash lpc21isp.exe foi modificado para suportar o LPC2378
- Foi acrescentado no WinARM o arquivo de cabeçalho `#include <arch/nxp/lpc23xx.h>`
- Foi acrescentado o terminal serial wtser.exe.

O pacote completo está no segunte arquivo auto-extraível com cerca de 18 MBytes:

WinARM.exe [18 MBytes]

Para poder compilar os programas a partir de qualquer diretório de trabalho é necessário que o diretório `WinARM\bin` esteja no caminho de busca por programas executáveis (`path`). Para alterar o `path` no Windows usa-se o programa `regedit` para editar a chave `HKEY_CURRENT_USER/Environment/PATH`. Geralmente é necessário reiniciar o Windows para que esta alteração do registry faça efeito. É necessário ter poderes de administrador para poder editar o registry. Quando não se tem este tipo de acesso, pode-se criar o path apenas para a sessão corrente da janela de comandos. Supondo que o WinARM tenha sido instalado em `c:\WinARM` pode-se configurar o caminho com o comando:

    path=c:\WinARM\bin;%path%

Este comando pode ser executado por um usuário comum, mas só faz efeito na janela de comando onde foi executado. Para automatizar este processo pode-se criar um arquivo batch com esta linha.

Outro método para configurar o caminho no Windows é usando o "Painel de Controle":

- A partir do menu "Iniciar" chame o programa "Painel de Controle"
- No painel de controle ative o ícone "Sistema" ou "System"
- No programa "Sistema" selecione o tab "Avançado"
- Aperte no botão "Variáveis de ambiente" (ou "Environment Variables" na versão em Inglês)
- Selecione a variável de ambiente chamada "Path" e aperte no botão "Editar"
- Acrescente o caminho `C:\WinARM\bin` ao valor da variável Path e aperte no botão "OK".

Para verificar se o compilador foi instalado com sucesso, pode-se executar o comando:

    arm-elf-gcc -v

O compilador deve escrever informações sobre a versão instalada.
Instalação do arm-gcc para Linux

Pegar o arquivo arm-elf-gcc-4.1.0-i586-4.tgz [29 MByte]

No Linux tipo Slackware pode-se usar o comando:

    installpkg arm-elf-gcc-4.1.0-i586-4.tgz

Nas outras distribuições pode-se usar os comandos:

    cd /
    tar xzf $OLDPWD/arm-elf-gcc-4.1.0-i586-4.tgz
    cd -

Estes comandos geralmente precisam ser executados como root. O arm-elf-gcc fica instalado dentro do /usr/local com tudo pronto para usar.

### Criação de um projeto aplicativo

Tendo um conjunto de ferramentas de desenvolvimento instalado e configurado, pode-se criar o diretório específico para o nosso projeto.

Por ser um compilador poderoso, capaz de compilar grandes projetos de software, o processo de compilação de um programa usando o gcc passa por diversas etapas. Geralmente o comando básico `gcc` ja faz tudo o que é necessário para gerar o programa executável, mas quando se compila para outra arquitetura alvo, como o ARM, é necessário ter mais controle, ativando explicitamente as etapas da compilação.

Os programas gerados pelo gcc usam um formato intermediário chamado `elf` (Embeddable and Linkable Format), que são os arquivos objeto com extenção `.o` Vários arquivos `elf` podem ser reunidos, incluindo o código de partida `crt.o` e as bibliotecas para formar o programa executável. No conjunto de ferramentas gnu, quem faz isto é o linker/loader chamado `ld`. No pacote para ARM temos o `arm-elf-ld`. Geralmente o `ld` é chamado automaticamente pelo `gcc`, mas como queremos usar uma rotina especial de partida, chamaremos o `arm-elf-ld` explicitamente. O resultado do comando `arm-elf-ld` é um programa que no Linux seria executável, mas para programá-lo na Flash do LPC2378, devemos converter este arquivo para o formato `*.hex`. Isto é feito pelo programa `arm-elf-objcopy`. Finalmente o arquivo com extenção `*.hex` pode ser usado para gravar a memória Flash do LPC2378 usando o programa `lpc21isp`.

Seria cansativo e propenso a erros ter que fazer todo este procedimento manualmente toda a vez que queremos compilar o projeto. É possível automatizar esta compilação usando um script de shell ou no DOS, um arquivo de execução em lote tipo `*.bat`, porém a melhor solução é usar o comando `make`.

O comando `make` usa um arquivo chamado `Makefile`, que descreve os procedimentos necessários para compilar o projeto.

O arquivo a02_piscaled.tgz contém a estrutura básica para o nosso primeiro projeto para o LPC2378 copilado com o arm-elf-gcc. Ao ser expandido (com `tar xzf a02_pisca_led.tgz` no linux, ou com o Win-zip no Windows), ele cria um diretório chamado `a02_pisca_led/` contendo os seguintes arquivos:

`Makefile`
  Arquivo de configuração do programa `make`, descrevendo os procedimentos necessários para automatizar a compilação do projeto.
`crt.S`
  Procedimento de inicialização (startup) escrito em linguagem assembly do ARM7. Este procedimento contem o ponto de entrada principal do programa e as entradas das interrupções. Ele faz algumas inicializações e chama a rotina `main()` da parte escrita em linguagem C.
`lpc2378_flash.ld`
  Script de configuração de linker/loader. Este arquivo descreve como o `arm-elf-ld` deve alocar memória no LPC2378 para os segmentos do programa.
`lpc23xx.h`
  Arquivo de cabeçalho para `#include` contendo a descrição dos registradores, e portas de I/O dos periféricos do LPC2378.
`main.c`
  Programa principal. Neste exemplo procurou se fazer a coisa mais simples possível que tenha resultados práticos: Fazer piscar um LED.

### Compilação e Instalação do projeto

Para compilar e testar o programa use o seguinte procedimento:

- Pegar o arquivo m2478j.tgz
- Expandir: No Linux usa-se o comando

      tar xzf mon24.tgz

- Pegar um `shell` (Janela de comandos) e entrar no diretório `mon24`

      cd mon24

- Compilar o projeto com o comando

      make

- Preparar o Kit LPC2478 para gravação: Conectar o cabo de comunicação serial, ligar a placa e pressionar e soltar o botão reset enquanto o botão de programação é mantido pressionado.
- Executar o comando para programar a Flash:

      make isp

  Este comando grava o programa na memória do LPC2378 e executa o programa. O LED deve começar a piscar. Pode ser necessário apertar no botão de Reset para que a execução do programa se inicie corretamente.
- Pode ser conveniente chamar o programa terminal `wtser` (Ou `ltser` no Linux) para comunicar com o Kit através da interface serial.
- Para apagar os arquivos intermediários gerados por uma compilação usa-se o comando

      make clean

- O programa m2478j.tgz pode ser expandido, compilado e gravado na memória FLASH de forma similar. Este programa é um monitor e boot-loader de arquivos intel-hex. Se o programa `m2478j` ja estiver gravado na memória Flash do microcontrolador, pode-se usar um outro método para compilar e executar programas no LPC2478. O monitor `m2478j` dispõe de um carregador de arquvos tipo Intel Hexadecimal, que permite caregar e executar programas na memória RAM, sem a necessidade de programar a memória Flash toda a vez que se deseja testar um programa. Isto também tem a vantagem de aumentar a durabilidade do kit, porque a memória Flash suporta um número finito de apagamentos e gravações. Para compilar o programa e envia-lo para a RAM pode-se usar a diretiva

      make tser

  Após este comanodo o computador estará executando um terminal `ltser`, com o programa armazenado na RAM a partir do endereço `0x40000000`. Pode-se então executar o programa usando o comando P do monitor.