EtherProg - Gateway RS232/Ethernet

0072

Author:
Sir Pinto de Castro (sirpdc@gmail.com)

Introducao

Os objectivos deste módulo são:

Para efectuar o acesso à Ethernet escolheu-se uma placa ISA com o integrado RTL8019AS, compatível com o NE2000. A abordagem seguida é discutível, mas na opinião dos autores este caminho oferece dividendos maiores, nomeadamente em termos de aprendizagem sobre as questões relacionadas com as implementações e limitações dos protocolos de comunicações. Também traz desvantagens, nomeadamente em termos de esforço despendido e eventual robustez do módulo. Alternativamente, poder-se-ia ter escolhido um módulo ou microcontrolador já com a "engenharia de comunicações" toda desenvolvida (http://www.beyondlogic.org/etherip/ip.htm), mas o valor acrescentado em termos académicos seria reduzido. Se o objectivo do sistema a desenvolver passasse pela comercialização imediata, a opção "chave na mão"(ou seja, adquirir o módulo das comunicações ) seria uma alternativa a considerar seriamente, principalmente na questão "time to market" e robustez, mas no contexto académico é de interesse questionável.

A implementação do sistema for pensada tendo em vista sistemas embebidos, de reduzidas capacidades de memória e de velocidades de processamento modestas. A plataforma escolhida para a implementação recaiu sobre o microcontrolador ATMega16, da família AVR, com 16 kbytes de memória de programas(Flash) e 1024 bytes de memória de dados(SRAM).

Uma vez que já existem implementações da pilha TCP/IP e UDP/IP para sistemas embebidos com qualidade, testadas e robustez assinalável, faz todo o sentido integrá-las no presente trabalho. Uma excelente implementação é a a uIP Embedded TCP/IP stack do Professor Andrew Dunkels(http://www.sics.se/~adam/uip/). É uma implementação diferente do habitual(orientada a eventos), compacta, com diminutos requisitos de memória, testada e com excelente documentação. Os módulos UDP, TCP, ICMP, IP e ARP foram adaptados da livraria uIP. Devido aos constrangimentos temporais apenas foi possível testar e implementar o UDP. Este protocolo de transporte apresenta algumas limitações face ao TCP, nomeadamente ao nível da confirmação de recepção/envio de pacotes. O ideal seria implementar uma solução híbrida, mas mais complexa, em que alguns dados seriam transmitidos em UDP(por exemplo o valor das amostras) e os parâmetros de configuração do módulo de aquisição seguiam em TCP.

As principais tarefas executadas no desenvolvimento deste módulo foram as seguintes:

Arquitectura

arch.png

Figura 1 - Arquitectura do Gateway

Na implementação do gateway seguiu-se uma abordagem por camadas. Cada camada fornece um "modelo de abstracção" das funcionalidades incorporadas no seu interior, proporcionando às camadas adjacentes um conjunto de serviços e funções que esta pode utilizar. Por exemplo, quando a aplicação (nível 5) invoca a função uip_send() (para enviar um pacote) do módulo UDP (nível 4), a aplicação "abstrai-se" dos mecanismos e procedimentos que estão por baixo do nível 4( por exemplo questões de routing, fragmentação de pacotes, resolução de endereços IP's em endereços MAC, entre outros) obtendo apenas a garantia que a trama irá ser enviar pelo interface Ethernet1. Devido á complexidade do sistema, o modelo de camadas também foi aplicado dentro das próprias camadas, ou seja sub-camadas(por exemplo no nível 2). Na Figura 1 está representada a arquitectura do gateway, constituída pelos vários níveis do modelo híbrido TCP/IP.

As low level function fornecem funcionalidades para comunicar com o barramento ISA - leitura de posições de memória(rtl8019_read()) e escrita (rtl8019write()) da placa Ethernet ISA.
O Device Driver NE2000 é capaz de interpretar o conteúdo dos registos do NIC e disponibiliza funções para interagir com este: transmissão de tramas (ei_transmit()) e recepção de tramas(ei_poll()).

O elo de ligação entre a pilha TCP/IP e o Device Driver é o Dispacher. Este módulo está a correr num loop infinito e constitui verdadeiramente o núcleo central do programa, desencadeando todo o processo de recepção/envio de pacotes. O Dispacher invoca periodicamente o device driver para adquirir tramas do NIC, encaminhando-as posteriormente para o módulo superior (módulo ARP ou módulo IP).

O módulo ARP(Address Resolution Protocol) mantém uma tabela com pares MAC/IP para resolver os endereços IP em endereços MAC dos interfaces das máquinas com o endereço IP de destino. Apesar de não aparecer representada na figura(por simplicidade optou-se por não se representar) todos os datagramas recebidos são objecto de tratamento por parte do módulo ARP(para actualizar os pares MAC/IP) e só depois é que são encaminhadas para o módulo IP(ver o capitulo referente ao Dispacher).

O módulo IP ("Internet Protocol") processa os datagramas: verifica o cabeçalho, fragmenta os datagramas2, efectua o rounting, ou seja determina o próximo hop, e encaminha os pacotes recebidos para o módulo de destino(ICMP(icmp_process), UDP(udp_process) ou TCP(tcp_process) ). Para optimizar o processamento dos pacotes, a implementação do ICMP, UDP e TCP estão integrados todos no módulo IP, mais concretamente na função uip_process() apesar de conceptualmente estarem em módulos diferentes.

O módulo ICMP (" Internet Control Message Protocol") responde apenas a ping's e constitui uma excelente ferramenta para testar a conectividade do interface.

O módulo UDP ("User Datagram Protocol") permite distribuir os pacotes pelos processos, diferenciando-os através do número das portas. Neste caso, apenas existe um processo em execução.

Os módulos TCP("Transmission Control Protocol") e o Application(TCP) Module não foram utilizados neste trabalho.

O Application(UDP) Module é invocado pelo módulo UDP para responder a determinados eventos(tipicamente recepção de pacotes). A função de encaminhamento de pacotes esta implementada no Application(UDP) Module. Após a recepção dum pacote o Application(UDP) Module encaminha-o para Aquisition Module através dum canal RS232( ou seja retransmite-o) e permanece à espera da resposta . O gateway está intrinsecamente ligado ao protocolo de aplicação, baseado no modelo Master-Slave ( apenas o Master faz perguntar e o Slave responde), o que permite simplificar o encaminhamento e a sincronização entre os módulos. O gateway utiliza esse facto quando encaminha o pacote, pois sabe de antemão que o Slave(Aquisition Module) irá ter sempre que responder á pergunta/pedido efectuada pelo Master(o PC). Quando o gateway terminar de receber a resposta do Aquisition Module, envia-a para o endereço IP e porta do computador que efectuou o pedido. A partir do momento que o Application(UDP) Module indica que quer enviar um pacote, dá-se inicio ao processo inverso(iniciado no Dispacher) para o envio da trama de resposta.

Para melhor se compreender o processo de tratamento de pacotes, a Figura 2 ilustra a interacção entre os vários módulos do gateway aquando a recepção dum pacote destinado ao nível de aplicação.

seq.png

Figura 2 - Diagrama UML de sequência, ilustrando a interacção entre os módulos aquando a recepção dum pacote destinado ao nível de aplicação

O processo inicia-se no dispacher, através da invocação da função ei_poll do device driver para aquisição duma trama ao NIC. Após adquirir a trama, o dispacher entrega-a temporariamente ao módulo ARP( uip_arp_ipin() ), a fim de actualizar os pares MAC/IP, e encaminha-a para o módulo IP ( uip_process() ). Este módulo verifica o cabeçalho do datagrama e entrega-o à camada superior ( módulo UDP, através do udp_process() ). Este módulo apenas verifica se o gateway está à escuta da porta a que o pacote se destina. Em caso afirmativo invoca o nível de aplicação, através do UIP_UDP_APPCALL(). É neste módulo que reside a verdadeira essência do gateway: encaminha o pacote para o canal RS232 ( TxFrame() ), aguarda por uma resposta ( RxFrame() ) e por fim encapsula-a para poder ser enviar pela Internet (uip_send() ). Desde a leitura por parte do Dispacher, o pacote foi "desencapsulado" progressivamente, subindo na pilha TCP/IP até atingir o módulo de aplicação. Para enviar o pacote de resposta, este irá ter de "descer" pela pilha TCP/IP, ou seja efectuar o percurso inverso. Após o términos do processamento do módulo de aplicação, o módulo UDP troca as portas, troca os endereços IP e recalcula o checksum para poder responder ao computador que efectuou o pedido. Logo após a conclusão do processamento do módulo IP( basicamente preenche o cabeçalho do datagrama), o dispacher envia o pacote para o módulo ARP para construir o cabeçalho Ethernet e por fim invoca a função ei_transmit() do device driver para enviar a trama.
Generated on Fri Jan 6 22:23:16 2006 for EtherProgs by  doxygen 1.4.5