On Fri, 21 Aug 2020 21:03:31 +0200, Bo Berglund via fpc-pascal <fpc-pascal@lists.freepascal.org> wrote:
>Instead I need to add a thread for reading data so I can have an event >driven reception of data. It would read available data and fire off a >NotifyEvent to handle the incoming data in the main application. I have now started to implement a simple "fpserialport" class using the built-in serial unit and I am trying to add a reading thread so I can get an OnRxData event which is needed by many of the non-GUI applications I want to port to Fpc/Lazarus. It can be a simple TNotifyEvent where the user will implement the actual read or else a specific event procedure providing a TBytes container with the data. Both are possible. But when doing this I have run into a problem, how can I check how many Rx bytes are available to be read from the operating system? If I simply use the SerReadTimeout() function it will return either with 1 or more bytes or after the timeout. But there is a problem here: function SerReadTimeout(Handle: TSerialHandle; var Buffer; mSec: LongInt): LongInt; When calling this the Buffer length has to be set *beforehand* so the arriving data can fit inside the buffer, but how can I know how big Buffer must be? I assume that if the Buffer is too small there will be an exception or else an overwrite of following memory? The other variant of the read: function SerReadTimeout(Handle: TSerialHandle; var Buffer: array of byte; count, mSec: LongInt): LongInt; Here there is a count argument that will limit the amount of data read into the buffer, but from the code in serial.pp it seems like the function can in fact read more data into the buffer than count. The break condition is: while fpSelect(Handle + 1, @readSet, nil, nil, @selectTimeout) > 0 do begin Inc(result,fpRead(Handle, Buffer[result], count - result)); if result >= count then // <== HERE possible overflow break; if Assigned(SerialIdle) then SerialIdle(Handle) end Is there a possibility to create a function that checks how many bytes are available in the operating system buffer and then dimension the buffer using this value and read only that count? Something like: function SerInbytesWaiting(Handle: TSerialHandle): LongInt; Then the read can be done using this value to get the exact number of bytes into the properly dimensioned buffer, which can then be provided to the event procedure as a TBytes container. I know too little about the operating system inner workings to be able to do this myself... -- Bo Berglund Developer in Sweden _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal