HOME      PROJETOS      PROGRAMAÇÃO     

WEB SERVER NO PIC18F4620




INTRODUÇÃO

Este projeto explica como montar um servidor de web (HTTP) num microcontrolador PIC18F4620 usando o Stack TCP/IP que a Microchip fornece gratuitamente para ser embarcado em seus microcontroladores. Isso deveria facilitar a tarefa de programação pois o Stack TCP/IP contem todos os protocolos necessários para comunicação em rede mas, para muitos hobistas e curiosos da eletrônica digital, não é tão simples como parece. Além da literatura estar em inglês, muitas coisas não são explicadas adequadamente ficando um abismo profundo entre a vontade de fazer a coisa funcionar e a possibilidade prática de executar o circuito e a programação. Como se isso não bastasse, ao abrir a pasta de exemplos e demos, que acompanha o Stack TCP/IP da Microchip, muitos vão se surpreender ao descobrir que todos os software foram escritos para suportar somente as placas de desenvolvimento homologadas pela Microchip, sem considerar que todos os programas são escritos em linguagem C, mais especificamente o C18.




OBJETIVOS

O objetivo principal deste projeto era embarcar o TCP/IP num microcontrolador simplesmente espetado num protoboard, e que pudesse responder a alguns comandos vindos do browser (Firefox, Opera, GoogleChrome, etc). Depois de vários dias pesquisando, encontramos o site do Jorge Amodio onde havia um projeto que embarcava um Stack TCP/IP e um servidor de web num microcontrolador PIC18F4620. Analisando o projeto, verificamos que haviam várias características indesejáveis que tornavam o projeto um pouco complexo para nossos objetivos. No projeto analisado havia um controle para display de mensagens num LCD, uma memória EEPROM externa onde seria gravado o sistema de arquivos do servidor de web, comunicação com o PC através da USART com um chip MAX232.

Além disso, para fazer a conexão com a rede, ele usava um chip ENC28J60 e um conector MagJack J45 acoplados com uma porção de outros componentes passivos (resistores, capacitores e bobinas) que complicavam a execução do circuito.

Após uma revisão, os periféricos LCD, EEPROM externa e o chip MAX232 foram eliminados. O chip ENC28J60 e o conector MagJack J45 configurados no esquema foram substituidos por uma placa da HanRun com um ENC28J60 integrado com um soquete MagJack J45 que já fornece a conexão com a rede Ethernet, facilitando em muito a vida do pobre curioso ou hobista que pretenda montar esse circuito. O único trabalho vai ser montar um cabinho para conectar a placa ao protoboard ou ao PCB.

A foto a esquerda mostra a placa da HanRun que, no Brasil, pode ser adquirida em lojas de eletrônica ou pela Internet pelo site Mercado Livre. Para quem quiser montar o projeto original, espetando chip ENC28J60 e o conector MagJack J45 no protoboard, aqui está o esquema elétrico.




O CIRCUITO

Este projeto já foi testado no protoboard com sucesso, mas ainda não foi montado em PCB, por isso, para quem quiser fazer o PCB, o arquivo de Projeto Eagle com o esquema elétrico está disponível aqui.

A imagem abaixo mostra o esquema elétrico do nosso projeto simplificado com os seguintes componentes:

  • Um microcontrolador PIC18F4620
  • Uma placa da HanRun adquirida no mercado
  • Um integrado CMOS 74ACT125N (three-state buffer não-inversor) ENC28J45 ao PIC
  • Tres chaves tácteis
  • Cinco LEDs
  • Um cristal de 10MHZ
  • Um regulador de tensão 7805
  • Alguns capacitores, diodos e resistores.






A PLACA HanRun

A placa da HanRun contem um microcontrolador ENC28J60 com o protocolo Ethernet embarcado para facilitar a tarefa de comunicação com esse tipo de rede. Essa placa executa a mesma função da placa de rede Ethernet do seu PC.

O microcontrolador PIC18F4620 é alimentado com 5,0V porém, a placa ENC28J60 deve ser alimentada no máximo com 3,3V, obrigando o uso de um regulador nessa faixa de tensão. No nosso projeto foram usado dois diodos 1N4148 que provocam uma queda de tensão de aproximadamente 0,7V cada um, fazendo com que a tensão caia de 5,0V para 3,6V. Isso pode ser feito com segurança pois o regulador de tensão de entrada 7805, fornece uma tensão nominal de 5,0V que na verdade fica entre 4,7V e 5,0V. Assim temos...

