Recent

Author Topic: Porting Delphi application to Lazarus then Linux, what about serial comm?  (Read 4935 times)

jamie

  • Hero Member
  • *****
  • Posts: 4906
Yes, there is a function in synapse I believe, "SendingData"
it reports if it is still sending..

You also have Purge and flush..
The only true wisdom is knowing you know nothing

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1053
hello,
as suggested by jamie , use SendingData (in your case FComm.SynSer.SendingData) to see number of bytes waiting to be sent :
Quote
function SendingData: integer; virtual;
Returns the number of bytes waiting to be sent in the output buffer. 0 is returned when the output buffer is empty.

and Flush (in your case FComm.SynSer.Flush()) to wait until all data to is sent.
Quote
procedure Flush; virtual;
Waits until all data to is sent and buffers are emptied. Warning: On Windows systems is this method returns when all buffers are flushed to the serial port controller, before the last byte is sent!

Friendly, J.P
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

BosseB

  • Sr. Member
  • ****
  • Posts: 359
hello,
as suggested by jamie , use SendingData (in your case FComm.SynSer.SendingData) to see number of bytes waiting to be sent :
Quote
function SendingData: integer; virtual;
Returns the number of bytes waiting to be sent in the output buffer. 0 is returned when the output buffer is empty.
OK, thanks. I have added this to the function (it is now in a conditional compile block in preparation for being ported):
Code: Pascal  [Select][+][-]
  1.       {$IFNDEF FPC} //Delphi
  2.         {$IFDEF USE_ASYNCPRO}
  3.           while FComm.OutBuffUsed > 16 do
  4.         {$ELSE}
  5.           while FComm.TxWaiting > 16 do
  6.         {$ENDIF}
  7.       {$ELSE}  //FPC using LazSerial
  8.           while FComm.SynSer.SendingData > 16 do
  9.       {$ENDIF}
  10.           begin
  11.             Application.ProcessMessages;
  12.             Sleep(1);
  13.           end;
  14.  
Quote
and Flush (in your case FComm.SynSer.Flush()) to wait until all data to is sent.
Quote
procedure Flush; virtual;
Waits until all data to is sent and buffers are emptied. Warning: On Windows systems is this method returns when all buffers are flushed to the serial port controller, before the last byte is sent!

Friendly, J.P
Well, that "Waits" sort of makes the system blocking, which is not what I want.
The code originates from long ago (2004) and it is not threaded apart from what a Delphi program itself provides.
Instead it is event driven.
During long serial transfers it therefore uses the construct above including the Application.Processmessages call to allow for the events to happen while the transfer is running on the serial port.
In some cases this could take many seconds up to more than a minute...
« Last Edit: May 12, 2020, 10:34:46 am by BosseB »
--
Bo Berglund
Sweden

tetrastes

  • Full Member
  • ***
  • Posts: 128
What do you want from Flush? It simply calls corresponding system function, and thats all. So it behaves just how system defines. It seems that you want real time system.  8-)
As for threading, you want others to do all job for you. Place the communucations in separate thread yourself, what's the problem?

BosseB

  • Sr. Member
  • ****
  • Posts: 359
What do you want from Flush? It simply calls corresponding system function, and thats all. So it behaves just how system defines. It seems that you want real time system.  8-)
HUH???
I was asking for the existence of a function inherent in LazSerial that would simply discard the incoming data buffer. But I could also just read the totality and throw it away. This was in my post on the subject.
And it is all caused by the fact that in the original code the two components to be replaced had such a function.
Quote
As for threading, you want others to do all job for you. Place the communications in separate thread yourself, what's the problem?
The problem is that the original code I am trying to port is written using a simple event controlled structure and I do not want to change that into a threading system. Too much work.
This is a peer to peer forum and is meant for Lazarus/Fpc questions to be asked and hopefully answered. It is no place for flame war....

I have been using Delphi since 1996, what experience do you have?
--
Bo Berglund
Sweden

