Fragen zu PySerial und Basisdatentypen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
suho
User
Beiträge: 5
Registriert: Montag 14. Januar 2008, 20:59

Hallo!

Ich habe ein Programm für einen AVR 8-bit Mikrocontroller geschrieben welches unter anderem Daten über sie serielle Schnittstelle überträgt. Zur fehlerfreien Übertragung wird auch ein CRC Wert der Daten gesendet der mit folgender C-Funktion berechnet wird:

Code: Alles auswählen

uint16_t crc_xmodem_update(uint16_t crc, uint8_t data) {
	int i;
	crc = crc ^ ((uint16_t)data << 8);
	for (i=0; i<8; i++) {
		if(crc & 0x8000)
			crc = (crc << 1) ^ 0x1021;
		else
			crc <<= 1;
	}
	return crc;
}
Ich möchte jetzt ein Prgramm in Python schreiben um mit dem Mikrocontroller zu kommunizieren. Dazu 2 Fragen:
1. Gibt es mit PySerial eine Möglichkeit eine Liste der zur Verfügung stehenden seriellen Schnittstellen zu bekommen?
2. Ich habe die CRC Funktion folgendermaßen in Python umgesetzt finde die Lösung aber ineffizient, da ich "unnötige" Formatierungen vornehmen muss da Python keinen reinen 8-bit char oder 16-bit int datentyp besitzt mit dem man logisches rechts/links-schieben betreiben kann:

Code: Alles auswählen


def crc_xmodem_update(crc, data):
	crc = crc ^ (data << 8)
	for i in range(8):
		if(crc & 0x8000):
			crc = (crc << 1) ^ 0x1021
		else:
			crc = crc << 1
	crc -= (crc >> 16)*(1 << 16)
	return crc

def get_crc(data):
	crc = 0xFFFF
	for c in data:
		crc = crc_xmodem_update(crc, ord(c))
	return crc
Meine Frage ist ganz einfach: Würdet ihr das so machen oder etwa anders? Es ist für mich schon recht interessant da ich bei der Datenübertragung immer 8-bit Zeichen sende und dann ständig mit chr, odr, int usw die typen wandeln muss.
BlackJack

Sieht ganz okay aus.

Bis auf Zeile 10, die ziemlich kompliziert ``crc &= 0xfff`` implementiert. :-)

Eventuell bringt es etwas eine ganze Zeichenkette mit dem `array`-Modul in Zahlen um zu wandeln, statt die einzelnen Zeichen mit `ord()`, aber ansonsten sieht das schon ganz gut aus.

Falls das doch ein Flaschenhals im Programm werden sollte, kannst Du's ja immer noch mit Psyco, Cython, oder C via `ctypes` angebunden versuchen. :-)
BlackJack

Ungetestet:

Code: Alles auswählen

from itertools import imap

def crc_xmodem_update(crc, data):
    crc ^= data << 8
    for dummy in xrange(8):
        crc <<= 1
        if crc & 0x8000:
            crc ^= 0x1021
    return crc & 0xffff

def get_crc(data):
    return reduce(crc_xmodem_update, imap(ord, data), 0xffff)
suho
User
Beiträge: 5
Registriert: Montag 14. Januar 2008, 20:59

Hmm ok, besten dank, die Funktion reduce() kannte ich noch nich
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

suho hat geschrieben:1. Gibt es mit PySerial eine Möglichkeit eine Liste der zur Verfügung stehenden seriellen Schnittstellen zu bekommen?
Vielleicht so:

Code: Alles auswählen

from serial import Serial
ports = []
for port in range(8):
    try:
        s = Serial(port)
        ports.append(str(port))
    except:
        pass
print 'Vorhandene COM-Ports:', ', '.join(ports)
MfG
HWK
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Die 1. Variante berücksichtigt einen vorhandenen Port nicht, wenn auf ihn nicht zugegriffen werden kann, weil er z.B. schon verwendet wird. Es sollten deshalb alle Ports, die beim Öffnen nicht Fehler Nr. 2 ('Das System kann die angegebene Datei nicht finden.') auslösen, in die Liste aufgenommen werden. Deshalb ein neuer Versuch:

Code: Alles auswählen

from serial import Serial, SerialException
ports = []
for port in range(8):
    try:
        s = Serial(port)
    except SerialException, error:
        if error[0].startswith('could not open port: (2,'):
            continue
    ports.append(port)
print 'Vorhandene COM-Ports:', ', '.join(str(x) for x in ports)
MfG
HWK
Antworten