[Lazarus] Usage of Serial in a testing program?

Mark Morgan Lloyd markMLl.lazarus at telemetry.co.uk
Mon Sep 10 17:27:13 CEST 2018

On 10/09/18 13:30, Bo Berglund via Lazarus wrote:
> On Sun, 9 Sep 2018 20:44:34 +0000, Mark Morgan Lloyd via Lazarus<lazarus at lists.lazarus-ide.org> wrote:
>> I did quite lot of work on the serial.pp unit more recently than that >wiki page, in fact I didn't even know it existed. Please refer to the >comments in that file in the first instance.
> Thanks Mark,I did that too and there is stuff I don't find there, like:
> Read blocking?----------------------From interface section:
> { Reads a maximum of "Count" bytes of data into the specified buffer.  Result: Number of bytes read. }function SerRead(Handle: TSerialHandle; var Buffer; Count: LongInt):LongInt;
> Does this function read whatever is in the buffer when called up to amaximum of Count, or does it actually wait until Count bytes havearrived? If it waits, for how long?

 From further down:

function SerRead(Handle: TSerialHandle; var Buffer; Count: LongInt): 
   Result := fpRead(Handle, Buffer, Count);

where the documentation for fpread() says

"FpdRead reads at most nbytes bytes from the file descriptor fd, and 
stores them in buf.

"The function returns the number of bytes actually read"

So this is a unix-style read that is prepared to read  Count  bytes, but 
returns the number actually available.

If you want timeouts then see SerReadTimeout(). I'd expect the Windows 
variants to behave the same (I tested Linux, Solaris and I think W2K, so 
there's a risk that newer versions behave differently). /If/ you find 
anomalies, please raise a bug report with the caveat that I have rather 
a lot of problems on my plate right now.

> Concerning the com port name for SerOpen():
> { Open the serial device with the given device name, for example:    \COM1, \COM2 (strictly, \\.\COM1...) for normal serial ports.    ISDN devices, serial port redirectors/virtualisers etc. normally    implement names of this form, but refer to your OS documentation.  Returns "0" if device could not be found }function SerOpen(const DeviceName: String): TSerialHandle;

On Linux that is, again, a very thin wrapper around the RTL fpOpen() 
function, on Windows it's a wrapper around CreateFile(). I really can't 
say the extent that I tested that with odder devices and high port 
numbers (I think I took SerOpen() etc. pretty much as supplied by the 
original author), but from other serial libraries on Delphi my 
recollection is that that leading \\.\ is mandatory for higher-numbered 
ports... I /think/ I got up to 12 ports but that really was a very long 
time ago.

Note that C/C++ examples relating to that sort of thing will usually 
refer to \\\\.\\ because of the special significance of \ in strings.

> In the Wiki example they use COMx: where x is a number, but this isprobably only working for single digit numbers 1..9.In any case the naming there is not described in serial.pp
> I need to huse a high numbered com port since all I have is USB2Serialdongles, which typically get you a port number like 29...

I can't comment on Windows there but on Linux they typically get called 
something like /dev/USB0 etc., with a risk that the numeric suffix will 
increment if it's replugged. I've used that library fairly heavily on 
Linux for instrumentation type stuff, it works fairly well with USB 
devices except that their timing can get flaky if you're trying to get 
the exact time at which e.g. CTS changes state relative to a stream of 
characters faster than about 300 Baud.

When I was working on it the major thing I did was reorganise some of 
the flush/drain/sync stuff which was generally felt to be in a mess, add 
a bit more in the way of control signal interfacing, and add 
SerReadTimeout()... note the provision for an idle callback.


Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk

[Opinions above are the author's, not those of his employers or colleagues]

More information about the Lazarus mailing list