4,7v - (2 x 0,7v) = 3,3V no mínimo e
5,0v - (2 x 0,7v) = 3,6V no máximo

...que é perfeitamente seguro e mais que suficiente para alimentar a placa.

Aqui não vamos discutir em profundidade o funcionamento placa da HanRun mas apenas prestar atenção na sua pinagem. A placa possui 10 pinos emparelhados 5 a 5. Observando a foto do lado esquerdo, que não está muito nítida, podemos notar duas colunas de pinos verticais.

A coluna de pinos da esquerda, de cima para baixo, apresenta os sinais CLKOUT, WOL, SI, CS e VCC.

A coluna de pinos da direita, de cima para baixo, apresenta os sinais INT, SO, SCK, RESET e GND.

Esses pinos devem ser conectados aos pinos correspondentes do esquema elétrico. Notar que os pinos CLKOUT, WOL não são usados neste projeto e ficam desconectados.

Para conectar essa placa ao protoboard foi montado um cabinho com conectores Modu que organizam a interface e simplifica a conexão.
No protoboard foi inserida uma barra de pinos verticais onde o cabinho foi conectado. A foto do lado direito mostra como ficou a ligação da plaquinha no protoboard.




POR QUE USAR UM PIC18F4620 NESTE PROJETO?

O microcontrolador PIC18F4620 foi escolhido para este projeto por ter uma capacidade de memória de programa suficiente para embarcar o Stack TCP/IP com um servidor HTTP (Web Server) e ainda poder alojar, na mesma memória, o sistema de arquivos que contem as páginas HTML e arquivos de imagens que serão usados pelo Web Server.




O OSCILADOR DE 40MHZ

Neste projeto o PIC18F4620 deve operar com um cristal de 10MHZ. Essa frequência deverá ser quadruplicada usado a opção HSPLL que habilitará o PLL interno, fazendo com que o microcontrolador atinja uma frequência de operação de 40MHZ. Isso é necessário pois o PIC vai ter que suar um bocado para atender a requisição de páginas pelo Web Server. O hobista não precisa se preocupar pois todos esses detalhes já estão definidos no programa. Basta apenas usar um cristal de 10MHZ ou menos na montagem do circuito. Pode-se usar cristais com frequências menores porém a performance vai cair. Nunca use um cristal de frequência superior a 10MHZ a menos que o programa seja recompilado com a configuração HS que desabilita o PLL.

Após montar corretamente o circuito (confira N vezes, sendo N > 9), faça o download do Projeto WebServer para o MPLAB e descomprima o arquivo.

Para poder recompilar o programa deste projeto é necessário que o MPLAB possa acessar o compilador C18.




O 3-STATE BUFFER 74ACT125N

Os pinos INT e SO da placa HanRun fornecem no máximo 3,3V de tensão para o nível lógico alto (1). O PIC deve receber uma tensão nominal de 5,0V para entender que se trata de um sinal no nível alto. Para ajustar o nível da tensão enviada ao PIC pela placa HanRun, é empregado um 3-STATE BUFFERR 74ACT125N que tem somente essa função.




MONTAGEM NO PROTOBOARD
FUNCIONA!!!




O STACK TCP/IP E O MODELO MULTITAREFA COOPERATIVA

O Stack TCP/IP da Microchip é um conjunto de protocolos semelhantes ao verdadeiro TCP/IP usado nos computadores reais e seu objetivo é permitir que um microcontrolador seja conectado à rede e responda a requisições de modo transparente, isto é, como se fosse um computador real. Nem todas as funções estão presentes no Stack da Microchip mas podem ser programadas pelo usuário.

O TCP/IP tradicional roda sob um sistema multitarefa que é gerenciado pelo sistema operacional do host (Linux, Windows).
Um modelo multitarefa é exigido quando muitos serviços devem ser executados simultaneamente.
Como o Stack TCP/IP vai rodar num microcontrolador e não sob um sistema operacional, ele próprio é construido para proporcionar um modelo de multitarefa chamado Multitarefa Cooperativa. Em poucas palavras, o modelo cooperativo implica em dividir a aplicação em pequenas partes (módulos) e colocá-las sob controle de um laço (loop) no programa principal que despachará cada uma. A tarefa despachada é então executada e retorna o controle ao programa principal que despachará a próxima tarefa.

