Seite 1 von 1
Bits setzen mit Python
Verfasst: Freitag 11. Februar 2011, 17:00
von Balu
Hallo zusammen,
ich möchte mit einem Python-Programm einen GPIO-Port meines Rechners ansteuern. Dazu muss ich zuerst an Port 0x800 das 5. Bit High setzen. Nun weiß ich leider nicht wie ich einzelne Bits eines Ports setzen, bzw. beschreiben kann.
Hat damit zufällig jemand Erfahrung und kann mir evtl. weiterhelfen?
Schöne Grüße und ein schönes Wochenende
Flo
Re: Bits setzen mit Python
Verfasst: Freitag 11. Februar 2011, 17:13
von BlackJack
@Balu: Das sind deutlich zu wenig Informationen. Was ist das für ein System? Wie wird die gewünschte GPIO-Leitung da angesprochen? Beziehungsweise wie werden "Ports" dort angesprochen? Ohne mehr Details zu Hardware und Betriebssystem kann man da nichts sagen.
Re: Bits setzen mit Python
Verfasst: Samstag 12. Februar 2011, 20:22
von Py-Prog
Und wieder ein mal hätte sich diese Frage erübrigen können.
SCNR
Re: Bits setzen mit Python
Verfasst: Samstag 12. Februar 2011, 23:13
von Leonidas
Py-Prog hat geschrieben:Und wieder ein mal hätte sich diese Frage erübrigen können.
SCNR
Inwiefern? Ich sehe das da Information fehlt, aber in sich ist die Frage doch total ok. Ich würde eher sagen dein Post dient keinem Zweck, außer "flamebait" vielleicht.
Re: Bits setzen mit Python
Verfasst: Sonntag 13. Februar 2011, 14:07
von Py-Prog
Du hast mich auf eine Idee gebracht, man könnte auch eine "Anleitung" darüber schreiben was man alles in einen Beitrag schreiben muss: System, Python-Version, Traceback, ...
. Das würde dann sogar die Felder im Profil unnötig machen.

Re: Bits setzen mit Python
Verfasst: Sonntag 13. Februar 2011, 14:10
von Hyperion
Py-Prog hat geschrieben:Du hast mich auf eine Idee gebracht, man könnte auch eine "Anleitung" darüber schreiben was man alles in einen Beitrag schreiben muss: System, Python-Version, Traceback, ...
. Das würde dann sogar die Felder im Profil unnötig machen.

Das gibt es schon, ist sogar im Thread "Vor dem Posten lesen" im Allgemeinen Forum verlinkt
http://wiki.python.de/Forum/Regeln
Re: Bits setzen mit Python
Verfasst: Montag 14. Februar 2011, 05:34
von snafu
Hyperion hat geschrieben:Py-Prog hat geschrieben:Du hast mich auf eine Idee gebracht, man könnte auch eine "Anleitung" darüber schreiben was man alles in einen Beitrag schreiben muss: System, Python-Version, Traceback, ...
. Das würde dann sogar die Felder im Profil unnötig machen.

Das gibt es schon, ist sogar im Thread "Vor dem Posten lesen" im Allgemeinen Forum verlinkt
http://wiki.python.de/Forum/Regeln
Klassischer Fall von *OWNED*

