On 23/09/18 08:15, Bo Berglund via Lazarus wrote:
On Sun, 23 Sep 2018 08:39:52 +0200, Bo Berglund via 
Lazarus<lazarus@lists.lazarus-ide.org> wrote:
I have now come as far in my application as I can test the way the>Serial unit opens and closes com 
ports.>It turns out that on Windows there are two port name syntaxes:>>Ports 1..9:     COM1 to 
COM9 will work>Ports 10..255:  Only \\.\COM10 to \\.\COM255 will work>>But one does not need 
to use different naming depending on the port>number, the second syntax \\.\COMx works also for 
ports 1..9
Forgot to add a question regarding making this a cross-platformprogram:
If I add a check for the platform inside my program, how sghould itlook like to 
work on both Windows and Linux?
Something like this:
function TWiFiCommTester.ConnectSerial(Port: byte; Baud: integer):boolean;var  
ComportName: string;  Flags: TSerialFlags;begin  FLastError := '';  {$IFDEF 
WINDOWS}  ComPortName:= '\\.\COM' + IntToStr(Port);  {$ENDIF}  {$IFDEF UNIX}    
 //What goes here?     ComPortName := ????  {$ENDIF}  FSerial := 
SerOpen(ComPortName);  ....

Sorry Bo and Paul, I mailed you directly when I meant to reply here. This rolls up the messages from earlier.


> Ports 1..9: COM1 to COM9 will workPorts 10..255: Only \\.\COM10 to \\.\COM255 will work

Which is something that I pointed out to you, although in my case I think I only tested up to 12 (i.e. with an 8-port card).

What comes after 255: 0 or 1? If 0 which form or name does it require?

> I have yet to complete other parts of the application so I don't yetknow if the data flow will wok as expected.

Note that that unit was specifically written to be usable either with or without separate communications threads. If you're /not/ using threads then there's a callback so that the read-with-timeout functions can periodically call Application.ProcessMessages, and that the places that it is used are OS-specific. You obviously /don't/ want to use that callback if the comms functions are in their own threads, since APM should only be called from the main thread.

I'm probably losing this email address on Tuesday, if there's anything that you think I can possibly clarify please raise it sooner rather than later.

> On 09/23/2018 02:39 AM, Bo Berglund via Lazarus wrote:...> Notice that contrary to the wiki example adding a colon to the end> like COM32: does NOT work so that is a wiki error.
> If I remember correctly the colon at the end is required for WinCE?--

OK, but this is something that the application programmer needs to be aware of. I suppose it would be possible to modify the unit so that if it sees a trailing : it changes it to a leading \\.\ if there isn't one there already, but since the exact names are OS-specific and since we're already insisting that the application programmer or user puts in /dev/ for unix I'm not sure that's justifiable.

In any event I'm not in a position to do any mods right now and am probably about to lose access to Solaris (which is probably still worth testing against) permanently.

(* If there are no serial ports on the system then return NIL, otherwise a *) (* TStringList. *) (* *) (* This returns an object, it is the caller's (eventual) responsibility to free *) (* this. *)
//
FUNCTION EnumeratePorts: TStringList;

(* On a Linux system with udev or similar the /dev directory will only contain *) (* devices which have been detected as being present. On an older system it *) (* will probably contain all possible devices so we need to restrict the list *) (* to what's reasonable; the user should still be able to enter a device name *) (* manually if necessary, e.g. where a machine with 2x standard ports plus a *) (* 2-port card insists that it's got ttyS0, ttyS1, ttyS45 and ttyS46. *)

CONST countTtyS= 12; (* Main board plus an 8-port card *) countTtyUSB= 8; (* Four dual-port adapters *) countTtyI= 4; (* A single 4-port ISDN card. *)

VAR     searchRec: TSearchRec;
        counter: INTEGER;

BEGIN
  RESULT:= TStringList.Create;
  RESULT.Sorted:= TRUE;
  counter:= countTtyS;
  IF FindFirst('/dev/ttyS*', faSysFile, searchRec) = 0 THEN
    REPEAT
      RESULT.Append('/dev/' + searchRec.Name);
      DEC(counter)
    UNTIL (FindNext(searchRec) <> 0) OR (counter <= 0);
  FindClose(searchRec);
  counter:= countTtyUSB;
  IF FindFirst('/dev/ttyUSB*', faSysFile, searchRec) = 0 THEN
    REPEAT
      RESULT.Append('/dev/' + searchRec.Name);
      DEC(counter)
    UNTIL (FindNext(searchRec) <> 0) OR (counter <= 0);
  FindClose(searchRec);
  counter:= countTtyI;
  IF FindFirst('/dev/ttyI*', faSysFile, searchRec) = 0 THEN
    REPEAT
      RESULT.Append('/dev/' + searchRec.Name);
      DEC(counter)
    UNTIL (FindNext(searchRec) <> 0) OR (counter <= 0);
  FindClose(searchRec);
  IF Result.Count = 0 THEN
    FreeAndNil(RESULT)
END { EnumeratePorts } ;

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

[Opinions above are the author's, not those of his employers or colleagues]
--
_______________________________________________
Lazarus mailing list
Lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus

Reply via email to