O trecho de código abaixo exemplifica como isso acontece no módulo main.c que se encontra em /webserver_v04/src/main.c. As tarefas "StackTask()", "HTTPServer()" e "DiscoveryTask()" são despachadas nessa ordem pelo laço infinito "while(1)" fazendo nosso web server funcionar.

     while(1)
     {
         if ( TickGetDiff(TickGet(), t) >= TICK_SECOND/2 )
         {
           t = TickGet();
           LED0_IO ^= 1;        // pisca o LED1
         }

         StackTask();           // Executa serviços do TCP/IP
         HTTPServer();          // Executa o web server
         DiscoveryTask();       // Executa a função announce
     }

O Stack TCP/IP deverá ser carregados no PIC juntamente com um programa aplicativo que executará as tarefas do Web Server. Como o Stack possui muitos módulos e muitos deles eram desnecessários para nosso objetivo, somente alguns deles foram carregados para compilar nosso Web Server.




O ENDEREÇO IP

O endereço IP configurado no programa deste projeto é 192.168.0.60.

Se sua rede possui endereço 192.168.0.0 e seu Gateway tem o endereço 192.168.0.1, então pode se considerar com sorte porque nenhuma alteração será necessária para rodar o programa. Continue lendo a partir do ítem GRAVANDO O PROGRAMA.

Se sua rede tem endereço diferente de 192.168.0.0, então será necessário configurar o programa para refletir o endereço de sua rede. Para isso, abra no MPLAB o projeto PIC10T.mcp, que se encontra na pasta webserver_v04, edite o arquivo config.h, que se encontra na aba Headers da janela Projetos, altere as seguintes linhas desse arquivo para configurá-lo com as características de sua rede:

LINHA 25 ..... #define DEFAULT_IP_ADDRESS { 192, 168, 0, 60 }   endereco IP da sua rede
LINHA 26 ..... #define DEFAULT_NETMASK { 255, 255, 255, 0 }   mascara
LINHA 27 ..... #define DEFAULT_GATEWAY { 192, 168, 0, 1 }   endereco do seu Gateway
LINHA 28 ..... #define DEFAULT_NS1 { 192, 168, 1, 1 }   endereco do NS

Atenção, nas linhas acima os números que formam os endereços devem ser separados por vírgula.

Salve o arquivo e recompile o programa.




GRAVANDO O PROGRAMA

A gravação do PIC18F4620 deverá ser feita com um programador ICSP ou algum outro programador que possa ser reconhecido pelo MPLAB e que suporte o microcontrolador PIC18F4620.

Se optar por um programador tipo JDM/ICSP use o programa WinPic800 pois ele possui suporte para gravação do PIC18F4620.
Na configuração do WinPic800, deve-se selecionar o programador JDM.

O programa ICPROG ainda não possui suporte para esse microcontrolador.

Após selecionar o programador, carregue o arquivo /webserver_v04/bin/PIC10T.hex e grave no PIC18F4620.




TESTANDO O PROGRAMA

Ligue a alimentação e, se tudo correu bem, o LED 1 começará a piscar.

Abra seu browser preferido e, na linha de comandos, digite o endereço IP configurado para o circuito, neste caso http://192.168.0.60 e a seguinte página deverá aparecer:

Clique no botão Iniciar e a página da aplicação vai aparecer.

Nesta tela pode-se interagir com o circuito.

A cor azul representa o LED1 que está piscando no circuito.

Os botões L1, L2,L3 e L4 podem ser clicado para acender e apagar os respectivos LEDs. Quando o servidor recebe a solicitação, o estado do LED clicado muda e a cor que representa seu estado na página é alterada.

O botão Blink faz com que os LEDs pisquem durante alguns segundos.

O botão Toggle inverte o estado dos LEDs, isto é, os que estão apagados se acenderão e vice-versa.

O botão Reset apagará todos os LEDs.

As cores verdes do lado direito B1 e B2 representam as chaves tácteis nomeadas BOTAO 1 e BOTAO 2 no esquema elétrico. Quando uma ou ambas as chaves forem pressionadas no circuito, as cores mudarão de verde claro para verde escuro na página.

A página é refrescada a cada segundo por um Java Script fazendo com que o servidor envie o estado em que as variáveis apresentam no momento.

