Ich hätte die Bitte, folgende Routine mal auf Eurem Heimsystem zu testen und Rückmeldung zu geben.
Voraussetzung: Linux, einen Rechner mit seriellen Schnittstellen und Interesse am Thema.
Beim Wechsel von Windows auf Linux fiel schnell auf, dass die seriellen Schnittstellen nicht so einfach ansprechbar waren. Der angemeldete User muss die Rechte auf die Dateien haben oder (besser) in einer Gruppe mit entsprechenden Rechten sein.
D.h. ohne Rumdoktern im Terminal kein Zugriff. Beim Stöbern nach funktionierendem PB-Code bin ich zwar auf einige Nachfragen, jedoch bisher nicht auf so ganz befriedigende Antworten gestoßen.
Da mein bisher aufwändigstes Windowsprogramm ein Tool für die serielle Schnittstelle ist, wäre es mein Ziel gewesen, es ansatzweise so komfortable auf Linux umsetzen zu können.
Die professionelle Lösung ist, als Root eine Gruppe mit den Rechten an der Schnittstelle anzulegen und den User zur Gruppe hinzuzufügen.
Für den schnellen Heimbetrieb hab ich mir nach und nach folgendes erarbeitet und hätte gerne gewusst, ob dies in den meisten Umgebungen erfolgreich sein könnte:
Was sollte die aufgeführte Routine erledigen:
- Es listet vorhandene serielle Schnittstellen per debug (ttyS0, ...)
- Es listet die Rechte des aktuellen Users an diesen Ports per debug.
- Es bietet die Möglichkeit in einem automatisch erscheinenden Terminal die Rechte für jeden vorhandenen Port per 'sudo' für diese Sitzung auf den aktuellen User zu erweitern (sudo-Passwort nötig)
- Es zeigt die neuen Rechte an diesen Ports und per debug an.
Man muss die Programmumgebung dazu nicht verlassen, z.B. um nach Anweisung zwischendurch im Terminal arbeiten. Das Terminal wird automatisch nur zur Eingabe des sudo-Passwortes angeboten!
Dann sollte auch das PureBasic-Beispiel in .../examples/sources/SerialPort.pb laufen.
Leider Ist das Programm relativ umfangreich und abschreckend...
Code: Alles auswählen
;SERIAL_AUTORISATION ...
Global.i gComPortsNum, gAllAccess
Global.s gttyFile = GetHomeDirectory()+"tty.txt"
Global.s gComPortNumList
Structure ComPortData
ComPortName.s
ComPortAccessPre.b
ComPortAccessPost.b
EndStructure
Global NewList ttyFileContent.ComPortData()
Procedure ComPortsExists(List ComList.ComPortData()); Lists existing ComPorts
Protected.i I, Pos, Line_, Num
Protected.s ComPort, TempS
If ReadFile(0, gttyFile)
While Not Eof(0)
Line_+ 1
TempS= ReadString(0)
If FindString(TempS, "at I/O")
Pos= FindString(TempS, "ttyS")
If Pos
ComPort= "ttyS"
Num+ 1
I= 0
While Mid(TempS, Pos + 4 + I, 1)<> " "
ComPort+ Mid(TempS, Pos + 4 + I, 1)
I+ 1
Wend
AddElement(ComList())
ComList()\ComPortName= ComPort
EndIf
EndIf
Wend
EndIf
ProcedureReturn Num
EndProcedure
Procedure.s ComPortNumList(List ComList.ComPortData()); Built a list in string, f.e. '[01]', works only with single figure, 0 - 9
Protected.s PortList= "["
ResetList(ComList())
While NextElement(ComList())
PortList+ Mid(ComList()\ComPortName, FindString(ComList()\ComPortName, "ttyS") + 4)
Wend
PortList+ "]"
ProcedureReturn PortList
EndProcedure
Procedure ComPortAccessbility(PostRights, List ComList.ComPortData()); Reads autorisation for existing ComPorts of current user
Protected.i Line_, AllAccess= #True
Protected.s TempS
If ReadFile(0, gttyFile)
While Not Eof(0)
Line_+ 1
TempS= ReadString(0)
ResetList(ttyFileContent())
If ListSize(ttyFileContent())
If NextElement(ttyFileContent())
Repeat
If FindString(TempS, ttyFileContent()\ComPortName)
If Mid(TempS, 8, 2)<> "rw"; No access for current user?
If PostRights
ttyFileContent()\ComPortAccessPost= #False
Else
ttyFileContent()\ComPortAccessPre= #False
AllAccess= #False
EndIf
Else
If PostRights
ttyFileContent()\ComPortAccessPost= #True
Else
ttyFileContent()\ComPortAccessPre= #True
EndIf
EndIf
EndIf
Until NextElement(ttyFileContent())= 0
EndIf
EndIf
Wend
EndIf
ProcedureReturn AllAccess
EndProcedure
;1. control kernel ringbuffer, find lines with 'ttyS', export to ttyFile ...
ProgramID = RunProgram("xterm", "-e " + #DQUOTE$ + "dmesg | grep ttyS | /usr/bin/tee " + gttyFile + #DQUOTE$, GetCurrentDirectory(), #PB_Program_Wait)
Delay(100)
gComPortsNum= ComPortsExists(ttyFileContent())
Debug "Existing Com-Ports: " + Str(gComPortsNum)
If gComPortsNum= 0: End : EndIf
ResetList(ttyFileContent())
While NextElement(ttyFileContent())
Debug ttyFileContent()\ComPortName
Wend
gComPortNumList= ComPortNumList(ttyFileContent())
;2. list files with 'ttyS'+no. of existing ports in 'gttyFile' ...
ProgramID = RunProgram("xterm", "-e " + #DQUOTE$ + "ls -l /dev/ttyS" + gComPortNumList + " | tee " + gttyFile + #DQUOTE$, GetCurrentDirectory(), #PB_Program_Wait)
Delay(100)
gAllAccess= ComPortAccessbility(0, ttyFileContent())
Debug "Authorisation ..."
ResetList(ttyFileContent())
While NextElement(ttyFileContent())
Debug ttyFileContent()\ComPortName + ": " + Str(ttyFileContent()\ComPortAccessPre)
If ttyFileContent()\ComPortAccessPre= #False
Debug "Loggin as 'sudo' to change authorisation for " + ttyFileContent()\ComPortName + " (close terminal if you want no change) ..."
;3. Loggon as sudo and change autorisation for each port without accessiblity...
ProgramID = RunProgram("xterm", "-e " + #DQUOTE$ + "sudo chmod a+rw /dev/" + ttyFileContent()\ComPortName + #DQUOTE$, GetCurrentDirectory(), #PB_Program_Wait)
EndIf
Wend
If Not gAllAccess; Access on all ComPorts? - List with new rights on files ...
ProgramID = RunProgram("xterm", "-e " + #DQUOTE$ + "ls -l /dev/ttyS" + gComPortNumList + " | tee " + gttyFile + #DQUOTE$, GetCurrentDirectory(), #PB_Program_Wait)
Delay(100)
ComPortAccessbility(1, ttyFileContent())
Debug "New authorisation ..."
ResetList(ttyFileContent())
While NextElement(ttyFileContent())
Debug ttyFileContent()\ComPortName + ": " + Str(ttyFileContent()\ComPortAccessPost)
Wend
EndIf
In einer VirtualBox müssen BEIM ANLEGEN bereits die Rechte an den Schnittstellen übergeben werden, sonst geht (auch nachträglich) nix!
Ziel des Ganzen wäre, für die meisten einigermaßen aktuellen Distributionen und Installationen eine funktionierende Routine zu schaffen.
Erstmal vielen Dank an die Mitwirkenden
Charly
PS:
Rücksetzen kann man die Rechte für Wiederholungen der Tests für jeden Port im Terminal mit:
sudo chmod a-rw /dev/ttySx (für x die Nummern des jeweilgen Ports angeben und erneut aufrufen, z.B. sudo chmod a-rw /dev/ttyS0, sudo chmod a-rw /dev/ttyS1, ...)
Beim nächsten login sind die ursprünglichen Rechte grundsätzlich wieder hergestellt.