[fpc-pascal] Using built-in serial instead of synaser and the like for Linux console app?

Bo Berglund bo.berglund at gmail.com
Tue Sep 1 10:22:08 CEST 2020


On Mon, 31 Aug 2020 12:01:33 +0200, Bo Berglund via fpc-pascal
<fpc-pascal at lists.freepascal.org> wrote:

>Thanks, I was worried about reading more data than specified.
>Now I can let the loop in Execute read say 10 bytes or so with timeout
>ane process these, then loop back after firing off the event.

Just a follow-up for completeness:

I have got it running now and I implemented the fpserialport object
such tghta if it is commanded to open the port without an event
procedure defined it will provide blocking read functions (overloaded
for string vs. TBytes containers).
But if the event is defined it will read the data in the Execute
function in the read thread and provide the data to the user via the
event.

Here is the read thread code (BUFFERSIZE is set to $2000):

TOnRxDataEvent = procedure(Sender: TObject; const Data: TBytes) of
object;

procedure TComPortReadThread.CallEvent;
begin
  if Assigned(Owner.FOnRxData) then
  begin
    Owner.FOnRxData(Owner, FBuffer);
  end;
end;

procedure TComPortReadThread.Execute;
var
  Cnt: integer;
begin
  try
    SetLength(FBuffer, BUFFERSIZE); //Set buffer size to 8192 bytes.
    while not MustDie do
    begin
      cnt := SerReadTimeout(Owner.FHandle, FBuffer[0], 10, 10); //Read
10 bytes with timeout of 10 ms
      if  cnt > 0 then
      begin
        SetLength(FBuffer, cnt); //Reduce size to fit rx data
        Synchronize(CallEvent); //Rx data in FBuffer to caller
        SetLength(FBuffer, BUFFERSIZE); //Restore buffer size
      end;
    end;
  finally
    Terminate;
  end;
end;

So this will fire the event on every 10 bytes received or after the 10
ms timeout, whichever comes first. No event without data, though.

I don't know if this is really OK, my applications are using 38400 and
115200 baud so the 10 bytes will arrive in less than 3 ms at the
slower speed.
But I could not figure out any better way to implement it, save for
firing off the event for every byte arriving, which would cause a lot
of calls...

Maybe I could tie the timeout to the actual baud used? Slower speeds
use longer timeout etc? Timeout could be set to the time it takes to
transfer the number of bytes to read?

And both arguments could be made properties of the class such that the
user can tweak performance a bit?


-- 
Bo Berglund
Developer in Sweden



More information about the fpc-pascal mailing list