Difference between revisions of "Hardware Access/pt"
Sekelsenmat (talk | contribs) |
Sekelsenmat (talk | contribs) |
||
Line 84: | Line 84: | ||
</code> | </code> | ||
− | + | Este código foi testado com uma placa ISA própria na porta$0220, utilizando o Lazarus 0.9.10 no Windows XP. Obviamente é necessário possuir a unidade Windows na clausula "uses" para que este código possa funcionar. Para distribuir um aplicativo que utilize a biblioteca você precisa apenas incluir a "inpout32.dll" no mesmo diretório do executável. | |
− | + | Está é a página da biblioteca: [http://www.logix4u.net/inpout32.htm www.logix4u.net/inpout32.htm] | |
− | == | + | ==Utilizando ioperm para acessar portas no Linux== |
− | + | A melhor maneira de acessar dispositivos de hardware no Linux é através de drivers, mas, devido a complexidade envolvida na criação de um, as vezes um método mais simples é útil. | |
− | + | Para utilizar a unidade "ports" no Linux, seu programa deve ser executado como superusuário (i.e. root) e utilizar a função IOPerm para definir as permissões de acesso as portas. Você pode encontrar documentação sobre a unidade "ports" [http://www.freepascal.org/docs-html/rtl/ports/index.html aqui]. | |
− | + | A primeira coisa a ser feita é estabelecer um vínculo estático com o glibc e chamar a função IOPerm. Uma unidade que estabelece vínculos para todo o glibc existe no Free Pascal, mas ela causa problemas quando utilizada diretamente pelo aplicativo, além do que não é adequado para um programa multi-plataforma chamar funções demais do glibc, assim iremos criar o mínimo indispensável de vínculos dependendes de plataforma declarando apenas a função do glibc a ser utilizada. | |
<code> | <code> | ||
Line 102: | Line 102: | ||
</code> | </code> | ||
− | * "from" | + | * "from" representa a primeira porta a ser acessada. |
− | * "num" | + | * "num" é o número de portas após a primeira a serem acessadas. Assim ioperm($220, 8, 1) fornecerá ao programa acesso a todos portas entre e incluindo $220 e $227. |
− | + | Após chamar a função OIPerm você pode utilizar "port[<Endereço>]" para acessar as portas. | |
<code> | <code> | ||
Line 117: | Line 117: | ||
</code> | </code> | ||
− | + | Este código for testado com uma placa ISA própria na porta $0220, utilizando o Lazarus 0.9.10 no Mandriva Linux 2005 e no Damn Small Linux 1.5. |
Revision as of 22:36, 20 October 2005
Visão Geral
Está página é o começo de um tutorial sobre acesso a dispositivos de hardware por programas desenvolvidos no Lazarus. Estes dispositivos incluem, porem não estão limitados a: Placas ISA e PCI, as portas paralela e serial e USB.
O acesso ao hardware de uma maneira completamente multi-plataforma não é implementada pela biblioteca RunTime do Free Pascal ou pela LCL, assim este tutorial cobre metodos diferentes para diferentes plataformas. O código pode ser compilado em ambientes diferentes utilizando a compilação condicional. Abaixo segue um exemplo disto:
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls,
{$IFDEF WIN32}
Windows;
{$ENDIF}
{$IFDEF Linux}
ports;
{$ENDIF}
Quem desejar pode contribuir para este documento.
Utilizando a inpout32.dll para Windows
No Windows há diferentes metodos para acessar dispositivos de hardware na série 9x e na série NT, o que pode gerar muitos problemas. A série 9x (95, 98, Me) permite que os programas acessem as portas diretamente, da mesma maneira que éra feita no DOS. A série NT, porém, não permite isto e todos acesso as portas deve ser feito através de Device Drivers. Isto é mecanismo de segurança, mas pode complicar o desenvolvimento de aplicativos pequenos que apenas precisam acessar uma determinada porta.
Felizmente existe uma biblioteca que carrega dentro de si um driver. Quando ela é chamada para acessar uma determinada porta ela detecta se o Windows em operação é da série NT e, em caso afirmativo, descomprime o driver Hwinterface.sys e o instala no kernel. Se a série 9x for detectada ele simplesmente utiliza instruções de assembler para acessar o hardware.
Mas como utilizar a biblioteca? Simples! Ela possuí apenas duas funções, Inp32 e Out32, e seu uso é bastante intuitivo.
Nós estaremos carregando a biblioteca dinamicamente, então é bom definir as funções antes:
type
TInp32 = function(Address: ShortInt): ShortInt; stdcall;
TOut32 = procedure(Address: ShortInt; Data: ShortInt); stdcall;
- Address representa o endereço da porta a ser acessada. Out32 envida Dados para a porta. Inp32 returna um byte da porta no Address.
Agora podemos carregar a biblioteca. Isto pode ser implementado num lugar como o evento OnCreate do seu formulário principal:
type
TMyForm = class(TForm)
.........
private
{ private declarations }
Inpout32: THandle;
Inp32: TInp32;
Out32: TOut32;
.........
implementation
.........
procedure TMyForm.FormCreate(Sender: TObject);
begin
{$IFDEF WIN32}
Inpout32 := LoadLibrary('inpout32.dll');
if (Inpout32 <> 0) then
begin
@Inp32 := GetProcAddress(Inpout32, 'Inp32');
if (@Inp32 = nil) then Caption := 'Error';
@Out32 := GetProcAddress(Inpout32, 'Out32');
if (@Out32 = nil) then Caption := 'Error';
end
else Caption := 'Error';
{$ENDIF}
end;
Se você carregar a biblioteca no evento OnCreate não esqueça de descarrega-la no evento OnDestroy:
procedure TMyForm.FormDestroy(Sender: TObject);
begin
{$IFDEF WIN32}
FreeLibrary(Inpout32);
{$ENDIF}
end;
Aqui está um exemplo de uso da função Inp32:
{$IFDEF WIN32}
myLabel.Caption := IntToStr(Inp32($0220));
{$ENDIF}
Este código foi testado com uma placa ISA própria na porta$0220, utilizando o Lazarus 0.9.10 no Windows XP. Obviamente é necessário possuir a unidade Windows na clausula "uses" para que este código possa funcionar. Para distribuir um aplicativo que utilize a biblioteca você precisa apenas incluir a "inpout32.dll" no mesmo diretório do executável.
Está é a página da biblioteca: www.logix4u.net/inpout32.htm
Utilizando ioperm para acessar portas no Linux
A melhor maneira de acessar dispositivos de hardware no Linux é através de drivers, mas, devido a complexidade envolvida na criação de um, as vezes um método mais simples é útil.
Para utilizar a unidade "ports" no Linux, seu programa deve ser executado como superusuário (i.e. root) e utilizar a função IOPerm para definir as permissões de acesso as portas. Você pode encontrar documentação sobre a unidade "ports" aqui.
A primeira coisa a ser feita é estabelecer um vínculo estático com o glibc e chamar a função IOPerm. Uma unidade que estabelece vínculos para todo o glibc existe no Free Pascal, mas ela causa problemas quando utilizada diretamente pelo aplicativo, além do que não é adequado para um programa multi-plataforma chamar funções demais do glibc, assim iremos criar o mínimo indispensável de vínculos dependendes de plataforma declarando apenas a função do glibc a ser utilizada.
{$IFDEF Linux}
function ioperm(from: Cardinal; num: Cardinal; turn_on: Integer): Integer; cdecl; external 'libc';
{$ENDIF}
- "from" representa a primeira porta a ser acessada.
- "num" é o número de portas após a primeira a serem acessadas. Assim ioperm($220, 8, 1) fornecerá ao programa acesso a todos portas entre e incluindo $220 e $227.
Após chamar a função OIPerm você pode utilizar "port[<Endereço>]" para acessar as portas.
{$IFDEF Linux}
i := ioperm($220, 8, 1);
port[$220] := $00;
myLabel.Caption := 'ioperm: ' + IntToStr(i);
i := Integer(port[$220]);
myOtherLabel.Caption := 'response: ' + IntToStr(i);
{$ENDIF}
Este código for testado com uma placa ISA própria na porta $0220, utilizando o Lazarus 0.9.10 no Mandriva Linux 2005 e no Damn Small Linux 1.5.