Aqui concluimos a parte braçal deste projeto. Agora vamos tentar entender um pouco como tudo funciona para que um dia possamos fazer algo útil com isso.





CONFIGURANDO O HARDWARE

O hardware do projeto é configurado no arquivo /webserver_v04/src/include/spin2.h. Veja a listagem abaixo:

",">",$reg); $num = "....".$n; echo substr($num,-4)." ".$reg."
\n"; $n++; } fclose($DD1); ?>

Algumas coisas importantes devem ser observadas na listagem acima:

  1. A linha 4 inclui o arquivo referente ao microcontrolador em uso, o PIC18F4620.

  2. A linha 8 define a frequência de clock na qual o microcontrolador vai operar. A configuração de clock já foi discutida anteriormente, assim, se desejar modificar a frequência de clock, deve considerar a modificação do valor do parâmetro CPU_CLOCK nesta linha.

  3. Da linha 12 até a linha 89 são mapeadas as portas do PIC18F4620. Qualquer referência a uma porta ou a um bit de uma porta deve ser feito usando-se as definições estabelecidas nessas linhas. Assim, se em algum lugar do programa você desejar acender o LED1, deverá usar a referência LED1_IO conforme definido na linha 77.

  4. Da linha 92 até a linha 102, estão as definições dos registradores do ENC28J60. Jamais altere essas definições, senão...





CONFIGURAÇÃO DO TCP/IP

A configuração do TCP/IP é feita no arquivo webserver_v04/src/include/config.h>. Veja a listagem abaixo.

",">",$reg); $reg = str_replace(" "," ",$reg); $num = "....".$n; echo substr($num,-4)." ".$reg."
\n"; $n++; } fclose($DD1); ?>

Algumas coisas importantes devem ser observadas na listagem acima:

  1. As linhas de 24 a 31 refletem as características de sua rede. Como já foi dito anteriormente, se sua rede tem o endereço 192.168.0.0, nada deve ser modificado neste arquivo mas, se sua rede não possui esse endereço, as modificações devem ser feitas nessas linhas.

  2. A linha 31 define o nome Netbios do nosso circuito na rede. Qualquer nome pode ser atribuido aqui.

  3. Outra coisa importante a observar são as linhas de 37 a 39. Essas linhas definem os protocolos do Stack TCP/IP que devem ser usados no projeto.





HTTP - O SERVIDOR

Talvez seja desnecessário definir aqui o que é um web server mas, vamos relembrar:

Um web server é um programa que atende requisições HTTP que é uma sigla que significa "HyperText Transfer Protocol".
Esse protocolo pertence à camada de aplicação do modelo OSI.

Uma requisição para um web server geralmente é feita por um browser com o comando GET, mais precisamente:

GET nome_do_arquivo HTTP/1.1

Quando essa requisição chega ao web server, ele procura em seu diretório pelo arquivo requisitado em "nome_do_arquivo", lê esse arquivo e o devolve ao browser solicitante. O arquivo devolvido ao cliente é, na maioria das vezes, um arquivo texto escrito em linguagem HTML. Assim, o web server nada mais é do que um servidor de arquivos.

Além disso, um bom web server deve responder certas requisições e produzir respostas dinâmicas, como por exemplo, enviar uma página ao browser com o resultado de uma pesquisa. Isso também pode ser feito com o comando GET, acrescentando alguns parâmetros na requisição como:

GET nome_do_arquivo?campo1=valor1&campo2=valor2&campo3=valor3 HTTP/1.1

Na requisição acima, na frente do "nome_do_arquivo", temos o caracter "?" informando ao web server que o texto que vem a seguir contem uma série de pares "nome=valor" separados por um caracter "&". Ao identificar esse tipo de requisição, o web server verifica se o arquivo informado em "nome_do_arquivo" é um executável e, em caso positivo, passa o controle para esse arquivo processar a tarefa usando os pares "nome=valor" como parâmetros. O arquivo informado em "nome_do_arquivo" ganha controle, processa as informações e devolve uma resposta dinamicamente, enviando linhas de texto HTML de volta ao browser.

Além de GET há outro método chamado POST mas não vamos discutí-lo aqui para não alongar muito o assunto.

Os métodos "GET" e "POST" são usados em formulários HTML que facilitam a aquisição de dados através do browser como no exemplo abaixo:

