segunda-feira, 23 de janeiro de 2012

Compilador MiniJava


Desde quando comecei meus estudos de computação e aprendi a primeira linguagem de programação, C, eu tenho a curiosidade de entender o funcionamento de um compilador.

Ficava fascinado pelo fato de um programa transformar um arquivo texto contendo construções da linguagem, em outro arquivo contendo código que uma máquina consegue compreender preservando a semântica, ou seja, seu significado. Esse é o processo de compilação.

Para iniciantes, isso fica um pouco abstrato porque o foco inicial é aprender a programar e não como funciona um compilador.
Finalmente, no meu 7° período de curso (bem que poderia ser antes!) tive a oportunidade de, não só entender todo esse processo de compilação, mas também construir um compilador seguindo as etapas de projeto. Cursei a disciplina Compiladores ministrada pelo professor Marcus Ramos o qual agradeço a paciência e disponibilidade para tirar dúvidas e compartilhar seu conhecimento, o que possibilitou a realização desse trabalho!

A linguagem usada para a construção foi MiniJava. Ela é uma versão reduzida do Java. Possui apenas construções simples e comandos básicos como if, while, System.out.println(), permite criação de métodos e atributos de classe e possui apenas tipos int, boolean, objeto e vetor de int.

Como nosso tempo foi curto (pouco menos de 2 meses, porque antes tivemos que ver a teoria que envolve a construção de compiladores), algumas decisões de projeto tiveram de ser tomadas para que pelo menos algo de cada etapa (análise sintática, análise de contexto e geração de código) pudesse ser feito.

A análise sintática consiste em reconhecer os símbolos (tokens) a partir da leitura de um arquivo texto de entrada e verificar se eles respeitam as regras gramaticais da linguagem fonte (no caso foi usada uma BNF estendida que pode ser encontrada aqui).

Na semântica, já com os tokens corretamente reconhecidos, o programa é verificado se está correto agora observando o significado das construções. Basicamente acontece a identificação (reconhecimento de variáveis e métodos) e vinculação (vincula cada uso de variável com sua declaração). Possíveis erros são facilmente identificados e mensagens exatas podem ser emitidas nessas etapas.

E, por fim, geração de código. Com o programa bem escrito e com o significado correto perante as regras da linguagem, as instruções podem ser traduzidas passo a passo para linguagem de máquina. Gerando o PUSH para reservar espaço para variáveis, STORE para guardar valores, LOAD para carregar valor de um registrador, JUMP para desvios, dentre outras. Essas são algumas básicas, cada máquina possui seu conjunto de instruções.

No nosso caso, o código de máquina foi gerado com base em uma máquina abstrata usada a partir do livro base da disciplina (link dele aqui), o TAM (Triangle Abstract Machine).

Aqui nesse link você encontra o arquivo compactado contendo o executável do compilador em bytecode juntamente com uma classe de exemplo. Também há um manual explicando como que instala e usa o compilador! Fique à vontade para testar e comentar.

Um abraço,
Bruno Pinho.

sexta-feira, 13 de janeiro de 2012

Dropbox no Debian Squeeze



Recentemente instalei o dropbox no Debian Squeeze e ele não funcionava de modo algum. Usei os pacotes .deb do site oficial tanto para Ubuntu quanto Debian e todos davam o mesmo problema: não encontrava um arquivo 'dropbox' no diretório /home/user/.dropbox-dist/ sendo que ele estava lá.

Tentei instalar pelo codigo fonte, compilei tudo mas não funcionou também. Mesmo erro. Depois de tanto procurar, resolvi tentar uma dica do site do dropbox mas o download falhava. Ate que encontrei uns arquivos compactados. Fiz o donwload versão x86 (versão 64 bits) deles e extraí para a minha pasta home. Entrei no diretório .dropbox-dist e executei o daemon do dropbox: ./dropboxd

A partir daí ele baixou uns arquivos de instalação e pude usá-lo normalmente. Para criar o atalho, pode ser na mão, mas se já tiver a versão instalada a partir do .deb, basta apagar o diretorio .dropbox-dist e substituí-lo pelo baixado do site como fiz acima. Pronto, agora o seu dropbox funciona tranquilamente no Squeeze!

Depois de vasculhar e tentar sem sucesso inúmeras vezes pelo .deb, consegui resolver o problema.
Espero que tenha ajudado!

3DSP? Nunca mais!


Placa wireless 3DSP
Hoje venho compartilhar com vocês, usuários de notebook MUB (Microboard Ultimate Black) da Microboard que vem com a placa de conexão wireless 3dsp de fabricação chinesa, o fim dos meus problemas com a rede sem fio. Recentemente instalei o Windows Seven e, ao instalar o driver da dita placa e usá-lo, volta e meia dava a famosa tela azul. Não sei por que isso, mas o problema era por conta da placa. Sempre a usei no Xp e sempre funcionou bem, não tenho do que reclamar. No entanto, eu gosto de usar Linux e na versão open source dos drivers o negócio é um pouco complicado.