tetrastes

  • Full Member
  • ***
  • Posts: 128
Quote
and Flush (in your case FComm.SynSer.Flush()) to wait until all data to is sent.
Quote
procedure Flush; virtual;
Waits until all data to is sent and buffers are emptied. Warning: On Windows systems is this method returns when all buffers are flushed to the serial port controller, before the last byte is sent!

Friendly, J.P
Well, that "Waits" sort of makes the system blocking, which is not what I want.

You wrote this about Flush, aren't you? So I answered you about Flush.
To discard the incoming data buffer you may add function based on slightly modified Purge, which discards all buffers.
Why you do not read the code of LazSerial yourself?

Quote
The code originates from long ago (2004) and it is not threaded apart from what a Delphi program itself provides.
Instead it is event driven.
During long serial transfers it therefore uses the construct above including the Application.Processmessages call to allow for the events to happen while the transfer is running on the serial port.
In some cases this could take many seconds up to more than a minute...

If you don't want rewrite code to multithread, then what is it about? Sorry that I didn't guess...

Quote
I have been using Delphi since 1996, what experience do you have?


I have been using FORTRAN IV since 1982   :'(

devEric69

  • Hero Member
  • *****
  • Posts: 599
Re: Porting Delphi application to Lazarus then Linux, what about serial comm?
« Reply #36 on: September 23, 2021, 04:57:33 pm »
hello BosseB,
can you you try this more readable code for your modification :
Code: Pascal  [Select][+][-]
  1. const
  2. {$IF (DEFINED(UNIX)) AND (NOT (DEFINED(CPUARM))) }
  3.   {$IFDEF DARWIN}
  4.   MaxRates = 18;  //MAC
  5.   {$ELSE}
  6.    MaxRates = 30; //UNIX
  7.   {$ENDIF}
  8. {$ELSE}
  9.   MaxRates = 19;  //WIN  and Raspberry Pi
  10. {$ENDIF}
  11.   Rates: array[0..MaxRates, 0..1] of cardinal =
  12.   (
  13.     (0, B0),
  14.     (50, B50),
  15.     (75, B75),
  16.     (110, B110),
  17.     (134, B134),
  18.     (150, B150),
  19.     (200, B200),
  20.     (300, B300),
  21.     (600, B600),
  22.     (1200, B1200),
  23.     (1800, B1800),
  24.     (2400, B2400),
  25.     (4800, B4800),
  26.     (9600, B9600),
  27.     (19200, B19200),
  28.     (38400, B38400),
  29.     (57600, B57600),
  30.     (115200, B115200),
  31.     (230400, B230400)
  32. {$IFNDEF DARWIN}
  33.     ,(460800, B460800)
  34.   {$IF (DEFINED(UNIX)) AND (NOT (DEFINED(CPUARM)))} //Not for RPi with ARM CPU
  35.     ,(500000, B500000),
  36.     (576000, B576000),
  37.     (921600, B921600),
  38.     (1000000, B1000000),
  39.     (1152000, B1152000),
  40.     (1500000, B1500000),
  41.     (2000000, B2000000),
  42.     (2500000, B2500000),
  43.     (3000000, B3000000),
  44.     (3500000, B3500000),
  45.     (4000000, B4000000)
  46.   {$ENDIF}
  47. {$ENDIF}
  48.     );
  49. {$ENDIF}
  50. {$IFDEF DARWIN}
  51. const // From fcntl.h
  52.   O_SYNC = $0080;  { synchronous writes }
  53. {$ENDIF}

I will update my github project if it is OK

Friendly, J.P

Old post, nevertheless, for information, I've notified the originel maintainer about this patch (proposal \ fix) in synaser.pas (Synapse 40.1.0.0), there for RasbPi \ RaspBerry Pi 4 . Thanks to @BosseB and @J.P.
« Last Edit: September 23, 2021, 05:39:40 pm by devEric69 »
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

 

TinyPortal © 2005-2018