Il 09/09/2018 13:33, Bo Berglund via
Lazarus ha scritto:
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.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 7For 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. 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; 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%!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... 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