Serielle Schnittstelle reseten

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Serielle Schnittstelle reseten

Beitrag von Mathias »

Ich verwende folgende Code:

Code: Alles auswählen

var
    ser: TBlockSerial;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  ser := TBlockSerial.Create;
  ser.Purge;
 
  {$IFDEF MSWINDOWS}
  ser.Connect('COM8');
  {$ELSE}
  ser.Connect('/dev/ttyUSB0');
  {$ENDIF}
 
  Sleep(1000);
  ser.Config(9600, 8, 'N', SB1, False, False);
 
  Memo1.Lines.Add('Device: ' + ser.Device + '   Status: ' + ser.LastErrorDesc + ' ' + IntToStr(ser.LastError));
  Sleep(1000);
end;   
 
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  ser.Free;
end;


Wen das Programm sauber über FormClose beendet wird, dann läuft alles wie gewollt.
Wird aber das Programm zB. über eine Laufzeitfehler oder Ctrl-F2 beendet, dann ist bei einem neuen Start meist nicht mehr möglich die Schnittstelle zu initialisieren.
Seit ich ser.Purge eingebaut habe, dann geht die Initialisierung ab und zu.

Wen ich aber dann ein externes Serial-Terminal (GtkTerm) starte, und anschliessend beende, dann ist eine Spezialisierung wieder möglich.

Gibt es bei TBlockSerial auch ein Reset oder was ähnliches, wie im Terminal-Programm ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Serielle Schnittstelle reseten

Beitrag von Mathias »

Hat niemand eine Idee ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Serielle Schnittstelle reseten

Beitrag von theo »

Was ist Ctrl-F2?

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Serielle Schnittstelle reseten

Beitrag von Mathias »

theo hat geschrieben:Was ist Ctrl-F2?

In der Lazarus IDE Start/Halt.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Serielle Schnittstelle reseten

Beitrag von theo »

Was willst du da machen? Abwürgen ist abwürgen. Das ist ja der Witz davon, dass dabei das Programm nicht mehr gefragt wird.

Ich kenne ja dein Szenario nicht. Ich sicher würde das Blockserial nach Gebrauch immer freen, nicht nur am Programmende.
Vielleicht gibt es da auch generelle Methoden unter Linux. k.A.

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Serielle Schnittstelle reseten

Beitrag von Mathias »

Hast du noch nie ein Programm mit einer Konsole geschrieben , und versehentlich das Programm über die Konsole geschlossen.
Oder einen SIGSEV gehabt.

Das ist eben das Problem beim Com-Port, dann kann ich diesen bei einem Neustart nicht mehr zurück holen, ausser wie oben beschrieben mit einem Fremd-Programm.
Wen das Fremd-Programm dies kann, dann sollte mein Program das auch irgendwie können. :wink:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Serielle Schnittstelle reseten

Beitrag von theo »

"Anständige" Signale kann man unter Linux schon abfangen, aber SIGKILL nicht.

SIGHUP oder SIGTERM kann man z.B. so in ein normales Form.Close "überführen".

Code: Alles auswählen

uses BaseUnix;  
...
var
  ...
  oahup, nahup, oat, nat: PSigActionRec;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
 
 
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  ShowMessage('test');
end;
 
procedure DoSig(sig: cint); cdecl;
begin
  writeln(sig);
  Form1.Close;
end;
 
initialization
  new(nahup);
  new(oahup);
  nahup^.sa_Handler := SigActionHandler(@DoSig);
  fillchar(nahup^.Sa_Mask, sizeof(nahup^.sa_mask), #0);
  nahup^.Sa_Flags := 0;
   {$ifdef Linux}// Linux specific
  nahup^.Sa_Restorer := nil;
   {$endif}
  if fpSigAction(SIGHUP, nahup, oahup) <> 0 then
  begin
    //Fehler
  end;
 
  new(nat);
  new(oat);
  nat^.sa_Handler := SigActionHandler(@DoSig);
  fillchar(nat^.Sa_Mask, sizeof(nat^.sa_mask), #0);
  nat^.Sa_Flags := 0;
   {$ifdef Linux}// Linux specific
  nat^.Sa_Restorer := nil;
   {$endif}
  if fpSigAction(SIGTERM, nat, oat) <> 0 then
  begin
    //Fehler
  end;
end.       

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Serielle Schnittstelle reseten

Beitrag von Mathias »

Ich denke, du hast meine Frage falsch verstanden.

Kann man die Verbindung zum COM-Port irgendwie erzwingen, wen die noch mit einem anderen Programm(abgestürztes/abgewürgten) verbunden ist ?
Wie schon geschrieben, gkterm kann dies, dann müsste man dies im eigenen Programm auch einbauen können.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Serielle Schnittstelle reseten

Beitrag von theo »

Ich habe dich schon verstanden, kenne aber keinen Weg für das was du meinst.
Kannst ja mal suchen, das hat mit dem Betriebssystem mehr zu tun als mit Lazarus.
Unter Linux vielleicht

Code: Alles auswählen

 tput reset > /dev/ttyXX

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Serielle Schnittstelle reseten

Beitrag von Mathias »

Ich habe es gerade Versucht mit

Code: Alles auswählen

$ tput reset > /dev/ttyUSB0 
$ meinProgramm


Bringt leider nichts.

Die Fehlermeldung in meinem Programm ist folgende:

Code: Alles auswählen

Device: /dev/ttyUSB0   Status: Bad file number 9


Vielleicht hilft die weiter.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Serielle Schnittstelle reseten

Beitrag von pluto »

Code: Alles auswählen

 
procedure TPLArduinoPCInterface_Uart.SetEnabled(AValue: Boolean);
begin
  inherited SetEnabled(AValue);
 
  if (not FileExists(Device)) then begin
    if Assigned(BlockSerial) then begin
      writeln('Socket Closed!!!');
      FreeAndNil(BlockSerial);
      BlockSerial:=nil;
    end;
  end
  else begin
    if not Assigned(BlockSerial) then begin
      writeln('Connect Socket');
 
      if Assigned(BlockSerial) then begin
        BlockSerial.Free;
        BlockSerial:=nil;
      end;
 
      BlockSerial:=TBlockSerial.Create;
      BlockSerial.LinuxLock:=False;
      BlockSerial.RaiseExcept:=False;
      BlockSerial.Connect(Device);
      sleep(1000);
      BlockSerial.Config(9600,8,'N',SB1,true,false);
    end;
  end;
end; // TPLArduinoPCInterface_Uart.SetEnabled
 

Ich mache das immer so, wichtig ist eben unter Linux das LinuxLock auf False stellt wird.
MFG
Michael Springwald

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Serielle Schnittstelle reseten

Beitrag von Mathias »

Ich mache das immer so, wichtig ist eben unter Linux das LinuxLock auf False stellt wird.

Danke, genau dies habe ich gesucht. :)

So wie ich sehe brauchst du dies auch für deinen Arduino.
Für was ist das : BlockSerial.RaiseExcept:=False; ?
Und bei Config hast du auch noch ein true mehr als ich ?

Wie sieht es unter Windows aus, muss ich da das LinuxLock ausklammern ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Serielle Schnittstelle reseten

Beitrag von pluto »

Für was ist das : BlockSerial.RaiseExcept:=False; ?

Das weiß ich selbst nicht genau.

Und bei Config hast du auch noch ein true mehr als ich ?

Das scheint egal zu sein, jedenfalls bei Arduino. Ob das immer so ist, weiß ich nicht.

Wie sieht es unter Windows aus, muss ich da das LinuxLock ausklammern ?

Ich denke nicht, da wird einfach nicht unterstützt oder der Compiler wirft eine Fehlermeldung.
MFG
Michael Springwald

creed steiger
Beiträge: 957
Registriert: Mo 11. Sep 2006, 22:56

Re: Serielle Schnittstelle reseten

Beitrag von creed steiger »

steht doch in der Doku:


property RaiseExcept: boolean read FRaiseExcept write FRaiseExcept;

If True, communication errors raise exceptions. If False (default), only the LastError value is set.

property LinuxLock: Boolean read FLinuxLock write FLinuxLock;

If set to True (default value), port locking is enabled (under Linux only). WARNING: To use this feature, the application must run by a user with full permission to the /var/lock directory!

Antworten