Re: Bits setzen mit Python
Verfasst: Montag 14. Februar 2011, 08:41
von Balu
ok, ok. Sorry hab das Freitag abend noch schnell zusammengeschrieben. ohne das durchzulesen... :K Tut mir leid...
Also ich arbeite mit Ubuntu 10.10, und möchte auf einem Nexcom Panel-PC APPC die GPIO-Ports ansprechen. Dazu steht im Handbuch folgendes:
I/O Base Address: 800h
Bit0: GPI 50
Bit1: GPI 51
Bit2: GPI 52
Bit3: GPI 53
Bit4: GPO 54
Bit5: GPO 55
Bit6: GPO 56
Bit7: GPO 57
1. Selsect GPIO group5 by setting I/O port 800h to 5h.
2 Read/Write GPIO data by I/O port 802h.
Um den Port zu testen hatte ich bereits an einem anderen Gerät, an dem ich den Schritt 1 weglassen konnte einfach das Beispielprogramm toggle.py, welches bei PortIO vorhanden ist benutzt. Dort werden alle Ausgänge im Takt von 3 Sekunden zwischen High und Low umgeschalten. Der Beispielcode ist folgender:
Code: Alles auswählen
#!/usr/bin/python
# .+
#
# .context : PortIO
# .title : Toggle parallel port lines
# .kind : command shell
# .author : Fabrizio Pollastri <f.pollastri@inrim.it>
# .site : Torino - Italy
# .creation : 13-Nov-2008
# .copyright : (c) 2008 Fabrizio Pollastri
# .license : GNU General Public License (see below)
#
# This file is part of "PortIO, python low level I/O for Linux x86".
#
# PortIO is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# PortIO is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# .-
import sys, time, os
import portio
# check for root privileges
if os.getuid():
print 'You need to be root! Exiting.'
sys.exit()
# acquire permission for I/O on lp0
status = portio.ioperm(0x378, 1, 1)
if status:
print 'ioperm:',os.strerror(status)
sys.exit()
# toggle for ever the data lines of lp0
data = 0
while 1:
lp0in = portio.inb(0x378)
portio.outb(data,0x378)
print 'read %x from lp0, written %x to lp0' % (lp0in,data)
data = ~data & 0xff
time.sleep(3)
#### END
Im Beispiel ist der gewünschte Port zum schreiben der Ausgänge 0x378. Ändert man diesen auf 802 sollte das mit meinem Gerät funktionieren.
Nun würde ich eben gerne wissen, wie ich es hinbekomme, vorher eben noch das 5. Bit von Port 800 auf High setzen kann?
Leider hab ich bisher noch nicht wirklich viel Erfahrung mit Python, daher hoffe ich das mir hier jemand helfen kann.
Schöne Grüße
Flo
Re: Bits setzen mit Python
Verfasst: Montag 14. Februar 2011, 09:24
von BlackJack
@Balu: Bits manipuliert man mit den gängigen
bitweisen Operatoren. Gezielt Bits setzen geht zum Beispiel mit einer Oder-Verknüpfung und der entsprechenden Bitmaske. Wenn Du also einen Wert `x` hast, kannst den Wert mit gesetztem 5. Bit mit ``x | 2**5`` ermitteln. Python benutzt syntaktisch die gleichen Operatoren wie C (und C#, Java, und viele andere).
Re: Bits setzen mit Python
Verfasst: Montag 14. Februar 2011, 10:54
von Balu
Sorry das ich so blöd frage, aber habe leider wirklich nicht viel Ahnung von dem ganzen...
wenn ich jetzt port 800 schreiben möchte, dann könnte ich doch theoretisch wie im Beispiel schreiben:
input = portio.inb(0x800)
mask= 0x16
data= (input|mask)
portio.outb(data,0x800)
Damit lese ich Port 800 aus, dann definiere ich meine Maske in HEX, wobei das 5. Bit HIgh ist und mache eine Oder-Verknüpfung. Zum SChluß schreibe ich dann an port 800 den Wert, der bei der Oder-Verknüpfung herauskam.
Wenn ich das so mache, bekomme ich aber immer die Meldung Segmentation fault. Sobald ich meine Änderungen wieder rückgängig mache, läuft alles wieder.
Re: Bits setzen mit Python
Verfasst: Montag 14. Februar 2011, 11:01
von cofi
Dann versuch es doch mal mit einer Maske die auch tatsaechlich das 5. Bit setzt, zb `0x20`
Re: Bits setzen mit Python
Verfasst: Montag 14. Februar 2011, 11:07
von Balu
Ok, das mit dem 5. Bit stimmt natürlich.
Aber der Fehler bleibt leider der selbe...
Re: Bits setzen mit Python
Verfasst: Montag 14. Februar 2011, 13:38
von BlackJack
@Balu: Hast Du Dir für den Port auch die nötigen Rechte geholt? Also auch den `ioperm()`-Aufruf angepasst?
Re: Bits setzen mit Python
Verfasst: Montag 14. Februar 2011, 14:52
von Balu
Ja, nachdem ich immer den Fehler bekam hab ich dort auch den Port 800 eingetragen.
Somit ist der Fehler Segmentation fault weg.
Aber wenn ich mit portio.outb(0x20,0x800) den Hexwert 20 schreibe, dann sollte bei einer Abfrage portio.inb(0x800) doch auch die 20 übernommen worden sein?
Wenn ich so vorgehen, bleibt nämlich bei der Abfrage des Ports eine 0 als Wert stehen.
Das ist alles sehr seltsam...
Trotzdem schon mal vielen Dank für die Hilfe!
Re: Bits setzen mit Python
Verfasst: Montag 14. Februar 2011, 16:39
von BlackJack
@Balu: Auslesen kann man die Bits nur wenn die Hardware das entsprechend zulässt. Keine Ahnung ob das in diesem Fall so sein sollte oder nicht.
Die Dokumentation scheint mir auch ein wenig dünn zu sein. Was bedeutet "select" bei 0x800? Bit ist gesetzt, dann kann man das entsprechende Bit in 0x802 benutzen und sonst ist es undefiniert, oder was?
Hast Du denn Hardware an den Leitungen hängen, mit der Du die Funktion überprüfen kannst?
Re: Bits setzen mit Python
Verfasst: Dienstag 15. Februar 2011, 16:18
von Balu
Habe das Problem inzwischen gelöst, waren mehrere Fehler die noch Probleme darstellten.
Zum einem eine falsche Aussage vom Supprt, das ich das 5. Bit High setzen soll. Dies war falsch, ich musste lediglich in Port 800 0x5h schreiben. Dies scheint wohl eine Art Freigabe für die Nutzung der GPIO-Ports zu sein.
Zum andern hatte ich die Rechte mit ioperm nur für jeweils einen der beiden Ports gesetzt. Hatte ich da beide ausgewählt (802 und 800) konnte ich auch schreiben und bekam am Ende auch vernünftige Ergebnisse.
Ich danke euch allen für die Hilfe und melde mich sicher wieder einmal bei einer Frage.
Schöne Grüße
Flo