Ne znam sad da li da ti odgovorim, posto nisam ETF-ovac .... :D
Ok, prvo par oficijelnih informacija:
-
http://www.ibiblio.org/pub/Linux/docs/HOWTO/Serial-HOWTO
-
http://www.ibiblio.org/pub/Lin...HOWTO/Serial-Programming-HOWTO
- redirektuj "man termios" u fajl pa odstampaj
- za testiranje mozda da stavis chmod 777 na /dev/ttyS0, recimo, ako ces njega da mucis :) Jeste da nije lepo, ali se lako vrati kasnije.
Na ovaj nacin inicijalizujes port i zatvaras ga (u zavisnosti da li si prosledio true ili false); da li ces to staviti u konstruktor ili u neku svoju OpenPort funkciju, tvoja stvar:
Code:
procedure TsSimpleSerial.SetOpen(Value:boolean);
var ios: termios;
portname : string;
bits, speed : cardinal;
begin
if Value <> FOpen then
begin
// if open
if Value then
begin
case ComPort of
ttyS0: portname := '/dev/ttyS0';
ttyS1: portname := '/dev/ttyS1';
ttyS2: portname := '/dev/ttyS2';
ttyS3: portname := '/dev/ttyS3';
end;
case Bitrate of
br2400: speed := B2400;
br4800: speed := B4800;
br9600: speed := B9600;
br19200: speed := B19200;
br57600: speed := B57600;
br115200: speed := B115200;
end;
case DataBits of
db5: bits := CS5;
db6: bits := CS6;
db7: bits := CS7;
db8: bits := CS8;
end;
// open the port and get its terminal attributes
ComHandle:= LibC.Open(pchar(portname),fmOpenReadWrite or o_nonblock);
// if its really opened ...
if ComHandle <> s_NONE then
begin
FOpen := true;
tcgetattr(ComHandle,ios);
cfmakeraw(ios);
// reset the attributes
case Parity of
pNone : ios.c_cflag := ios.c_cflag and (not PARENB);
pEven : begin
ios.c_cflag := ios.c_cflag or PARENB;
ios.c_cflag := ios.c_cflag and (not PARODD);
end;
pOdd : begin
ios.c_cflag := ios.c_cflag or PARENB;
ios.c_cflag := ios.c_cflag or PARODD;
end;
end;
if FlowControl <> fcNONE then
ios.c_cflag := ios.c_cflag or CRTSCTS
else
ios.c_cflag := ios.c_cflag and (not CRTSCTS);
if StopBits = sb1 then
ios.c_cflag := ios.c_cflag and (not CSTOPB);
ios.c_cflag := ios.c_cflag and (not CSIZE);
ios.c_cflag := ios.c_cflag or bits;
// set in/out speeds
cfsetospeed (ios, speed);
cfsetispeed (ios, speed);
// and apply the changed attributes
tcsetattr (ComHandle,tcsanow,ios);
end
else raise ESerialPortError.Create('Cannot open serial port '+portname);
end
else // if open = false
if ComHandle <> s_NONE then
fileClose(ComHandle);
end;
end;
ComPort, BitRate, Parity, DataBits, FlowControl, StopBits su atributi moje klase, postavljanju se iz drugih metoda, a vrednosti koje se stavljaju u njih su klasicna enum polja. Ovde se samo proveravaju i ocigledno je da je rvalue vrednosti iz libc biblioteke.
s_NONE je moja konstanta i iznosi -1.
ESerialPort je moja exception klasa.
Sve ostalo bi trebalo da bude libc-ovo.
PChar je kylix funkcija koja pretvara pascal string u null-terminisani string.
Cardinal je u Kylixu unsigned 32-bit integer, dakle unsigned long.
Za terminal atribute pogledaj pomenuti "man termios". Moze klasa stvarno da se napravi kompletna, ali meni nije trebalo toliko komplikovanje.
Dalji upis i citanje radis sa klasicnim FileWrite i FileRead (sa klasicnim parametrima - adresa bafera i 'koliko bajtova'), dakle, nesto ovakvo:
Code:
//==============================================================================
function TsSimpleSerial.ReadTG(var Buffer; Count: integer): integer;
begin
if (Open and (ComHandle <> s_NONE) ) then
Result := FileRead(ComHandle, Buffer, Count)
else
Result := s_NONE;
end;
//==============================================================================
function TsSimpleSerial.WriteTG(const Buffer; Count: integer): integer;
begin
if (Open and (ComHandle <> s_NONE) ) then
Result := FileWrite(ComHandle, Buffer, Count) // -1 = error
else Result := s_NONE;
end;