<form method="GET" action="nome_do_arquivo">
<input name="campo1" value="valor1">
<input name="campo2" value="valor2">
<input name="campo3" value="valor3">
<input type="submit" value="ok">
</form>

Ao acionar o botão OK, o formulário acima envia ao servidor uma requisição do tipo:
GET nome_do_arquivo?campo1=valor1&campo2=valor2&campo3=valor3 HTTP/1.1

Num web server como o Apache, rodando num computador, o processo dinâmico de geração de páginas é conseguido através da execução de programas chamados CGIs que podem ser escritos em linguagem C ou Perl e também por módulos especializados como o PHP. Concluindo, os processos de geração de páginas dinâmicas são os responsáveis pela força de todos os produtos que hoje rolam pela Internet.





HTTP - O SISTEMA DE ARQUIVOS

Como dissemos anteriormente...

"Quando uma requisição chega ao web server, ele procura em seu diretório pelo arquivo requisitado em "nome_do_arquivo", lê esse arquivo e o devolve ao browser solicitante..."

No caso de um web server, como o Apache, que roda num servidor e atende muitas requisições, as páginas escritas em HTML devem ficar gravadas em algum diretório do sistema de arquivos do computador.

Nem é preciso dizer que: um web server rodando num microcontrolador como o PIC18F4620 não pode ser comparado a um web server Apache rodando num computador, mesmo que seja num pequeno desktop.

Assim, nosso sistema de arquivos não poderá ser tão grande que não caiba dentro do microcontrolador e nem muito pequeno que não possa armazenar algumas páginas e figuras.

Por simplificação, nosso projeto propõe usar a memória de programa do PIC18F4620 para armazenar o sistema de arquivos. Isso vai limitar a quantidade de espaço de armazenamento necessário porém, vamos ganhar em velocidade de acesso, facilidade de programação e praticidade na manutenção das páginas.

As páginas necessárias para nosso projeto estão na pasta /webserver_v04/web. Nessa pasta encontram-se os arquivos "index.htm", "index.cgi" e "mchp.gif". Esses arquivos são suficientes para demonstrar o funcionamento de um web server que responde a requisições e gera páginas HTML dinamicamente, como veremos mais para frente em Execução de Comandos e Substituição de Variáveis.

Como o sistema de arquivos deve residir na memória de programa, teremos que, de alguma maneira, fazer com que a pasta /webserver_v04/web seja gravada nessa memória. Para fazer isso, há um programa utilitário fornecido pela Microchip chamado "MPFS.EXE" que se encontra na pasta "/webserver_v04/tools/MPFS.EXE".

Para formatar o sistema de arquivos siga os passos:

  1. No menu Iniciar do Windows, abra a opção Executar e digite cmd.

  2. Na tela preta do Prompt de Comandos digite cd /webserver_v04/tools e tecle Enter.

  3. Execute o programa digitando o comando:
    MPFS   /webserver_v04/web  mpfsimg.c  /c
    Isso vai gerar o arquivo mpfsimg.c na pasta atual cd /webserver_v04/tools.

  4. Edite o arquivo mpfsimg.c e, na linha 11 ou próximo dela, substitua no comando #include o nome de arquivo Compiler.h por config.h e salve em seguida.

  5. Copie o arquivo mpfsimg.c para a pasta /webserver_v04/src/.

  6. Recompile o programa e regrave o microcontrolador.

Lembre-se, o arquivo "PIC10T.hex" que se encontra na pasta "/webserver_v04/bin/PIC10T.hex" já tem o sistema de arquivos embutido e esta pronto para ser usado. A recompilação do programa só deve ser feita se você quiser modificar o conteúdo das páginas ou reconfigurar o endereço da rede.





HTTP - EXECUÇÃO DE COMANDOS

Como vimos anteriormente, o web server pode responder a uma requisição gerando páginas dinamicamente.
Uma requisição do tipo GET nome_do_arquivo?campo1=valor1&campo2=valor2&campo3=valor3 HTTP/1.1 pede ao web server para executar o programa especificado em "nome_do_arquivo" e pede ao web server que passe para esse programa os parâmetros "campo1=valor1&campo2=valor2&campo3=valor3".

