quarta-feira, 18 de setembro de 2013

ENC28J60 - A Reta Final!

Pessoal,

Bom, cá estou novamente as voltas com uma nova versão da biblioteca para o ENC28J60 que funcione satisfatoriamente no Arduino...

É fato que a primeira versão da EthernetSupENC28J60.h não resolveu o problema e ainda gerou novas dúvidas. Lancei então uma segunda versão do núcleo da biblioteca, chamado EtherEncLib.h, que também apresentou os mesmos problemas da primeira versão.

Resolvi então suspender a segunda versão do núcleo e comparar os datasheets do ENC28J60 com o do W5100. Foi aí que entendi o que se passava...

O W5100 tem internamente no chip, toda uma camada de aplicação já pronta. Além disso ele tem o dobro da memória do ENC28J60 e já lida automaticamente com a montagem, envio, recepção e desmontagem dos pacotes TCP. Tudo já está pronto no W5100! Isso não só para TCP, mas também para UDP e outros protocolos.

Não pára por aí. O W5100 tem 4 sockets independentes, controlados por registradores também independentes. Resumindo, tudo está resolvido no W5100, enquanto no ENC28J60 tudo tem que ser feito na unha!

Toda essa parte de sockets, buffers independentes, tratamento automático de pacotes e timers internos para controlar a resposta, simplesmente não existe no ENC28J60.

Foi então que tive outra idéia. Fui procurar o material existente sobre o ENC28J60, diretamente na fabricante, a Microchip. E achei! Um material muito completo e um SDK monstruoso para diversas versões de plataformas PIC. Segue o link:

http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en022889

Nesse link existem documentos técnicos, programas e ferramentas para desenvolvedores sobre o ENC28J60. Lógico que totalmente voltado para a plataforma PIC, também fabricado pela Microchip.

Após algum estudo, resolvi que o caminho era por aí. Bastava traduzir a programação para PIC em Arduino e a camada que eu precisava de aplicação já estava resolvida.

Comecei a estudar essa implementação e percebi que o trabalho seria imenso e que no final eu não saberia como colocar para funcionar. Empaquei de novo.

Foi aí que a idéia da Reta Final apareceu! Decidi utilizar a própria biblioteca do W5100 como base para essa minha nova biblioteca! Pois essa biblioteca eu tenho certeza que funciona e só preciso agora importar a programação que foi feita para o PIC e adicionar na biblioteca do W5100 para Arduino.

Mas o mais interessante dessa implementação é que estou criando um "conector" do ENC28J60 para a biblioteca oficial do Arduino para o W5100. Dessa forma, quem tem um programa já funcionando no Ethernet Shield W5100, bastará substituir alguns arquivos da biblioteca para compilar o mesmo código para o ENC28J60, totalmente transparente!!!

Já avancei bastante com essa Reta Final e agora falta finalizar a implementação que já está bem avançada. Até agora não encontrei nenhum problema impossível, nada que o W5100 que o ENC28J60 não possa fazer com uma camada a mais de aplicação.

Inclusive estou otimizando o uso dos 8K bytes do buffer do ENC28J60 para acomodar os 4 sockets que o W5100 implementa internamente. Separei a memória em 10 pequenos buffers, sendo 2 maiores de 2K bytes e 8 menores de 512 bytes.

O ENC28J60 tem uma funcionalidade muito legal que é a cópia DMA entre partes do buffer. Com isso pretendo copiar os dados de entrada/saida para os buffers independentes dos socketes, implementando exatamente a mesma funcionalidade que o W5100 possui internamente.

Outro detalhe que estou implementando e que não foi implementado em nenhuma outra versão de biblioteca para o ENC28J60 é a utilização da interrupção gerada na chegada de pacotes, para otimizar o desempenho.

Bom, é isso pessoal! Conto com a paciência de vocês para o amadurecimento desse projeto que é o Curso Arduino Automation. Não existe sentido em lançar uma solução parcial, que não atenda totalmente e que seja melhor continuar usando o W5100.

Mas porque não continuar utilizando o W5100? Por dois motivos bem simples: 1. porque ele é caro; 2. porque ele tem problemas de escalabilidade (vide: http://pt.wikipedia.org/wiki/Escalabilidade -- principalmente Carga de escalabilidade).

Para finalizar, essa nova Reta Final vai atender aqueles que esperam que eu faça modificações também na biblioteca EthernetSupW5100, pois agora com a integração da biblioteca oficial Ethernet.h, tudo isso ficará integrado e existirá apenas uma versão de EthernetSup no futuro, dependendo apenas de algumas configurações para funcionar em um modelo de Ethernet Shield ou noutro.

Abraços,
Renato

quarta-feira, 4 de setembro de 2013

Dilema do ENC28J60 - Parte 2

Pessoal,

Boa noite! Estou de volta após alguns contratempos! Infelizmente não dá para fazer projetos de clientes e criar aulas do Curso Arduino. Tive que escolher um e optei pelo último!

Mas para a segunda aula do Curso Arduino Automation, um amadurecimento da biblioteca EthernetSupENC28J60.h, lançada na primeira aula, era necessário.

O problema nem era a biblioteca em si, mas o núcleo dela que tinha alguns BUGs sérios e que comprometiam o funcionamento e a velocidade.

O principal BUG que me fez rescrever totalmente o núcleo, ao invés de apenas arrumá-lo, é um que reinicia o Arduino a cada request, forçando a biblioteca utilizar EEPROM para manter o estado entre os reinícios. Além de comprometer a EEPROM do Arduino, ainda existe o problema do reinício que é ruim por si só.

Por esse e outros problemas, causados principalmente pela pressa que fiz a primeira versão, mudei um pouco a abordagem nesse novo núcleo e o compilei separadamente em uma biblioteca chamada EtherEncLib.h, que acabei de publicar no GitHub, conforme segue o link:

https://github.com/renatoaloi/EtherEncLib

Essa biblioteca é independente e não necessita da EthernetSupENC28J60.h (ainda a ser lançada) para funcionar. Acompanha exemplos de funcionamento. Um deles inclusive apresenta todas as portas digitais disponíveis no Arduino UNO para acionamento, em links numa página HTML.

Para finalizar, devo acrescentar que o desafio dessa vez foi organizar todo o código. São mais de 1500 linhas de funções que não seguem um funcionamento linear. A função available() por exemplo não apenas avisa a chegada de um request, mas também efetua a conversação inicial (handshaking) e alimenta o buffer de parâmetros do GET. Obs: POST ainda não foi implementado

Outra modificação importante foi a separação de parte do código no arquivo enc28j60.c para o arquivo socket.c, isolando de vez as funções de hardware.

Para os mais avançados, vale a pena dar uma olhada nas funções de macros do arquivo net.h, utilizadas no arquivo EtherEncLib.c; e foram isoladas dessa forma para caracterizar funções de leitura e escrita dos buffers.

É isso aí pessoal! A segunda aula já está saindo!

Ah! Pessoal, sobre dúvidas, sugestões sobre este tópico, principalmente as técnicas, participem do:

Fórum do Curso Arduino
http://www.seriallink.com.br/forum

Abraços,
Renato