Eu tenho a preferencia pela distro Debian. Mas eu tinha uma barreira que impedia de usá-lo. Os drivers não funcionavam corretamente. Para compilar era um trabalho e tinha que renomear uns diretórios e mesmo assim não funcionava. Quando pensava estar tudo ok, a placa não tinha um bom desempenho. Instabilidade na conexão e superaquecimento do meu note são só 2 problemas que listo... Só havia uma distribuição Linux em que os drivers funcionavam corretamente: Ubuntu. Você baixava o pacote .deb e instalava numa boa. Só que eles tinham limitação de versão do kernel e, sempre na próxima versão do Ubuntu que sair e tiver uma atualização do lernel, o drive pára de funcionar. Então teria que e esperar sair o pacote pré-compilado para a próxima versão do Ubuntu. Ou seja, sempre ficava dependendo do pessoal desenvolver o próximo pacote para a versão... Isso não é uma coisa boa!

Mas há o código fonte, você poderia compilar e resolver o problema... Não! Simplesmente esse código fonte só funcionava também no Ubuntu. Tentei inúmeras vezes instalar no Debian mas aí aparecia a famosa frase dessa placa quando abria o seu gerenciador: “no valid wireless device”.

Então, já cansado de ficar limitado a usar ao o Ubuntu,  abdiquei do bluetooth (só para lembrar, a 3dsp possui wireless e bluetooth na mesma placa) e a troquei. Antes de tudo, precisava pesquisar quais placas teriam suporte no Linux ou pelo menos drivers que funcionassem. Isso pode ser visto para o Debian aqui. Achei duas placas de nome no mercado que teria suporte no Linux: atheros e rtl. Não achei atheros com preço acessível. Então parti para a rtl. Mas possuem 3 versões. Eu optei pela rtl8187b da azurewave. Além de ter suporte, possui drivers open source. E, para nossa alegria, o Debian Squeeze já possui módulo para essas placas: rtl8187. Bastava então instalá-lo e carregar. 

Placa RTL8187B da Azurewave
Comprei a placa Minipci no valor de 39 reais. Abri o notebook e fiz apenas trocar pela 3dsp reconectando os cabos da antena da mesma maneira que estavam. Liguei o notebook e pronto. Tanto o Windows quanto o Linux reconheceram automaticamente o driver. Fiquei surpreso já que tinha separado os drivers.. Mas o importante é que agora tenho a liberdade de escolher qualquer distribuição Linux porque essa placa tem suporte em muitas versões do kernel e o código fonte esta disponível para instalação manual. E, na pior das hipóteses, pode usá-la com o ndiswrapper. A 3dsp não funcionava com o ndiswrapper porque não possui o arquivo necessário.    

Então, para aqueles que ainda têm dor de cabeça com essa placa, segue mais uma experiência de alguém que resolveu trocá-la para ter melhor desempenho e liberdade com seu notebook MUB!

quinta-feira, 22 de setembro de 2011

Vídeo - Comando fork() no Linux

Bem pessoal, segue abaixo uma vídeo-aula que fiz explicando como se cria processos no ambiente linux usando o comando fork().


domingo, 11 de setembro de 2011

O que são Microcontroladores?


Alguém já ouviu falar em microcontrolador e ficou se perguntando o que é e para que serve? Pois é, imagine um computador em miniatura que possui um conjunto reduzido de instruções mas que é capaz de controlar inúmeras coisas como a temperatura do seu forno microondas, a temperatura de um dado ambiente e até acionar motores! O objetivo é criar um dispositivo que seja semelhante ao chip de processador usado em seu notebook ou desktop mas seja projetado para aplicações específicas e que exija bem menos potência para funcionar. Foi então que surgiu o PIC (Programmable Interface Controller ou controlador de interface programável) fabricado pela Microchip. Dentro desta "pastilha" preta cheia de pinos acima, há inúmeros módulos, por assim dizer, que possuem características importantes para o funcionamento do conjunto.

Aí dentro encontramos diversos dispositivos de entrada e saída e periféricos. Ou seja, encontramos um conversor Analógico/Digital, memória, uma CPU para processar os dados, dentre outros. O conversor serve para obter dados provenientes de sensores e convertê-lo para um sistema que seja fácil do computador interpretar. Os dados que estão na natureza possuem muitas vezes natureza analógica, ou seja, sinais contínuos no tempo. Os computadores só entendem 0 e 1, então é preciso converter esse sinal contínuo em uma sequência de zeros e uns!!
A memória é usada para guardar o programa que a gente faz usando a linguagem C, por exemplo, dentro do chip para ele poder ser executado, e, ao ser desligado, o seu conteúdo não seja perdido!
E também uma memória volátil, aquela que os dados são perdidos quando tiramos a alimentação (energia).

O uso desses componentes pequenos está cada vez mais comum hoje em dia já que sistemas específicos e projetos direcionados são cada vez mais necessários. Você aí, se tiver uma fazendo e quer que a sua irrigação seja monitorada 24horas por dia para que não haja prejuízos, com certeza você pode "encomendar" um sistema desse de um Engenheiro por exemplo. Ele vai desenvolver o programa e adquirir os sensores corretos para monitorar e quem sabe, se for preciso, acionar alguma coisa. Ele vai fazer uma plaquinha que vai conter lá o elemento principal para fazer todo o gerenciamento do sistema, o Microcontrolador! Um sistema desses você pode encontrar por aí, garanto que não vai ser fácil, e pior, talvez não seja 100% adequado para o seu problema. Então é por isso que sua aplicabilidade é muito grande. Já que cada situação possui suas características que precisam ser desenvolvidas especificamente para cada cliente.

Esse chip também possuem pinos usados para enviar sinais para serem interpretados por um computador via comunicação usb ou serial. Então além de monitorar a sua fazenda, ele ainda pode enviar os dados para serem salvos em HD e analisados depois, e por aí a imaginação ajuda bastante nessas horas, colocar tudo em banco de dados, criar gráficos, analisar em qual época do ano tal fenômeno é mais presente, onde é preciso aumentar ou diminuir a quantidade de água e etc!
Bem é isso, espero que tenham entendido um pouco do que expliquei!

quinta-feira, 8 de setembro de 2011

Comando fork() - Sistemas Operacionais

Pessoal, resolvi postar algo sobre o uso do comando fork() em ambiente Linux de programação.
Quando damos o comando fork() em um programa escrito em C no Linux, ele vai criar uma cópia exata a partir do ponto em que o comando é executado e dois processos executam ao mesmo tempo, o processo pai (aquele que chama o comando fork() ) e o processo filho (o que foi gerada pela chamada do fork() ).
Um programa simples que usa o fork() pode ser visto logo abaixo:

#include < stdio.h >
#include < stdlib.h >
#include < sys/types.h >
#include < sys/wait.h >
#include < unistd.h >

int main ()
{
pid_t filho;
filho = fork(); //aqui criamos o processo filho
if ( filho == 0 ) { //execução do filho
printf ("Sou o filho executando...\n");
_exit(0);
}
else { //execução do pai
printf ("Sou o pai executando.\n");
}
exit(0);
}

Uma maior explicação dos cabeçalhos incluídos nesse programa pode ser encontrado nas entradas de manual do linux, como "man fork". Você pode encontrar descrições detalhadas de cada função.
Podemos ver que quando damos um comando fork() um valor de retorno é atribuído à variável filho. No processo pai, esse valor é diferente de zero, no processo filho, é igual a zero. Observe que o que estiver abaixo do comando fork() é replicado para outro processo, então tanto o processo pai quanto o filho irão executar o que vier abaixo, por isso precisamos testar com o "if" o que cada um deve executar. Então se o valor da variável filho é igual a zero, então quer dizer que é o trecho de código que o filho deve executar, caso contrário, será o do pai. Dessa forma, temos dois processos executando, sendo que um foi gerado pelo outro! A ideia é fazer com que os dois executem e realizem tarefas de modo mais rápido, sendo que cada tarefa é atribuída para cada um realizar separadamente, com isso pode-se obter ganho de desempenho!
Espero que tenham gostado!

domingo, 4 de setembro de 2011

Sistemas Operacionais

Recentemente comprei um livro de Sistemas Operacionais para poder acompanhar melhor as aulas, já que estou cursando essa disciplina nesse semestre, e gostaria de compartilhar o que estou achando dele.
É esse aqui: Sistemas Operacionais Modernos - Ed. 2010 - Tanenbaum, Andrew S. Por enquanto estou gostando muito de sua abordagem sobre a teoria em que se baseia um S.O. (Abreviação de Sistemas operacionais). Para quem não sabe, esse Tanenbaum desenvolveu um S.O. para fins didáticos, baseado no UNIX, o pai da família de Linux que vemos por aí e BSD's da vida, como o da Apple que acompanha seus notebooks. O nome desse sistema didático é MINIX, já que era uma versão menor do Unix (confira aqui: www.minix3.org). No site encontramos o seu código-fonte e um monte de documentação ensinando a instalar e usar.
Na minha opinião nada melhor para estudar S.O. do que no linux, ainda mais quando dispomos de um material inicial, como o Minix, para podermos praticar um pouco daquilo que estudamos. Ele possui um conjunto reduzido de instruções, o que permite um maior entendimento e facilidade para poder usar os comandos e quem sabe até estudar realmente a implementação já que podemos abrir o código fonte, na sua maioria escrito em C.
Pretendo em breve postar mais alguns conceitos importantes como processos e threads!
Um abraço!

domingo, 28 de agosto de 2011

Falha boot ubuntu 10.04

Iae galera, depois de tanto tempo sem postagem resolvi voltar para mostrar uma solução simples para um "bug" que aconteceu em meu notebook quando instalei a versão 10.04 (stable) do ubuntu.
Toda vez quando inicio o sistema a mensagem aparece logo após a escolha do sistema operacinal no grub:

"udevd [308] open /dev/null failed: no such file or directory"

Pesquisei e não achei uma solução. Então resolvi fazer um teste, atualizei a versão do kernel para a 2.6.32-33-generic e essa mensagem deixou de aparecer.
Provavelmente era alguma tentativa de leitura de algum dispositivo que o sistema não estava tratando corretamente!

Por enquanto é isso. Em breve irei preparar umas boas postagens!