Pelo fato do web server presente no Stack TCP/IP da Microchip precisar ser muito simples, algumas modificações foram feitas para adaptá-lo à realidade de um microcontrolador. Convencionou-se, então, que a requisição passada para o web server pelo GET será: "GET CMD?c1=v1&c2=v2&....cn=vn" onde:

  • CMD é um número de comando.

  • c1 a cn são números de argumentos

  • v1 a vn são os respectivos valores dos argumentos.

Além disso, o web server do Stack TCP/IP da Microchip deixa a cargo do desenvolvedor escrever uma função para detetar os parâmetros e executar a ação requerida pelos comandos CMD. Toda vez que uma requisição com mais de um argumento for passada ao web server, ele chamará a função "HTTPExecCmd()" para realizar essa tarefa.

Supondo que uma requisição     GET 0?3=12&4=x     tenha sido feita ao web server, este deve interpretar os argumentos e armazená-los na variável argv da seguinte maneira:

  • argv[0] => 0 ........... número do comando; geralmente o valor de um ACTION de um formulário
  • argv[1] => 3 ........... número do argumento; geralmente o nome de um campo de formulário
  • argv[2] => 12 .......... valor do argumento
  • argv[3] => 4 ........... número do argumento; geralmente o nome de um campo de formulário
  • argv[4] => x ........... valor do argumento

A função "HTTPExecCmd()" esta definida na linha 358 do módulo /webserver_v04/src/main.c.

Os números de comandos (CMD) devem ser definidos através macros como, por exemplo, o comando 0 (zero) esta definido com a macro #define CGI_CMD_DIGOUT (0) (ver linha 270 do módulo main.c).

Abra o arquivo main.c e estude como a função "HTTPExecCmd()" trabalha pois um exemplo vale por mil palavras.





HTTP - SUBSTITUIÇÃO DE VARIÁVEIS

Como não poderia deixar de ser, além de executar os comandos, o web server também deixa a cargo do desenvolvedor a substituição de variáveis no texto a ser devolvido ao browser quando a resposta é dinâmica. Isso é feito pela função "HTTPGetVar()" que esta definida na linha 358 do módulo /webserver_v04/src/main.c.

Toda variável deve ser definida com o uso de macros, tal como na linha 277 do do módulo main.c e podem haver até 255 variáveis diferentes.

Uma variável que deve ser substituida por um valor, deve ser referenciada pelo caracter "%".
Veja, por exemplo, o arquivo /webserver_04/web/index.cgi listado abaixo:

",">",$reg); $reg = str_replace(" "," ",$reg); $num = "....".$n; echo substr($num,-4)." ".$reg."
\n"; $n++; } fclose($DD1); ?>

Na linha 14 temos a referência %24 e a linha 15 temos %25, que correspondem respectivamente as variáveis VAR_MSG1 (0x24) e VAR_HITSCNT (0x25) definidas nas linhas 306 e 307 do módulo main.c.

Nas linhas de 29 a 35 temos as referências %00, %01, %10, %11, %12, %04 e %0D que correspondem respectivamente as variáveis VAR_LED1, VAR_LED2, VAR_LED3, VAR_LED4, VAR_DIGIN0 e VAR_DIGIN1 definidas a partir da linha 277 de main.c.

Além disso, o web server substitui um caracter por vez de cada variável, chamando a função "HTTPGetVar()" para cada caracter a ser substituido. A função "HTTPGetVar()" deve então verificar se é o início ou fim da variável entes de continuar. O trecho de código abaixo, retirado das linhas 535 a 547 do módulo main.c, exemplifica o que tentamos dizer:

   case VAR_MSG1:
     if( ref == HTTP_START_OF_VAR )
     {
        strcpy(VarString, msg001);
     }
     *val = VarString[(BYTE)ref];
     if(VarString[(BYTE)ref] == '\0')
        return HTTP_END_OF_VAR;
     else if(VarString[(BYTE)++ref] == '\0' )
        return HTTP_END_OF_VAR;
     return ref;




CONCLUSÃO

Para saber mais, é necessário abrir os arquivos que compõem o Stack TCP/IP e analisá-los com cuidado. Divirta-se...

Longe de mim esperar que essa página tenha servido para sanar totalmente suas dúvidas. Espero apenas ter acendido uma vela para iluminar a escuridão que envolvia o assunto.



Índice dos circuitos




H P S P I N

Desde 04 de Março de 2010

Atualização: 14 de Nov de 2024