Arquivos Mensais: junho \29\UTC 2015

Acesso a porta paralela programando em C no Linux

[Repostagem de um post publicado em 2006 (velho, né?) e, por motivos inescusos, excluído do blog. Finalmente, aí está de volta.]
ATENÇÃO:
Não me responsabilizo por qualquer dano que você possa causar no seu computador por seguir as instruções deste texto. Você é inteiramente responsável por tudo o que você fizer, mesmo que seja exatamente como eu disser aqui. Você tem o direito de copiar, distribuir, vender (apesar que eu achar meio brabo alguém querer comprar :)) e alterar este texto, desde que não tome os créditos para você e assine as alterações antes de redistribuir.
Pequena explanação sobre a porta paralela (importante!!!)…

Para acessar a porta paralela (mudar os níveis lógicos dos bits de saída e ler os de entrada) em sistemas Linux é necessário que o programa tenha permissões especiais, e o usuário que vai executar o programa deve ser superusuário (sudo, root, algo do gênero… não entendo muito).

A porta paralela é dividida em:

– Quatro bits de controle(saída);

– Oito bit (um byte) de dados (saída)*;

– Cinco bits de status (entrada);

Cada divisão dessas é um registrador de um byte e tem um endereço na memória (os endereços para os registradores de dados, status e controle são respectivamente em notação hexadecimal 378, 379, 37A). Os oito bits do registrador de dados tem conexão física com a porta paralela, enquanto que os registradores de controle apenas os 4 bits menos significantes (os mais da direita) tem conexão física, os outros quatro bits servem para configuração da porta, portanto toda vez que for mexer no registrador de controle tome o cuidado de não mexer nos 4 bits mais significantes, a não ser que você tenha total consciência do que está fazendo. Do registrador de status só têm contato físico com a porta paralela os cinco mais significantes bits, mas você pode ler todo o byte, claro.

Como meu programa pede permissão pro sistema?

Para o seu programa pedir permissão para o sistema existe uma função chamada ioperm. Ela está presente em libc5 e glibc, então se você tem libc5, você inclui unistd.h e no caso da glibc inclua sys/io.h. Como eu tenho as duas, vai qualquer uma. Nos programas de teste aqui eu vou incluir as duas para não dar problema para ninguém, mas você pode deixar apenas a necessária pra você.

A ioperm recebe dois inteiros e um valor booleano como argumento: o primeiro é o endereço da memória sobre o qual você está falando, o segundo é o numero de bytes que sobre os quais você quer falar a partir do endereço que você colocou, e o booleano é se você que pedir acesso a esse(s) lugar(es) da memória ou bloquear seu acesso (zero “0″ (falso) para bloquear e um “1″ (verdadeiro) para pedir acesso).

Como nós queremos acesso aos registradores 378, 379 e 37A (hexadecimal) e eles vêm um atrás do outro, podemos pedir permissão para a porta paralela usando a função ioperm dessa forma:

ioperm(0×378, 3, 1);

Assim pedimos acesso ao registrador com endereço 0×378 e os dois seguintes a ele: 0×379 e0×37A.

A função ioperm retorna 0 se bem sucedida e -1 se houver algum problema. Assim, podemos criar um programinha apenas para pedir permissão de acesso aos registradores da porta paralela e dizer se teve sucesso ou não. Lá vai o programa teste.c:

#include <stdio.h> //pelo bom costume

#include <unistd.h> //retire essa linha se voce so usa glibc

#include <sys/io.h> //retire essa linha se voce so usa libc5

int main()

{

if(ioperm(0×378, 3, 1)) {

printf(”Houve algum problema. Voce deve ser superusuario.\n”);

} else {

printf(”Tudo certo. Tenho acesso a porta paralela agora.\n”);

}

}

Bom, compile com o comando ‘$gcc teste.c’. Em seguida execute com usuário normal: ‘$ ./a.out’ e depois como root ‘# ./a.out’ (ou com o comando sudo: ‘$ sudo ./a.out’). Você verá a diferença.

