quarta-feira, junho 04, 2014

Programando o ATtiny85 com a IDE, runtime e bibliotecas do Arduino - Parte 1

Nas minhas experiências até agora tenho programado o ATtiny85 usando diretamente o "avr-gcc toolchain". Embora esta abordagem tenha várias vantagens, como um domínio maior do runtime e um processo de geração do executável mais transparente e rápido, o uso da IDE do Arduino tem os seus atrativos, principalmente a farta disponibilidade de bibliotecas.

Entretanto, o ATtiny não é suportado diretamente pela IDE do Arduino. São necessários alguns ajustes manuais de arquivos de configuração e a obediência a algumas restrições.

Abrindo o Capô da IDE do Arduino - O Arquivo boards.txt

As informações relevantes para a adaptação do ambiente de desenvolvimento do Arduino a hardwares não suportados estão no subdiretório hardware\arduino. Aqui encontramos o arquivo boards.txt que descreve as placas suportadas. A documentação oficial (incompleta) pode ser vista aqui.

Vamos dar uma olhada na definição do Arduino Mega original (que usava o ATmega1280):

mega.name=Arduino Mega (ATmega1280)

mega.upload.protocol=arduino
mega.upload.maximum_size=126976
mega.upload.speed=57600

mega.bootloader.low_fuses=0xFF
mega.bootloader.high_fuses=0xDA
mega.bootloader.extended_fuses=0xF5
mega.bootloader.path=atmega
mega.bootloader.file=ATmegaBOOT_168_atmega1280.hex
mega.bootloader.unlock_bits=0x3F
mega.bootloader.lock_bits=0x0F

mega.build.mcu=atmega1280
mega.build.f_cpu=16000000L
mega.build.core=arduino
mega.build.variant=mega

O primeiro ponto a notar é a identificação (mega) que aparece no início das linhas.  Este identificação é interna, no menu da IDE é usado o nome informado na primeira linha.

As três linhas seguintes dizem respeito à carga dos sketchs: o protocolo usado, o tamanho máximo do código e a velocidade de comunicação.

O bloco seguinte é usado na gravação do bootloader a partir da IDE e informa o valor para os diversos fuses e o caminho e arquivo onde está o bootloader.

A parte final é, provavelmente, a mais importante. O parâmetro mcu informa o modelo do microcontrolador, esta informação será passada ao avr-gcc e ao avrdude. O clock é informado por f_cpu. As duas linhas finais determinam os arquivos que serão usados para a geração do runtime:
  • core determina o diretório onde estão os fontes do runtime (no caso hardware\arduino\cores\arduino).
  • variant determina o diretório que contem o arquivo de definição pins_arduino.h, que veremos a eguir.

Mapeando os Pinos - O Arquivo pins_arduino.h

O arquivo pins_arduino.h fica em hardware\arduino\variants\xis onde xis é o nome da variante que foi informado em boards.txt.

Na programação do Arduino nos referimos aos pinos por números (por exemplo, falamos no LED ligado à saída digital 13) ou identificações simbólicas (como A0). Por outro lado, o microcontrolador mapeia os pinos a bits de registradores (o pino marcado como 13 corresponde bit 5 dos registradores que controlam a porta B). O mapeamento entre a identificação usada nas bibliotecas do Arduino e o hardware do microcontrolador usado é feito no arquivo pins_arduino.h.

Este mapeamento é feito através de macros e tabelas. Para entendê-lo, experimente comparar os arquivos para o arduino padrão e para o arduino mega com os datasheets dos microcontroladores ATmega328 e ATmega1280.

O Runtime do Arduino

Ok, queremos suportar o ATtiny85 (ou algum outro modelo de AVR). Definimos uma placa em boards.txt e mapeamos os pinos em um arquivo pins_arduino.h. Basta isto para tudo funcionar?

Infelizmente não. Se você examinar os fontes em hardware\arduino\cores\arduino, vai encontrar linhas como

#if defined(__AVR_ATtiny24__)

As configurações em pins_arduino.h não são suficientes para cobrir todas as diferenças entre os vários modelos de avr. O jeito encontrado foi o programador codificar trechos diferentes e usar compilação condicional. Infelizmente, a quantidade de modelos suportados (e a qualidade deste suporte) varia de fonte para fonte. A análise do suporte ou não de um determinado modelo é bastante complexa. Em alguns trechos temos o teste para um modelo específico (como o caso ATtiny24 acima). Em outros, é testado a presença de um determinado registrador.

Um ponto bastante crítico são os timers, pois existem vários modelos com recursos diferentes e grande variação na disponibilidade deles no microcontroladores.

Outras Bibliotecas

Bibliotecas externas ao runtime serão compatíveis com placas customizadas na medida em que
  • interajam com o hardware sempre através das funções do runtime
  • não assumam a presença de um recurso ausente no microcontrolador usado

Carga do Software no ATtiny85

Existem duas estratégias possíveis para a carga de sketches.

A primeira é não usar bootloader e fazer a gravação diretamente com um programador como o USBtiny ou USBasp. Se você manter o shift pressionado ao clicar no botão de Upload, o programa será enviado pelo programador configurado em Tools Programmer. A não ser que você não esteja usando os pinos de programação (ou consiga usar de forma a não interferir), provavelmente fará a carga fora do seu circuito de aplicação.

A outra é colocar um bootloader no ATtiny85. Este modelo não possui particionamento da Flash nem proteção para o bootloader, mas permite a gravação da Flash sob o controle do programa. Ele também não tem uma UART, a comunicação serial precisa ser feita por software. Na forma mais simples, você pode usar um conversor externo de TTL para RS232 ou USB. Outra opção é usar o esquema do V-USB para conectar o ATtiny diretamente a uma porta USB do PC (o que complica o hardware e consome mais flash).


Na segunda parte vou mostrar como colocar tudo isto  na prática.

12/6/14: Corrigida a menção a UART no ATtiny85.

Nenhum comentário: