Il 09/09/2018 13:33, Bo Berglund via Lazarus ha scritto:
I am writing a testing application for checking out a TCP to Serial
bridge component. I am using Lazarus 1.8.0 and fpc 3.0.4 on Windows 7

For the serial port handling I found the "built-in" Serial unit
described here:
http://wiki.freepascal.org/Hardware_Access#FPC_built_in_Serial_unit

Now I have a few questions about its usage:

1) Serial port name
-------------------
When opening the port the example does this:

str(ComPortNr,tmpstr);
ComPortName:= 'COM'+tmpstr+':';
serialhandle := SerOpen(ComPortName);

So for say port 29 this results in ComPortName 'COM29:'
Is this always the case? I have a hunch that for port numbers 1..9 the
Windows port naming is different than for higher port numbers...

And if I want to port this to Linux, I guess thta the name is
completely different, but no hint is given.
Here is the procedure I'm using to fill up a combo box with the names of the existing serial devices on the platform. Please note the different naming conventions in Linux and Windows. Also note that to report a serial port as existing a test is made to open it (using the fpc serial function), and avoid "phantom" ports.
procedure TForm1.btnScanPortClick(Sender: TObject); var PortNr: Integer; PortName: String; PortHandle: TSerialHandle; begin cbSelPort.Items.Clear; cbSelPort.Text:= ''; {$IFDEF MSWINDOWS} for PortNr := 1 to 9 do begin PortName := 'COM' + IntToStr(PortNr); PortHandle := SerOpen('\\.\'+PortName); if PortHandle > 0 then begin cbSelPort.Items.Add(PortName); SerClose(PortHandle); if cbSelPort.Text = '' then begin cbSelPort.Text:=PortName; PortSel.Caption:= PortName; end; end; end; {$ELSE} for PortNr := 0 to 9 do begin PortName := '/dev/ttyS' + IntToStr(PortNr); PortHandle := SerOpen(PortName); if PortHandle > 0 then begin if cbSelPort.Text = '' then begin cbSelPort.Text:=PortName; PortSel.Caption:= PortName; end; cbSelPort.Items.Add(PortName); SerClose(PortHandle); end; end; for PortNr := 0 to 9 do begin PortName := '/dev/ttyUSB' + IntToStr(PortNr); PortHandle := SerOpen(PortName); if PortHandle > 0 then begin if cbSelPort.Text = '' then begin cbSelPort.Text:=PortName; PortSel.Caption:= PortName; end; cbSelPort.Items.Add(PortName); SerClose(PortHandle); end; end; {$ENDIF} end;

2) Blocking send?
------------------
Is this port blocking for sending?

The example has this:

status := SerWrite(serialhandle, s[1], writecount );

where s is a string holding the text to send (I will actually need to
use a TBytes array instead) and writecount returns the bytes actually
sent.

If I want to send an array of say 100 kbytes at 9600 baud, will the
call return only when the data have been completely sent or earlier?
It will take about 100 seconds to send that array...
Yes, SerWrite is blocking. I hope you don't plan to send 100 kbytes in a single write on a serial line. The probability of an error in between is near to 100%!
What I'm doing in such cases is to create a dedicated thread to handle send and receive, without blocking the main thread, which remains responsive, and split the send in many small blocks (and getting some sort of ACK/NAK from remote receiver), which makes it possible to show a progress bar or whatever visual feedback you like.
3) Receiving data
----------------
For data reception I see this:

s:='';
ComIn:='';
while (Length(Comin)<10) and (status>=0) and not keypressed do 
begin
   status:= SerRead(serialhandle, s[1], 10);
   ...

Since the call parameters are the receive buffer and the count to read
I do not understand how this can work. s has been emptied (length = 0)
just before the call so how can SerRead stuff any data into the buffer
starting at s[1], which should not even exist???

I would like to have a way to read incoming data asynchronously so I
also could handle the user feedback and the TCP connection which is
sending the data that ultimately will arrive on the serial line...

Any suggestions on how to do this?


I never use SerRead, but rather SerReadTimeout (from the same unit) which gives a much better control of what is going on. Of course in that case your receiving buffer must be large enough to accommodate the largest block you expect. (This replies also to your further questions).


I hope that it helps.


Giuliano

-- 
Do not do to others as you would have them do to you.They might have different tastes.
-- 
_______________________________________________
Lazarus mailing list
Lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus

Reply via email to