Lendo os valores…

Para ler os valores dos registradores existe uma função denominada inb(). Ela recebe um único inteiro como argumento que é o endereço do registrador que se quer ler, e retorna o valor lido. Segue um exemplo de programa que retorna todos os valores da porta:

#include <stdio.h>
#include <unistd.h> //retire essa linha se voce soh usa glibc
#include <sys/io.h> //retire essa linha se voce soh usa libc5
#include <stdlib.h> //pra usar a função exit
#define DATA_END 0×378

int main()
{
if(ioperm(0×378, 3, 1)){
printf(”Algum problema. Você deve ser super usuário.\n”);
exit(1);
}
printf(”Valores:\nDADOS: %d\nSTATUS: %d\nCONTROLE: %d\n”, inb(DATA_END), inb(DATA_END+1), inb(DATA_END+2));
}

Escrevendo no registrador de dados…

Escrever no registrador de dados é tão simples quanto ler. Existe uma função chamada outb() que é para escrever valores na memória. Ela recebe dois argumentos, o endereço onde se quer escrever e o valor a ser escrito na ordem inversa, isto é, o valor primeiro e o endereço depois. Segue-se um programa que coloca em nível alto todos os bits de dados (coloca 255 na porta – FF em hexadecimal).

#include <stdio.h>
#include <unistd.h> //retire essa linha se voce soh usa glibc
#include <sys/io.h> //retire essa linha se voce soh usa libc5
#include <stdlib.h> //pra usar a função exit
#define DATA_END 0×378

int main()
{
if(ioperm(0×378, 3, 1)){
printf(”Algum problema. Você deve ser super usuário.\n”);
exit(1);
}
outb(0xff, DATA_END);
}

Depois de compilar e executar o programa acima, execute o programa que fizemos para leitura para verificar o estado do registrador de dados, ou acrescente a linha:

printf(”DADOS: %d”, inb(DATA_END));

no programa atual abaixo da linha:

outb(0xff, DATA_END);

Concluindo…

Bom, nesse tutorial não mexemos no registrador de controle, mas estou disponibilizando abaixo os programas que eu fiz nesse tutorial e mais um outro (o mesmo do antigo post) que tem umas funções prontinhas pra setar os bits separadamente.

Download dos códigos deste tutorial:

teste.c

lendo.c

escreve_dados.c

Download do meu programa pra controle da porta:

lpt_control.c

Atenção: Cuidado se quiser setar os bits de controle!!! NÃO mexa nos quatro bits mais significativos porque eles são para configurar a porta. Mais adiante falarei sobre o registrador de controle.
Qualquer problema, envie-me um e-mail: jetervaz (a) gmail.com

Mais informações sobre o hardware da porta paralela no site: http://www.rogercom.com

————————————————————

*Também pode ser usado como entrada em alguns casos, mas aqui vamos demonstrar apenas como usar para saída.

Aplique o arco-íris na sua foto

batatinha-2Com uma votação de 5×4, a Suprema Corte dos EUA decidiu, hoje, que o casamento entre pessoas do mesmo sexo é constitucionalmente assegurado em todo o país (http://www1.folha.uol.com.br/mundo/2015/06/1648129-em-decisao-historica-estados-unidos-legalizam-casamento-gay.shtml). Com isso, muita gente começou a aplicar o arco-íris, em solidariedade à comunidade LGBT, nas suas fotos de perfil nas redes sociais.

Alguns estavam tendo dificuldade com o App, e também tem pessoas que não usam facebook, ou simplesmente não querer utilizar o aplicativo para não compartilharem informações de seus perfis. Segue um script que fiz pra quem quiser aplicar o filtro de cor na sua foto, e baixar a foto para usar onde quiser. Acesse aqui: http://prototypes.com.br/rainbow/