Diplomarbeit - Lehrstuhl für Nachrichtentechnik
Transcription
Diplomarbeit - Lehrstuhl für Nachrichtentechnik
Universität Kaiserslautern Fachbereich Elektrotechnik Lehrstuhl für Nachrichtentechnik Prof. Dr.-Ing. Ralph Urbansky Diplomarbeit Entwurf und Implementierung des Physical-Layers mit variabler Faltungscodierung für ein Powerline-System im Rahmen eines fächerübergreifenden Projektes mit dem Fachbereich Informatik Denis Geiter September 2002 Betreuer: Prof. Dr.-Ing. Ralph Urbansky Dr.-Ing. Wolfgang Sauer-Greff Bearbeiter: Denis Geiter Gerhart-Hauptmann-Str. 24 Denis Geiter Gerhart-Hauptmann-Str. 24 67663 Kaiserslautern Erklärung Die vorliegende Arbeit ist unter Betreuung von Herrn Dr.-Ing. Wolfgang Sauer-Greff entstanden. Hiermit erkläre ich, dass ich die vorliegende Studienarbeit selbstständig und ohne weitere fremde Hilfe verfasst und keine anderen als die ausdrücklich angegebenen Hilfsmittel verwendet habe. Kaiserslauern, den 26.9.2002 (Denis Geiter) Danksagung Ich möchte mich bei allen, die mich bei der Erstellung der vorliegenden Arbeit unterstützt haben, herzlich bedanken. Insbesondere danke ich Herrn Dr.-Ing. Sauer-Greff für seine Unterstützung und die Vielzahl an Anregungen, die er in meine Arbeit einbrachte. Weiterhin gilt mein Dank allen, die meine Arbeit gelesen und mir bei der Überarbeitung geholfen haben. INHALTSVERZEICHNIS 1 Einleitung ....................................................................................................................1 1.1 Fächerübergreifendes Projekt "Chatroom over Powerline" ............................... 1 1.2 Gliederung .......................................................................................................... 2 1.3 Was ist Powerline-Communication? .................................................................. 2 1.3.1 Die Marktsegmente .................................................................................. 3 1.3.2 Eigenschaften der PLC ............................................................................ 3 2 Grundlagen der PLC .................................................................................................5 2.1 Kommunikationskanal/Modell........................................................................... 5 2.1.1 Koppelnetzwerk ....................................................................................... 5 2.1.2 Kanalmodell des PLC-Kanals.................................................................. 7 2.1.3 Dämpfung eines PLC-Kanals .................................................................. 8 2.1.4 Zeitvariantes Verhalten des Netzes.......................................................... 8 2.1.5 Störungen in der Stromleitung ................................................................. 8 2.2 Übertragungsverfahren OFDM .......................................................................... 9 2.2.1 Multiplexing........................................................................................... 10 2.2.2 Modulation und Demodulation .............................................................. 12 2.2.3 Einfügen von Schutzintervallen ............................................................. 13 2.2.4 Impulsstörungen..................................................................................... 14 2.2.5 Differenzielle Modulation...................................................................... 15 2.2.6 Nachteile von OFDM............................................................................. 15 2.2.7 Anforderungen an den Sendeverstärker................................................. 16 2.2.8 Schmalbandige Störungen ..................................................................... 16 2.2.9 Kanalkapazität........................................................................................ 17 2.3 Standardisierung der Powerline-Communication ............................................ 19 2.3.1 Regulierungen in Europa ....................................................................... 19 2.3.2 Medien-Zugriffsprotokoll im CENELEC-C-Band ................................ 21 2.3.3 Regulierungen in USA........................................................................... 22 2.3.4 Regulierungen außerhalb Europas und der USA ................................... 23 2.3.5 Die Nutzungsbestimmung 30................................................................. 23 2.3.6 HomePlug Power Alliance..................................................................... 25 2.3.7 PowerPacket........................................................................................... 25 2.4 Das OSI-Referenzmodell ................................................................................. 29 2.4.1 Die Bitübertragungsschicht.................................................................... 30 2.4.2 Die Sicherungsschicht............................................................................ 31 2.4.3 Die Vermittlungsschicht ........................................................................ 31 2.4.4 Die Transportschicht .............................................................................. 32 2.4.5 Die Sitzungsschicht................................................................................ 32 2.4.6 Die Darstellungsschicht ......................................................................... 32 2.4.7 Die Anwendungsschicht ........................................................................ 33 I INHALTSVERZEICHNIS 3 Kanalcodierung .........................................................................................................34 3.1 Faltungscodierung ............................................................................................ 35 3.1.1 Zustandsdiagramm ................................................................................. 36 3.1.2 Codebaum .............................................................................................. 37 3.1.3 Trellisdiagramm ..................................................................................... 38 3.1.4 Polynominale Darstellung...................................................................... 39 3.1.5 Katastrophale Faltungscodierer ............................................................. 40 3.1.6 Endliche Faltungscodes ......................................................................... 42 3.1.7 Punktierte Faltungscodes ....................................................................... 43 3.2 Viterbi-Algorithmus ......................................................................................... 46 3.3 Checksummen .................................................................................................. 49 3.3.1 CRC - Cyclic Redundancy Checksums ................................................. 49 3.4 Rahmensynchronisation ................................................................................... 52 3.4.1 Implementierung .................................................................................... 54 3.5 Forward Error Correction................................................................................. 56 4 Powerline-Communication-Chipsets .....................................................................58 4.1 Austria Mikro Systeme..................................................................................... 58 4.2 Intellon.............................................................................................................. 60 4.3 Echelon............................................................................................................. 62 4.4 Adaptive Networks........................................................................................... 63 4.5 Itran Communications ...................................................................................... 64 4.6 Inari .................................................................................................................. 65 4.7 Cogency............................................................................................................ 66 4.8 Überblick der Anbieter..................................................................................... 67 5 Programmierung des PHY-Layers .........................................................................68 5.1 Aufgabenstellung.............................................................................................. 68 5.2 Paketaufbau ...................................................................................................... 69 5.3 Schnittstelle PHY-/MAC-Layer ....................................................................... 70 5.4 Die serielle Schnittstelle................................................................................... 72 5.4.1 Overlapped/Nonoverlapped Modus ....................................................... 72 5.5 Multithreading .................................................................................................. 73 5.6 Synchronisation von Threads ........................................................................... 75 5.7 Eventgesteuerte Threads................................................................................... 79 5.8 Programmbeschreibung.................................................................................... 82 5.9 Test der Bitfehlerrate........................................................................................ 84 5.10 Übersicht der Funktionen ................................................................................. 86 5.10.1 CRC8( ) .................................................................................................. 86 5.10.2 CRC16( ) ................................................................................................ 87 5.10.3 FrameSync( ).......................................................................................... 88 5.10.4 Encode( ) ................................................................................................ 89 5.10.5 Puncture( ).............................................................................................. 90 5.10.6 Decode( )................................................................................................ 91 5.10.7 GenerateTrellis( ) ................................................................................... 92 5.10.8 Distance( ) .............................................................................................. 93 II INHALTSVERZEICHNIS 5.10.9 Compare( ) ............................................................................................. 94 5.10.10. AddErrors( ) ........................................................................................ 95 5.10.11. OpenComPort( ) .................................................................................. 96 5.10.12. PHY_Init( ).......................................................................................... 97 5.10.13. PHY_Receive( ) .................................................................................. 99 5.10.14. PHY_Send( ) ..................................................................................... 101 5.10.15. PHY_IsCarrier( ) ............................................................................... 103 5.10.16. PHY_TestReceive( ) ......................................................................... 104 5.10.17. PHY_TestSend( ) .............................................................................. 105 5.10.18. MAC_CarrierStateChange( )............................................................. 106 5.10.19. MAC_Receive( ) ............................................................................... 107 6 Ausblick ..................................................................................................................108 6.1 Mögliche Realisierung eines Powerline-Modems.......................................... 108 7 Quellcode für den Physical-Layer ........................................................................111 8 Literaturverzeichnis ..............................................................................................128 9 Glossar ....................................................................................................................131 III 1 EINLEITUNG 1 Einleitung Die vorliegende Diplomarbeit entstand im Rahmen eines fächerübergreifenden Projekts des Fachbereichs Elektrotechnik und Informationstechnik (EIT) und des Fachbereichs der Angewandten Informatik im Sommersemester 2002. Studierenden dieser beiden Fachbereiche wurde die Möglichkeit damit geboten, sich an einem gemeinsamen Projekt mit Studien- und Diplomarbeiten zu beteiligen. 1.1 Fächerübergreifendes Projekt "Chatroom over Powerline" Thema dieses Projekts war die Entwicklung eines Chatrooms, welches das hausinterne Energieversorgungsnetz als Kommunikationsmedium nutzte. Unter Anleitung wurden wichtige Komponenten eines solchen Kommunikationssystems nach modernen Engineering-Methoden von den Teilnehmern gemeinsam entwickelt. Zur Realisierung der Anwendung wurde die Aufgabenstellung in vier Teilbereiche gegliedert, die von kleinen Studentengruppen bearbeitet wurden. Die Gruppeneinteilung geschah in Anlehnung an das OSI-Schichtenmodell, welches auf der obersten Ebene die Anwendung, in unserem Fall den Chatroom, und auf der untersten Ebene die Bitübertragung mittels Powerline-Modem vorsieht. Jede Gruppe bekam einen fachkompetenten Betreuer sowie einen Moderator zugewiesen. Die Aufteilung der Gruppen sah wie folgt aus: • Anwendung • Kommunikations-Middleware • MAC-Schicht • Bitübertragungsschicht In 14-tägigen Sitzungen präsentierten die Moderatoren in Kurzvorträgen die Fortschritte ihrer Arbeit. Die anschließenden Gruppendiskussionen boten die Möglichkeit, noch offene Fragen zu erörtern sowie über technische Problemstellungen zu diskutieren. Neben diesen Treffen fanden weitere Gespräche mit den Betreuern und den Gruppen statt, um die Anforderungen der gemeinsamen Schnittstellen untereinander zu besprechen. Ziele des Projekts waren die Förderung der Teamfähigkeit, Analyse von Problemen, Erarbeitung von Zielsetzungen, Präsentation der Ergebnisse sowie die praktische Erfahrung für die 1 1 EINLEITUNG Vorgehensweise in größeren Projekten. Es bot zugleich eine sinnvolle Vorbereitung im Hinblick auf das spätere Berufsleben in der Industrie. 1.2 Gliederung Die vorliegende Diplomarbeit behandelt eine Vielzahl an Themengebieten. Daher wird an dieser Stelle ein kurzer Überblick der Kapitel gegeben. Das erste Kapitel enthält eine kurze Einführung in das Powerline-Projekt. Das 2. Kapitel erklärt die Grundlagen der PowerlineCommunication und geht dabei auf den Powerline-Kanal, OFDM-Modulation und die gesetzlichen Rahmenbedingungen ein. Ferne beinhaltet es eine kurze Einführung in das OSI-Referenzmodel, da die Gliederung des Projektes nach diesem Vorbild geschah. Kapitel 3 beschreibt die Kanalcodierung, insbesondere die Faltungscodierung, den Viterbi-Algorithmus, die Punktierung, Checksummen und die Rahmensynchronisation. Im 4. Kapitel werden auf dem Markt erhältliche Powerline-Modems verschiedener Firmen vorgestellt. Die Implementierung des Physical-Layers zeigt Kapitel 6 auf. Dort finden sich Programmiertechniken zur Kommunikation mit der seriellen Schnittstelle, Paketaufbau und ausführliche Beschreibungen zu jeder Funktion des Physical-Layers. Kapitel 6 beinhaltet einen Ausblick, wie eine Weiterentwicklung in der Powerline-Communication aussehen kann. In Kapitel 7 findet man den Quellcode für den Physical-Layers. Das Literaturverzeichnis befindet sich in Kapitel 8 und ein Glossar in Kapitel 9. 1.3 Was ist Powerline-Communication? Powerline-Communication, häufig auch lediglich Powerline oder PLC genannt, ist nichts anderes, als die Übertragung von Daten über das existierende Stromnetz. Es stellt somit eine Alternative zum herkömmlichen Rechner-Netzwerk dar. PLC beinhaltet eine Reihe von Vorteilen: • Übertragungsrate von 2,4 kbit/s bis zu über 10 Mbit/s • ständige Verfügbarkeit • Nutzung der in jedem Haushalt vorhandenen Stromkabel als Netzwerk – keine Verlegung neuer Kabel • Zugang zum jeweiligen Haushalt über den Stromanschluss im Keller – letzte Meile, somit Konkurrenz zur Telekom im Ortsnetzbereich • Vernetzung von Outhouse und Inhouse-Systemen für die Home Automation • Möglichkeit zur (Fern-) Steuerung der elektrischen Einrichtungen eines Haushalts/ Unternehmens (z.B. Audiogeräte, Kühlschrank, Zählerfernablesung oder Alarmanlage). 2 1 EINLEITUNG 1.3.1 Die Marktsegmente Die Powerline Communication lässt sich hauptsächlich in folgende Bereiche gliedern: • Home Area Networks mit vielen neuen Möglichkeiten für die Vernetzung unterschiedlichster Geräte in Privathaushalten • Energiedienstleistungen: Zählerfernablesen, Energie- und Lastmanagement • Automatisierung im Facility Management als Infranet • Nutzung der PLC Technik als alternative Anschlusstechnologie für die Last Mile in einem deregulierten Telekommunikationsmarkt 1.3.2 Eigenschaften der PLC Durch die Übertragung der Signale bis in den MHz-Bereich ergibt sich eines der mit der Einführung verbundenen Probleme. Denn im Gegensatz zu Telefonleitungen sind Stromkabel gegen die Belastung der Umgebung durch Schwingungen hoher Frequenz nicht abgeschirmt. Statt dessen wirkt das Kabel wie eine Sendeantenne und bildet Störfelder. Die Folge sind mögliche negative Einflüsse auf Funknetze, worunter auch der Radioempfang leiden kann. Störungen durch PLC Aus diesem Grund unterliegt die Einführung von PLC-Angeboten den Auflagen des Telekommunikationsgesetzes und des Gesetzes über die elektromagnetische Verträglichkeit von Geräten. Die notwendige Genehmigung wird von der Regulierungsbehörde für Telekommunikation und Post (RegTP) erteilt. Sie liegt momentan noch nicht vor. Das Verfahren ist in der Phase, in der Personenkreise, die von den negativen externen Effekten der PLC betroffen sind, ihre Bedenken vorbringen können (z.B. Amateur-Funker). Die Testinstallationen laufen deshalb z.B. auf Basis von Sondergenehmigungen der Regulierungsbehörde [25]. Knappes Frequenzangebot Ein Teilaspekt ist beispielsweise, dass die betroffenen Frequenzbänder im wesentlichen bereits belegt sind. Sie werden u.a. auch von Polizei und Rettungsdiensten genutzt. Würde eine Reservierung von Funkfrequenzen durch PLC genehmigt werden, würde eine netzgebundene 3 1 EINLEITUNG Übertragungsart auch andere Übertragungsressourcen blockieren, was angesichts der z.T. bereits knappen Frequenzbänder nur bedingt zu vertreten wäre. Übertragungskapazität Ein weiterer Nachteil der Technologie ist, dass sich die maximale Übertragungskapazität auf den Empfang bzw. die Signalabnahme an der Trafostation bezieht. Die zur Verfügung stehende Leistung verteilt sich auf die Haushalte, die an eine Station angeschlossen sind. Je nachdem wie stark das Übertragungsmedium zum jeweiligen Zeitpunkt genutzt wird, kann die Übertragungsrate im Extremfall bzw. bei einigen Hundert angeschlossenen Haushalten noch unter ISDN-Niveau sinken. Diese Unsicherheit schwächt die Attraktivität. Im Praxiseinsatz muss die Zuverlässigkeit von PLC auch im Hinblick auf die im Stromnetz vorkommenden Schwankungen der Datenübertragungseigenschaften gewährleistet sein. Diese Schwankungen können bereits beim Einschalten von einzelnen elektrischen Geräten entstehen. 4 2 GRUNDLAGEN DER PLC 2 Grundlagen der PLC 2.1 Kommunikationskanal/Modell In diesem Unterkapitel wird die Stromversorgungsleitung als Kommunikationskanal untersucht. Ein Kanal ist definiert als eine physikalische Verbindung zwischen Sender und Empfänger. Zu beachten ist diesem Zusammenhang, dass das Niederspannungsnetz aus mehreren Kanälen mit jeweils eigener Charakteristik und Qualität besteht. Bild 2.1 zeigt ein digitales Kommunikationssystem, welches die Stromversorgungsleitung als Kommunikationskanal benutzt. Der Sender befindet sich auf der linken und der Empfänger auf der rechten Seite. Wichtige Parameter dieses Komunikationssystems sind die Ausgangsimpedanz Zt des Senders und die Eingangsimpedanz Zl des Empfängers. Zt Zt Sender Bild 2.1: Koppelnetzwerk PowerlineKanal Koppelnetzwerk Empfänger Digitaler Kommunikations-Kanal für das Niederspannungsnetz Ein Koppelnetzwerk wird verwendet, um das Kommunikationssystem mit dem Niederspannungsnetz zu verbinden. Das Koppelnetzwerk hat zwei Aufgaben. Es schützt einerseits das Kommunikationssystem vor 240V-Netzspannung, welches für die Energieversorgung benutzt wird, und andererseits stellt es sicher, dass der größte Teil des empfangenen/gesendeten Signals innerhalb des Frequenzbandes für die Kommunikation liegt. 2.1.1 Koppelnetzwerk Das Koppelnetzwerk hat die Aufgabe die informationstragenden Signale auf die 50 Hz Wechselspannung des Stromnetzes aufzuprägen bzw. von ihr abzutrennen [14]. Seine Aufgabe ist es, im Sendefall eine größtmögliche Signalamplitude einzuspeisen unter der Berücksichtigung der zulässigen Grenzwerte. In Empfangsrichtung trennt das Koppelnetzwerk das Infor- 5 2 GRUNDLAGEN DER PLC mationssignal von der Netzspannung und unerwünschten Störungen ab. Die bislang in Europa freigegebenen Frequenzen der Informationssignale liegen im Bereich von etwa 95 bis 150 kHz. Zur Signalkopplung wird eine galvanische Trennung mit einem Übertrager benutzt. Der Übertrager besitzt Hochpasscharakter, so dass er die Netzspannung mit den niederfrequenten Störungen unterdrückt. Im Inhouse-Bereich wird das Signal parallel zwischen Nulleiter und einer Phase eingespeist. Im Bereich zwischen Trafostation und Hausanschluss dagegen erfolgt die Kopplung zwischen zwei Phasen. Es hat sich als vorteilhaft erwiesen, für Sende- und Empfangsseite jeweils getrennte Kopplungsnetzwerke zu verwenden. Für die Sendeseite wird eine starke Kopplung verwendet, um das Sendesignal möglichst ungeschwächt ins Netz einspeisen zu können. Auf der Empfangsseite hingegen hat sich eine schwache Kopplung bewährt, damit die netzseitige Vormagnetisierung gering wird sowie Störungen unterdrückt werden. Grundsätzlich lässt sich die Signalkopplung auf der Sendeseite durch Abbildung 2.2. beschreiben: Sendeendstufe Ue Transientenschutz vom D/A Wandler u. Tiefpass Bild 2.2: Übertrager mit Hochpass Stromnetz Sendeseitige Signalkopplung Auf der Empfangsseite empfiehlt sich eine Anordnung nach Abbildung 2.3. Ue Übertrager mit Hochpass Stromnetz Bild 2.3: EingangsBandpass Ua zum A/D-Wandler Empfangsseitige Signalkopplung Ähnlich wie bei der sendeseitigen Signalkopplung wird auch empfangsseitig ein Übertrager mit Hochpasscharakter benötigt, um die 50 Hz-Wechselspannung abzukoppeln. Der Hochpass filtert alle Frequenzen bis zu etwa 20 kHz heraus, da bis zu dieser Frequenz Störungen aus dem Netzbetrieb herrühren können. 6 2 GRUNDLAGEN DER PLC 2.1.2 Kanalmodell des PLC-Kanals Die Beeinträchtigungen des PLC-Kanals, welche die Performanz des Kommunikationssystems reduzieren, teilen sich hauptsächlich auf folgende Ursachen auf: • Impedanz-Fehlanpassung am Sender • Kanaldämpfung • Störungen durch Rauschen • Impedanz-Fehlanpassung am Empfänger • Zeitvariante Beeinträchtigungen Bild 2.4 zeigt ein Modell des Powerline-Kanals für obige Beeinträchtigungen. Alle Effekte mit Ausnahme des Rauschens werden durch zeitvariante lineare Filter, welche durch den Frequenzgang charakterisiert sind, dargestellt [12]. Die zufälligen Störungen werden durch additives Rauschen berücksichtigt. Bild 2.4: Beeinträchtigungen im Powerline-Kommunikationskanal Alle diese Beeinträchtigungen können zu einem einzigen Filter-Modell, bestehend aus einem zeitvarianten Filter und additivem Rauschen, zusammengefasst werden, wie es Bild 2.5 zeigt. Bild 2.5: Vereinfachtes Powerline-Kommunikations-Modell Trotz seiner einfachen Form umfasst dieses Modell eine ganze Reihe an Eigenschaften, welche für den Entwurf des Kommunikationssystems und der zugehörigen Performanz grundlegend 7 2 GRUNDLAGEN DER PLC sind. Die Übertragungsfunktion des Systems kann entweder durch Messungen geschätzt oder durch theoretische Analysen abgeleitet werden. 2.1.3 Dämpfung eines PLC-Kanals Der Widerstand in einer Leitung wächst bei Wechselstrom mit der Quadratwurzel der Frequenz wegen des Skineffektes. Des Weiteren sind dielektrische Verluste in den Isoliermaterialien zu berücksichtigen, welche zu einer frequenzproportionalen Erhöhung der Ableitverluste führen. 2.1.4 Zeitvariantes Verhalten des Netzes Ein Problem des Powerline-Kanals ist die Zeitvarianz der Beeinträchtigungen. Die Rauschleistung und die Dämpfung hängen teilweise von dem Verbund der angeschlossenen Lasten ab, die zeitlich variieren. Ein zeitvarianter Kanal erschwert den Entwurf eines Kommunikationssystems. In manchen Zeiträumen wird die Kommunikation gut verlaufen, in anderen Zeiträumen allerdings wird eine starke Rauschquelle den Kanal beeinträchtigen und den Kommunikationskanal eventuell blockieren. Um dieses Problem zu lösen, verwendet man Kommunikationssysteme, die sich dem Kanal anpassen [12]. Die Charakteristiken des Kanals werden fortlaufend geschätzt, z. B. durch Messungen. Die Ergebnisse werden dazu verwendet, bessere Entscheidungen im Empfangsprozess zu treffen. Durch das zeitvariante Verhalten wird die Komplexität des Systems erhöht. 2.1.5 Störungen in der Stromleitung Die Stromleitung als Kommunikationskanal ist gekennzeichnet durch eine nach Zeit und Frequenz variierende Impedanz. Darüber hinaus gibt es einen wechselnden Pegel von InterferenzSignalen, Impuls-Störungen und durch Schalten hervorgerufene Störungen. Geräte, die am meisten zum Störungspegel beitragen, sind u.a. Netzschalter, Bildschirme, induktive Heizgeräte, Dimmer, Radiostationen und Frequenzwandler. Um Auswirkungen dieser Störungen vorzubeugen, wurden bereits erhebliche Entwicklungsanstrengungen im Bereich Kanalcodierung, Forward error correction (siehe Kapitel 3.5), dynamische Adaptivität und minimale SNR-Anforderungen für verlässliche Signalerkennung unter den speziellen Störungsbedingungen im Stromnetz unternommen. Des Weiteren wurden kostengünstige Zusatzgeräte entwickelt, um den Effekt bei kritischen Störquellen wie zum Beispiel Geräten mit Schaltnetzteilen zu eliminieren. 8 2 GRUNDLAGEN DER PLC 2.2 Übertragungsverfahren OFDM Powerline-Modems übertragen die Daten anders als zum Beispiel Netzwerkkarten oder Telefon-Modems nicht im Basisband. Die Daten werden im Powerline-Kanal in höheren, von der CENELEC (Commité Européen de Normalisation Electrotechnique) freigegebenen Frequenzbändern übertragen, sodass ein neues Modulationsverfahren erforderlich wird, um den Datenstrom aus dem Basisband in die dafür vorgesehenen Frequenzbänder zu verschieben (siehe Abschnitt 2.3). Der Nachteil bei der FSK-Modulation in den CENELEC-Bändern liegt in der niedrigen Datenübertragungsrate. Neue Entwicklungen für die Übertragung via Powerline verwenden die OFDM-Modulation , welche sich bei höheren Übertragungsraten etabliert hat [24], [13]. Einige Anbieter derartiger Powerline-Modems finden sich in Kapitel 4. Die Abkürzung OFDM steht für “Orthogonal Frequency Division Multiplexing”. Anstatt einem einzelnen, breiten Träger, kommen bei diesem Modulationsverfahren viele schmale Träger zum Einsatz. Das Modem teilt zu diesem Zweck den zu sendenden seriellen Datenstrom (beispielsweise 1 x 200 kbit/s) in mehrere parallele Datenströme auf (etwa 4 x 50 kbit/s). Das Besondere der OFDM-Modulation ist, dass es die Nutzinformation auf viele Kanäle so verteilt, dass deren Nominal-Frequenzen in spektralen Nullstellen ihrer Nachbarkanäle liegen. Dadurch kann das Frequenzspektrum besser ausgenutzt werden, und es lässt eine aufwendige Kanalentzerrung, die bei Modulationsverfahren mit nur einem Träger notwendig wäre, entfallen. Theoretisch ließe sich dieses Multiplexing durch Ansteuerung einer Vielzahl von Signalgeneratoren mit den parallelen Datenströme realisieren, wobei jeder einzelne Signalgenerator exakt auf eine Frequenz abgestimmt sein müsste. Da diese Realisierung einen zu hohen Aufwand bedeutet, bedient man sich in der Praxis der Inversen-Fourier-Transformation. Durch die IFFT (Inverse Fast-Fourier-Transformation) transformiert man das Modulationssignal für jeden einzelnen Träger in den Zeitbereich. Die Realisierung der IFFT geschieht beispielsweise mit dem Cooley-Tukey-Algorithmus. Ein Nachteil dieses Verfahrens ist jedoch der steigende Rechenaufwand mit der Anzahl der Träger. Da bei der IFFT-Modulation Seitenbänder entstehen, die nach der Fourier Transformation im Abstand der Übertragungsrate zu Null werden, wählt man diesen Frequenzabstand für die Trägersignale. Der Abstand der Trägerfrequenzen entspricht bei OFDM der Übertragungsgeschwindigkeit des modulierten Signals. Soll also beispielsweise ein 1-Mbit/sSignal mittels OFDM über zehn Trägerfrequenzen, die jeweils mit 100 kbit/s moduliert werden, übertragen werden, dann ist der optimale Abstand der Trägerfrequenzen 100 kHz. Die Vielzahl der Träger im OFDM-Verfahren gewährleistet bei den für den Powerline-Kanal typischen schmalbandigen Störungen und Dämpfungsmaxima, dass ein Großteil der Träger 9 2 GRUNDLAGEN DER PLC unbeeinträchtigt bleibt. Zusammen mit einer Forward Error Correction (FEC, siehe auch Kapitel 3) bieten OFDM-Modems eine sichere Übertragungsart, da der Empfänger aus den gestörten Eingangsdaten die fehlerhaften Bits rekonstruieren kann. Diese Kombination aus FEC und OFDM wird auch COFDM (Coded Orthogonal Frequency Division Multiplexing) genannt. Weitere Vorteile dieses Verfahrens sind die gezielte Ausblendung von Trägern, die in gestörten Frequenzbereichen liegen und die Möglichkeit die einzelnen Subträger je nach ihrer Übertragungsqualität unterschiedlich zu modulieren. In Verbindung mit einem Schutzintervall ist das OFDM-Verfahren unempfindlich gegen Echokanäle und eignet sich daher auch besonders bei stark beeinträchtigter terrestrischer Funkübertragung wie beim Digitalen Radio DAB. Neben den genannten Vorteilen existieren jedoch auch einige Nachteile der OFDM-Technik. Der Verstärker des Senders benötigt über einen weiten Dynamikbereich eine möglichst lineare Auslegung. Zwischen Sender und Empfänger wird eine sehr präzise Synchronisation benötigt, weil die einzelnen Träger aufgrund ihrer Vielzahl sehr schmalbandig ausgelegt sind. 2.2.1 Multiplexing Die zu übertragenden digitalen Datenströme D(t) werden beim OFDM-Verfahren durch Aufteilung (Multiplexing) in n parallel laufende Datenströme Di(t) zerlegt, mit i = 1 ... n. Die Taktfrequenzen der Datenströme Di(t) werden um den Faktor n gegenüber dem zu übertragenden Datenstrome D(t) verkleinert. Bild 2.6 gibt den Fall für n = 4 wieder. D1(t) t D2(t) D(t) t Multiplexing D3(t) t D4(t) t Bild 2.6: Aufteilung (Multiplexing) des zu übertragenden Datenstromes bei OFDM in n = 4 Datenströme mit niedrigerer Datenrate 10 2 GRUNDLAGEN DER PLC Beim Multiplexing werden also n Bits zur gleichen Zeit übertragen. Die Datenrate der einzelnen Teilströme sinkt hierbei um den Faktor 1/n gegenüber dem ursprünglichen Signal ab. Damit sich die vielen Teilsignale Di(t) (i = 1 ... n) gegenseitig nicht beeinflussen, werden sie auf schmalbandigen Trägern gesendet, die sich in der Mittenfrequenz derart unterscheiden, dass alle Teilsignale orthogonal zueinander stehen. Im Frequenzbereich S(f) erkennt man deutlich die orthogonale Eigenschaft der Teilsignale. Auf jeder einzelnen Frequenz fi sind die Amplituden aller Teilsignale bis auf eines jeweils Null, wodurch eine gegenseitige Störung ausgeschlossen wird. Bild 2 verdeutlicht diese grundlegende Eigenschaft der OFDM-Modulation für den Fall n = 4. Trägermittenfrequenzen S(f) f0 f1 f2 f3 f4 f5 t f D1(t) Bild 2.7: D2(t) D3(t) D4(t) Bild 2: Orthogonale Träger – bei den Mittenfrequenzen eines Trägers beträgt die Amplitude aller anderen Träger Null 11 2 GRUNDLAGEN DER PLC 2.2.2 Modulation und Demodulation D2(t) D2e(t) D3(t) y(t) Dn(t) Bild 2.8: ÜbertragungsStrecke ye(t) D3e(t) Demultiplexer D1e(t) Demodulator D1(t) Modulator D(t) Multiplexer Im Allgemeinen kann man ein digitales OFDM-Übertragungssystem mit Abbildung 2.8 beschreiben. De(t) Dne(t) Störungen Bild 3: Grobstruktur eines OFDM-Übertragungssystems Das ursprüngliche Datensignal wird durch einen Multiplexer in die Datenströme Di(t) (i = 1 ... n) aufgesplittet. Danach gelangen die einzelnen digitalen Datenströme Di(t) (i = 1 ... n) in den Modulator des Senders. Im Modulator werden diese parallelen digitalen Signale in ein analoges Signal mittels IFFT umgewandelt. Eine mögliche Realisierung besteht in der Ansteuerung von n schmalbandigen Signalgeneratoren, welche von jedem einzelnen Datenstrom Di(t) getrennt angesteuert wird. Das zu sendende Ausgangssignal ergibt sich somit aus der Addition dieser Einzelsignale. In der Praxis wäre der Hardwareaufwand jedoch zu hoch, so dass man einen anderen Weg geht. Heutige OFDM-Systeme verwenden hierzu die IFFT (Fast-FourierTransformation). Im Falle der in Abbildung 2.7 verwendeten Modulationsart (BPSK, Binary Phase Shift Keying) lässt sich das abgetastete Ausgangssignal y(ta) der Senders durch folgende mathematische Gleichung (2.1) darstellen. fi sind hierbei die Trägerfrequenzen. n n å å æ ö ( j2p f i t a )÷ y ( ta ) = D i ( t a ) × cos ( 2pf i t a ) = Re ç Di ( ta ) × e ç ÷ èi = 1 ø i=1 (2.1) Eine zeiteffiziente Berechnung der inversen diskreten Fourier-Transformation (IDFT) ermöglicht der Cooley-Tukey-Algorithmus, welcher blockweise n Abtastwerte des zu sendenden Signals y(t) generiert. Diese Realisierung zeichnet sich durch einen geringen Rechenaufwand aus und kann problemlos mit heutigen digitalen Signalprozessoren (DSPs) umgesetzt werden, weil sie auf den FFT-Algorithmus optimiert sind. 12 2 GRUNDLAGEN DER PLC Auf Empfängerseite wandelt der Demodulator die empfangenen analogen Signale wieder in die digitalen Datenströme Di(t) zurück und der Demultiplexer stellt aus den digitalen Teildatenströmen wieder das ursprünglich gesendete Datensignal D(t) her. Das analoge Sendesignal y(t), welches am Modulator durch inverse Fourier-Transformation entsteht, wird dementsprechend am Demodulator durch Fourier-Transformation zurückgewonnen. Man verwendet auch hierbei den Algorithmus der schnellen Fourier-Transformation (FFT). 2.2.3 Einfügen von Schutzintervallen Wie man in Abbildung 2.7 erkennen kann, ist die Einhaltung eines korrekten Frequenzabstandes der einzelnen Träger eine wichtige Bedingung für die Orthogonalität. Andernfalls lässt sich das ursprüngliche Datensignal nicht mehr eindeutig aus dem empfangenen Signal zurückgewinnen. Durch die Impulsantwort des Kanals kommt es zu einer weiteren Schwierigkeit bei der Übertragung, welche sich in der so genannten Intersymbolinterferenz (ISI) bemerkbar macht. Ein realer Übertragungskanal besitzt ein für ihn charakteristisches dynamisches Verhalten, welches durch die Impulsantwort beschrieben wird. Sendet man am Eingang des Übertragungskanals einen Impuls, vergeht am Ausgang eine gewisse Zeit bis am Ausgang alle Reaktionen auf die Anregung abgeklungen sind. Die Dauer T der Impulsantwort wird gemessen und wird später für die Dauer des Schutzintervalls benötigt. Das durch eine Rechteckfunktion hervorgerufene Ausgangssignal kann Abbildung 2.9 entnommen werden. Sendesignal Empfangssignal Übertragungsstrecke t Bild 2.9: t Antwort auf ein Rechtecksignal In Abbildung 2.10 kommt es durch zwei in dichter Abfolge gesendeter Rechteckfunktionen zu einer Überlappung der empfangenen Signale, weil der zeitliche Abstand T der Impulsantwort zwischen den Rechteckfunktionen unterschritten wurde. Diese Verzerrung am Empfänger kann Datenverlust verursachen. Sendesignal Empfangssignal Übertragungsstrecke t t Bild 2.10: Überlappungen im Empfangssignal 13 2 GRUNDLAGEN DER PLC Abbildung 2.11 zeigt eine Möglichkeit diese Verzerrung zu vermeiden, indem der zeitliche Abstand der gesendeten Rechteckfunktionen größer als die Länge T der Impulsantwort gewählt wurde. Sendesignal Empfangssignal Übertragungsstrecke t Schutzintervall t Schutzintervall Bild 2.11: Schutzintervalle vermeiden Intersymbol-Interferenzen Ein Bit wird vor der unerwünschten Intersymbol-Interferenz geschützt, wenn zwischen zwei gesendeten Bits ein so genanntes Schutzintervall eingefügt wurde. Das Schutzintervall sollte größer als die Dauer T der Impulsantwort des Kanals sein. Ein Nachteil dieses Schutzintervalls ist jedoch die daraus resultierende niedrigere Datenrate bei der Übertragung. Die effektive Datenrate kann durch ein im Verhältnis zur Zeitdauer eines Datenbits sehr langes Schutzintervall stark verringert werden. Das Schutzintervall wird bei OFDM durch periodische Fortsetzung des OFDM-Blocks erreicht. Der Multiplexer aus Abbildung 2.6 generiert aus dem mit der Frequenz f getaktetem Datenstrom D(t) mehrere Datenströme Di(t) der Taktrate f/4. Fügt man ein Schutzintervall der Zeitdauer 1/f vor dem Multiplexer ein, halbiert sich die Datenrate von D(t). Das Einfügen des gleichen Schutzintervalls nach dem Multiplexer jedoch verringert die Datenrate nur um f/5. Da sich dieser Effekt der Datenratenreduktion um so mehr verringert, je größer die Anzahl der Träger ist, kann man die zeitliche Dauer der Schutzintervalle vergrößern ohne merkenswerte Einbuße der Datenrate. Wenn man die Trägeranzahl n erhöht, verkleinert sich im Gegenzug die Datenrate der Teildatenströme Di(t) und die Symboldauer vergrößert sich. Damit lassen sich in der OFDM-Modulation beispielsweise lang andauernde Echos unterdrücken ohne den zusätzlichen Aufwand eines Echoentzerrers. Durch die erhöhte Trägeranzahl steigt aber der Rechenaufwand im FFTAlgorithmus. Denn die Anzahl der notwendigen komplexen Multiplikationen beträgt n--- × ld(n) . 2 2.2.4 Impulsstörungen Übertragungsstrecken sind im Allgemeinen durch eine Vielzahl unterschiedlicher Störungen geprägt. Das OFDM-Verfahren zeichnet sich besonders widerstandsfähig gegenüber Impulsstörungen aus. Impulsstörungen sind gekennzeichnet durch Signale, die über eine kurze Zeit eine hohe Amplitude vorweisen. Dadurch stören sie im Frequenzspektrum einen sehr 14 2 GRUNDLAGEN DER PLC breiten Bereich. Es nützt daher wenig die Informationsdaten über ein breites Spektrum zu verteilen, weil gerade dann Impulsstörungen Schwierigkeiten bereiten können. Durch die Verteilung der Daten auf mehrere Träger und der damit verbundenen zeitlichen Ausdehnung der OFDM Symbole, können zeitlich kurze Impulse die Daten bei OFDM-Übertragung kaum beeinflussen. Bei Modulationsverfahren mit nur einem Träger dagegen ist eine gezielte Anpassung an die Impulsstörungen nötig, um die gleiche Robustheit zu erhalten. Zu diesem Zweck werden beispielsweise Limiter zur Amplitudenbegrenzung und Kanalcodierung verwendet. 2.2.5 Differenzielle Modulation Das OFDM-Verfahren zeichnet sich weiterhin durch eine vereinfachte Kanalentzerrung bei hohen Übertragungsraten aus. Bei der Kanalmodellierung genügt es, einen schmalen Bereich des Frequenzbandes für jeden einzelnen Träger zu betrachten. Vereinfacht lässt sich jeder dieser Unterkanäle als ein Übertragungsglied mit fester Dämpfung und konstanter Phase darstellen. Eine Kanalentzerrung für jeden einzelnen Unterkanal ist zwar nicht sehr rechenintensiv, denn sie besteht aus einer komplexwertigen Multiplikation. Sie lässt sich jedoch für das OFDM-Verfahren durch differenzielle Modulationsverfahren ganz vermeiden und unbekannte Dämpfungen oder Phasenlagen müssen nicht ermittelt werden. Denn ein genauer Dämpfungswert bzw. eine genaue Phasenlage eines solchen Unterkanals ist nur dann wichtig, wenn die absolute Amplitude bzw. Phase des gesendeten Signals bestimmt werden muss. Bei Einträger-Verfahren, welche über einen größeren Frequenzbereich gespreizt sind, ist hingegen meist eine aufwendigere Kanalentzerrung nötig, um eine sichere Datenübertragung zu gewährleisten. 2.2.6 Nachteile von OFDM Durch die längere Symboldauer der Datenströme Di(t) (i = 1 ... n) benötigen die modulierten Träger eine kleinere Bandbreite im Frequenzbereich. Diesem Vorteil stehen jedoch auch Nachteile entgegen. Um ein vorgegebenes Frequenzband vollständig auszunutzen, wird eine Vielzahl an Trägern verwendet. Je mehr Träger benutzt werden, desto mehr Punkte müssen während der Fourier-Transformation bei der Modulation sowie der Demodulation im OFDMVerfahren berechnet werden. Die Zunahme der Komplexität in der Berechnung lässt den Realisierungsaufwand steigen. Da die Bandbreite der einzelnen Träger relativ gering ist, muss der Empfänger sehr genau mit dem Sender synchronisiert werden, um bei der Demodulation die Wiedergewinnung der Daten zu gewährleisten. Bei der Realisierung eines OFDM-Systems muss daher ein Kompromiss zwischen Schmalbandigkeit und der damit verbundenen längeren Bitdauer und einer aufwändigeren Synchronisation gefunden werden. 15 2 GRUNDLAGEN DER PLC 2.2.7 Anforderungen an den Sendeverstärker Das Ausgangssignal am Sender y(t) ergibt sich aus der Überlagerung der Modulation der statistisch unabhängigen Teildatenströme Di(t) (i = 1 ... n). Die statistische Unabhängigkeit der Teildatenströme folgt aus der Annahme der statistischen Unabhängigkeit des ursprünglichen Datenstromes D(t). Daher lässt sich die Amplitudenverteilung des analogen Ausgangssignals y(t) (für große n) nach dem Zentralen Grenzwertsatz der Wahrscheinlichkeitstheorie durch eine Gaußverteilung annähern. Der Sendeverstärker, der die meiste Zeit mit relativ kleinen Signalamplituden angesteuert wird, sollte einen großen linearen Dynamikbereich aufweisen. Denn mit einer kleinen Restwahrscheinlichkeit treten zu bestimmten Zeiten sehr hohe Signalamplituden auf. In diesem Fall der Übersteuerung treten nichtlineare Effekte aufgrund der Signalbegrenzung auf und gehen einher mit Störungen der Nachbarkanäle. Da der Sendeverstärker in der Regel nur über sehr kurze Zeitbereiche übersteuert wird, kann diese Begrenzung des Sendesignals auf der Empfangsseite vernachlässigt werden. Durch die lange Symboldauer können Impulsstörungen sowie kurzeitige Übersteuerungen die Datenübertragung kaum beeinträchtigen. 2.2.8 Schmalbandige Störungen Eine weitere Art der Störung in Energienetzen sind sinusförmige schmalbandige Störungen. Sie können aufgrund ihrer Schmalbandigkeit nur einen kleinen Frequenzbereich und damit nur wenige Unterträger stören. Auf den höheren Frequenzbereichen im MHz-Bereich beobachtet man schmalbandige Störer meist auf festen Frequenzen, da sie ihre Ursache oft in Mittel- und Kurzwellensendern haben. Ein lernfähiges OFDM-System erlaubt es, in einer anfänglichen Testphase die gestörten Frequenzen ausfindig zu machen und seine Übertragung daraufhin anzupassen. Die Anpassung geschieht durch Veränderung der Punktierung in der Kanalcodierung, durch die Modulationsart pro Unterträger oder durch „ausblenden“ gestörter Übertragungskanäle, wie es in Abbildung 2.12 dargestellt wird. 16 2 GRUNDLAGEN DER PLC Störleistungsdichte ausgeblendeter Unterträger Störspektrum Unterträger Frequenz Bild 2.12: Ausblenden von Unterträger gegen schmalbandige Störungen Durch eine ständige Anpassung des Übertragungsverfahrens an den Kanal zu periodischen Zeitabständen wird eine hohe und sichere Datenübertragung erreicht. Neben den schmalbandigen Störungen treten in hausinternen Stromnetzen oft durch Dimmer verursachte periodische Störsignale sowie durch Schaltvorgänge kurzzeitige Impulse auf. Die periodischen Störungen lassen sich leicht mit Codierverfahren begrenzen. Es ist jedoch schwierig ein Verfahren zu entwickeln, welches gleichzeitig gegen gelegentliche Impulsstörungen sowie gegen periodische Störungen wirkt. OFDM bietet daher durch seine generelle Robustheit gegenüber Impulsstörern eine interessante und effektive Alternative zu aufwendigen Codiermaßnahmen. 2.2.9 Kanalkapazität Die durch die Shannon’sche Kanalkapazität begrenzte maximale Übertragungsgeschwindigkeit erreicht bei OFDM-Modulation etwa ein Drittel der Kanalkapazität C, die durch Formel (2.2) gegeben ist [31]. C = B × ld ( 1 + SNR ) (2.2) Hierbei entspricht B der Bandbreite des Übertragungskanals und SNR dem zugehörigen Signal-Rausch-Verhältnis. Die maximale Übertragungsgeschwindigkeit d ist damit abhängig von von der Bandbreite B sowie vom SNR. Sie berechnet sich demnach aus Gleichung (2.3). 1 d » --- × B × ld ( 1 + SNR ) 3 (2.3) Legt man beispielsweise eine Bandbreite von B = B B + B D = 30kHz + 8, 5kHz = 38, 5kHz , wie sie die CENELEC B- und D-Bänder (siehe Abschnitt 2.3) vorgeben, zugrunde , ergibt sich bei 17 2 GRUNDLAGEN DER PLC einem Signal-Stör-Verhältnis von ungefähr 35 dB, wie es in Haushalten anzutreffen ist, eine maximale Übertragungsgeschwindigkeit von d » 150kbit ¤ s . Verringert sich das SNR auf 20 dB, können mittels OFDM nur noch d » 85kbit ¤ s übertragen werden. In Abbildung 2.13 findet man ein charakteristisches Sende-, Empfangs- und Rauschspektrum, wie es in einer normalen Büroumgebung vorkommen kann. Hierbei wurde eine Übertragungsstrecke von etwa 50 m zugrunde gelegt. Im Rauschspektrum sind bei 11, 12 und 14 kHz schmalbandige Störungen anzutreffen, wie sie durch Computermonitore hervorgerufen werden können. Im Durchschnitt beträgt das Signal-Stör-Verhältnis zwischen Empfangs- und Rauschspektrum etwa 35 - 40 dB. Bild 2.13: Sende-, Empfangs- und Rauschspektrum bei OFDM-Modulation im In-HouseBereich [26] Gestörte Frequenzbereiche können durch das OFDM-Verfahren gezielt von der Übertragung ausgenommen werden. Die Information wird über die ungestörten Frequenzen gesendet. Das SNR braucht dabei nicht über die gesamte Kanalbandbreite konstant sein, denn das OFDMVerfahren beinhaltet die Möglichkeit, den Trägerfrequenzen dynamisch einen gewissen Informationsgehalt je nach SNR im betreffenden Frequenzbereich zuzuordnen. Dies nennt man auch QAM-Adaptivität. Obige Formeln sind dann so zu modifizieren, dass die Einzelkapazitäten für die Frequenzen fi mit den Bandbreiten Bi für das SNR(fi) nach Gleichung (2.4) addiert werden. C = å B × ld( 1 + SNR ( f ) ) i i (2.4) i 18 2 GRUNDLAGEN DER PLC 2.3 Standardisierung der Powerline-Communication Es gibt mehrere verschiedene PLC Standards für Low-Speed-PLC wie z.B. EIB, EHS, Batibus in Europa und CeBus in den USA. Für Medium- und High-Speed-PLC gibt es zurzeit keinen definierten Standard. Zu den möglichen zukünftigen Standards gehören PLCforum, HomePlug, Echonet und weitere. Die Trägerfrequenzen für die binäre Datenübertragung über die Stromleitung liegen deutlich über den für den Elektrizitätstransport standardisierten Frequenzen von 50 bzw. 60 Hz. Die von der europäischen CENELEC-Norm EN50065-1 [11] definierten Frequenzbänder sind jedoch verhältnismäßig schmal. In USA dürfen beispielsweise Trägerfrequenzen bis zu 450 kHz genutzt werden, während in Europa die Grenze bei nur 148,5 kHz liegt. Daher sind in Europa Technologien, die eine große Bandbreite benötigen, wie beispielsweise Spread-Spectrum, nur bedingt einsetzbar. Werden Powerline Produkte, die für den amerikanischen Markt entwickelt wurden, so verändert, dass sie die europäischen Normen erfüllen, ist dies meist mit einer erheblichen Reduzierung der Übertragungsgeschwindigkeit verbunden. Verfahren, die ein relativ schmales Frequenzband nutzen und ein kleines Signal-Rausch-Verhältnis zur sicheren Datenerkennung benötigen, sind hier besser geeignet. Heute übliche Standards sind: • Europa: CENELEC: EN 55022 (CISPR 22), CISPR 24, EN 50065-1 • USA: FCC: Part 15 Subpart B • Kanada: Canada Industry: ICES-006 2.3.1 Regulierungen in Europa Das Europäische Komitee für Elektrotechnische Normung in Brüssel (CENELEC) hat mit der Norm EN50065-1, [11] den Rahmen für die Powerline-Kommunikation in Europa festgelegt. Sie wurde von der Deutschen Elektrotechnischen Kommission als DIN-EN50065-1 und vom VDE als Klassifikation VDE0808 übernommen und sieht vier unterschiedliche Frequenzbänder vor: • Das A-Band (9 kHz - 95 kHz) ist für Energieversorgungsunternehmen reserviert, • das B-Band (95 kHz - 125 kHz) welches von allen Anwendungen innerhalb des Hauses ohne Zugriffsprotokoll genutzt werden kann, • das C-Band (125 kHz - 140 kHz), das für Home-Automation-Anwendungen vorgesehen ist. Ein vorgeschriebenes Zugriffsprotokoll (CSMA/CD = Carrier Sense Multiple Access/ 19 2 GRUNDLAGEN DER PLC Collision Detection) ermöglicht die Koexistenz verschiedener, inkompatibler Systeme in diesem Frequenzband; und schließlich • das D-Band (140 kHz - 148,5 kHz), das Alarm- und Sicherheitssystemen ohne Zugriffsprotokoll vorbehalten ist. Für alle vier Frequenzbänder werden von der EN50065-1 die maximalen Signalpegel zur Modulation auf das Stromversorgungsnetz definiert (Bild 2.14). Für Home-Automation-Anwendungen ist das C-Band mit einem Signalpegel von höchstens 116 dB(µV) bestens geeignet, da hier ein besonderes Medien-Zugriffsprotokoll gefordert wird. Bild 2.14: Maximale Signalpegel im Frequenzbereich von 3kHz bis 148,5kHz Zur Bestimmung des Ausgangspegels muss das Signal mit einem Spitzenwertdetektor bei einer vorgeschriebenen Messschaltung über einen Zeitraum von 1 Minute gemessen werden. Daneben legt die EN50065-1 für alle elektrischen Geräte am Stromversorgungsnetz Störleistungsgrenzwerte in den entsprechenden Frequenzbändern fest. So wird eine parasitäre Beeinflussung der Powerline-Communication aufgrund von Störungen anderer Verbraucher vermieden. 20 2 GRUNDLAGEN DER PLC 2.3.2 Medien-Zugriffsprotokoll im CENELEC-C-Band Im CENELEC-C-Band ist die Einhaltung eines Medien- Zugriffsprotokolls erforderlich (CSMA/CD). Dieses legt einen Frequenzbereich um die Bandmitte fest, auf dem der Signalpegel eine gewisse Zeit lang unterhalb von 80 dB(µV) liegen muss bevor mit dem Senden begonnen werden kann. So lassen sich „Kollisionen“ verhindern, bei denen zwei Stationen gleichzeitig senden. Außerdem ist die maximale Dauer für jeden Sendevorgang begrenzt, was einer Gleichberechtigung der Kommunikationspartner entgegenkommt. Das Medien-Zugriffsprotokoll wirkt dem Effekt entgegen, der zurzeit im 433 MHz-ISM-Band zu beobachten ist: Bekanntlich kommt es hier aufgrund einer völligen Freigabe immer wieder zur ungewollten gegenseitigen Beeinflussung verschiedener Systeme im Feld. In Hinblick auf eine verstärkte Nutzung der Powerline-Frequenzbänder, vor allem auch von hochwertigen und hochdatenratigen Anwendungen wie Telefonie oder Internet-Dienste, gewährleistet das CENELEC-C-Band sowohl eine kostengünstige als auch eine zuverlässige Kommunikation. In den anderen Frequenzbändern (B- und D-Band) ist auf Dauer eine ähnliche Situation wie beim besagten 433 MHz-ISM-Band zu erwarten, und es wird sich nur noch mit erheblichem Aufwand eine ausreichende Zuverlässigkeit erreichen lassen. Die Abbildungen 2.15 bis 2.17 zeigen die Regeln, die von der EN50065-1 bei der Nutzung des C-Bandes eingehalten werden müssen. Die gesamte Dauer des Sendevorgangs einer Station (Sender A) darf demnach nicht länger als 1 Sekunde sein (Abbildung 2.15). Während dieser Zeit dürfen keine „Übertragungslücken“ von mehr als 80 ms entstehen, da sonst andere sendewillige Stationen das Medium als frei erkennen könnten. Nach Abschluss der Übertragung muss der Sender eine Pause von mindestens 125 ms einhalten, um den anderen Stationen ebenfalls die Möglichkeit für einen Sendevorgang einzuräumen (Abbildung 2.16). Eine andere Station (Station B) darf bereits nach frühestens 85ms mit der Übertragung beginnen (Abbildung 2.17). Bild 2.15: Maximale Übertragungsdauer 21 2 GRUNDLAGEN DER PLC Bild 2.16: Zeit zwischen zwei Sendevorgängen von einem Sender Bild 2.17: Zeit zwischen den Sendevorgängen von zwei Sendern 2.3.3 Regulierungen in USA Nach den Vorschriften der FCC (Federal Communications Commission) Part 15 werden PLC Systeme für Inhouse-Anwendungen als "Carrier Current Systems" bezeichnet und arbeiten als unbeabsichtigte Strahler. Im Bereich von 535 kHz bis 1705 kHz (Mittelwellenradio) ist der leitungsgeführte Ausgangspegel auf 60 dBµV (Quasipeak-Detektor, 9 kHz Bandbreite, Netznachbildung nach CISPR 16) begrenzt. Tabelle 2.1: Grenzwerte für Strahlungsemissionen: Frequenzbereich in MHz Feldstärkengrenze in dBµV/m Messabstand in m 0.009 - 0.490 48.5 - 13.8 300 0.490 - 1.705 33.8 - 23 30 1.705 - 30 29.5 30 22 2 GRUNDLAGEN DER PLC Grenzwerte oberhalb von 30 MHz existieren, sind aber in dieser Liste nicht aufgeführt. Der Detektor ist ein Mittelwert-Detektor unterhalb von 490 kHz, Quasipeak auch von 90-110 kHz. Die Messbandbreite ist 200 Hz unterhalb von 150 kHz und 9 kHz oberhalb von 150 kHz. 2.3.4 Regulierungen außerhalb Europas und der USA Nach der internationalen Norm IEC 61000-3-8: 1997-08 dürfen PLC Systeme den Frequenzbereich von 3 kHz bis 525 kHz benutzen. Gleichtakteinspeisung ist nicht zulässig. Die Grenzwerte der Ausgangspegel sind (geplant in ITU Region 3: Asien/Pazifik) Tabelle 2.2: Ausgangspegelgrenzwerte Frequenzbereich Ausgangspegelgrenzwerte 9 -95 kHz 134 dBµV 95 - 148,5 kHz 116 dBµV (134 dBµV in Industriegebieten) 148,5 - 500 kHz 66 - 56 dBµV, linear abnehmend mit dem Logarithmus der Frequenz 500 - 525 kHz 56 dBµV Sofern ein Land kein Mitgliedstaat der EU und kein Mitglied von CENELEC ist, muss im Detail geklärt werden, welche Vorschriften anzuwenden sind. 2.3.5 Die Nutzungsbestimmung 30 Der Bundesrat verabschiedete am 30. März 2001 drei Verordnungen, die die Powerline-Nutzung rechtlich absichern. Voraussetzung: Andere Funkdienste dürfen nicht beeinträchtigt werden. Die Nutzungsbestimmung 30 (NB 30) der Regulierungsbehörde bestimmt ab 1. Juli 2001 gültige “Grenzwerte für Störfeldstärken in und längs von Leitern”, die zum einen sicherstellen sollen, dass Funkdienste nicht unangemessen gestört werden und zum anderen neue telekommunikative Dienste wie Powerline nicht von vornherein verhindert werden. NB 30 beinhaltet einen Stufenplan für Störungsfälle, der nach dem Muster Störung lokalisieren, Störung beseitigen und im Worst Case abschalten, allen Eventualitäten vorbeugen soll. Die Nutzungsbestimmung 30 enthält die folgenden Bestimmungen: (1) In und längs von Leitern können Frequenzen für Telekommunikationsanlagen (TK-Anlagen) und Telekommunikationsnetze (TK-Netze) im Frequenzbereich von 9 kHz bis 3 GHz freizügig genutzt werden, 23 2 GRUNDLAGEN DER PLC 1. wenn die Frequenznutzung in Frequenzbereichen erfolgt, in denen keine sicherheitsrelevanten Funkdienste betrieben werden, 2. und wenn am Betriebsort und entlang der Leitungsführung im Abstand von 3 Metern zur TK-Anlage bzw. zum TK-Netz oder zu den angeschalteten Leitungen die Störfeldstärke (Spitzenwert) der Frequenznutzung die Werte von Tabelle 1 nicht überschreitet; die Messung der Störfeldstärke erfolgt auf der Grundlage geltender EMV-Normen entsprechend der Messvorschrift Reg TP 322 MV 05 "Messung von Störfeldern an Anlagen und Leitungen der Telekommunikation im Frequenzbereich 9 kHz bis 3 GHz". Tabelle 2.3: Grenzwerte der Störfeldstärke von TK-Anlagen und TK-Netzen Frequenzbereich 9 kHz - 1 MHz Grenzwert der Störfeldstärke mV (Spitzenwert in 3 m Abstand dB( ------- ) m 40 – 20 × log ( f ¤ ( MHz ) ) > 1 MHz - 30 MHz 40 – 8, 8 × log ( f ¤ ( MHz ) ) > 30 MHz - 1 GHz 27 (1) > 1 GHz - 3 GHz 40 (2) (1) Dies entspricht der äquivalenten Strahlungsleistung von 20 dBpW. (2) Dies entspricht der äquivalenten Strahlungsleistung von 33dBpW. (2) Die Frequenznutzung nach Absatz (1) genießt keinen Schutz vor Störungen durch Aussendungen von Sendefunkanlagen. (3) Die einschränkenden Bedingungen nach Absatz (1) gelten für Frequenzen bis 30 MHz vom 1. Juli 2001 an und für Frequenzen über 30 MHz vom 1. Juli 2003 an. (4) Für Frequenznutzungen in und längs von Leitern, für die keine Freizügigkeit nach Absatz (1) gegeben ist, können die räumlichen, zeitlichen und sachlichen Festlegungen durch die Regulierungsbehörde für Telekommunikation und Post unter Beachtung der Verhältnismäßigkeit und nach Anhörung der Betroffenen entweder im Frequenznutzungsplan oder in der erforderlichen Frequenzzuteilung für den jeweiligen Anwendungsfall getroffen werden. Sind sicherheitsrelevante Funkdienste betroffen, ist insbesondere zu berücksichtigen, inwieweit eine konkrete Gefährdung der Sicherheit zu befürchten ist. 24 2 GRUNDLAGEN DER PLC 2.3.6 HomePlug Power Alliance Die HomePlug Power Alliance wurde zur Entwicklung eines offenen Standards für Powerline-Systeme gegründet. Die dreizehn ursprünglichen Allianzmitglieder bekamen Zuwachs von vielen Firmen, typischerweise Chip- und Gerätehersteller. In Jahr 2000 einigte sich die Gruppe auf die Spezifikation 1.0 basierend auf Intellon’s PowerPacketTechnologie (siehe Abschnitt 2.3.7). 2.3.7 PowerPacket PowerPacket ist eine Technologie zur Datenübertragung via Powerline der Firma Intellon [23]. Sie ist die Grundlage der Spezifikation 1.0 der HomePlug Power Alliance und stellt einen Standardisierungsvorschlag für den Physical- und MAC-Layer der Powerline-Kommunikation bereit. Im Physical-Layer wird das Multi-Trägerverfahren OFDM als Basistechnologie verwendet, um eine Anpassung der Sendesignale an die widrigen Übertragungsbedingungen im Stromnetz zu erhalten. Die beanspruchte Bandbreite reicht von 4.5 bis 21 MHz. Die OFDMModulation wird ausführlich in Kapitel 2.2 beschrieben. Die Kombination aus Forward Error Correction (FEC), Viterbi-Decodierung, Interleaving und Fehlerdetektion ermöglichen eine hohe Fehlersicherheit und passen sich den wechselnden Kanalbedingungen an. Diese Verfahren werden unterstützt durch ein Automatic Repeat Request (ARQ) Protokoll, um zuverlässige Datenübertragung zu gewährleisten. Die Headerdaten der Pakete werden durch Turbo Product Coding (TPC) geschützt [27]. Das MAC-Protokoll der PowerPacket-Technologie ist eine Variante des Carrier Sense Multiple Access with Collision Avoidance (CDMA/CA) Protokolls, ähnlich dem 802.11-Standard. Dieses Protokoll benutzt eine klassische listen-before-talk-Strategie und sendet nach einer zufällig ausgewählten Zeitperiode um Kollisionen zu vermeiden. Mehrere Besonderheiten wurden zusätzlich implementiert, wie beispielsweise die Unterstützung von QoS. Pakete der PowerPacket-Technologie bestehen aus einem start-of-frame delimiter, der Payload und einem end-of-frame delimiter. Der Paketaufbau ist in Abbildung 2.18 dargestellt. Delimiter beinhalten eine Präambel-Sequenz gefolgt von einem TPC codiertem frame-control Feld. Die Präambel ist eine festgelegte Bitsequenz, die von den Empfängern zuverlässig erkannt werden kann. Unicast-Aussendungen werden bestätigt durch Aussendung eines response-delimiters. 25 2 GRUNDLAGEN DER PLC Delimiter 25 Bits Frame Header 5 Bytes 6 Bytes 6 Bytes variable Länge Preamble Frame control Segment control DA SA Frame Body 4 Symbole Check Sequence Frame Body 2 Bytes Delimiter 25 Bits B-PAD FCS EFG Preamble Frame control variable Symbolanzahl: 20 - 170 Symbole 4 Symbole Payload Bild 2.18: PowerPacket Frameformat Der Payloadanteil eines Frames hängt von der Übertragungsrate und der Güte des Kanals zwischen Sender und Empfänger ab. Die Kanalanpassung geschieht auf drei verschiedenen Wegen: Nichtbenutzung von gestörten Teilkanälen im OFDM-System, Wechsel der Modulation zwischen DQPSK und DBPSK und Änderung der FEC-Rate zwischen 3/4 und 1/2. Diese Parameter auszuhandeln sind eine Besonderheit von PowerPacket, um hohe Datenraten via Powerline zu erzielen. Die niedrigste Datenrate und zugleich die sicherste ist der so genannte ROBO-Mode. In diesem robusten Modus werden alle Träger mit DBPSK moduliert, die stärkste Codierung mit Interleaving verwendet sowie Bitwiederholung eingesetzt. Der ROBOMode benutzt keine Trägerausblendung und kann daher generell von jedem Empfänger verstanden werden. Benutzt wird dieser Modus in der Startphase der Kommunikation zwischen Geräten, welche noch keine Kanalanpassung ausgeführt haben, für Mulicast-Aussendungen und in Unicast-Aussendungen, wenn der Kanal extrem gestört wird. PowerPacket MAC-Layer PowerPacket benutzt das Physical-Carrier-Sense- und Virtual-Carrier-Sense-Verfahren, um festzustellen, ob eine andere Station gerade sendet. Im Physical-Carrier-Sense-Verfahren werden gesendete OFDM-Symbole einer anderen Station detektiert. Im Gegensatz dazu ist das Virtual-Carrier-Sense-Verfahren eine zeitbasierte Nachführung der Träger. Im Frame-ControlFeld eines jeden Delimiters (siehe Abbildung 2.18) werden Informationen über Dauer einer Aussendung eines Senders mitversendet. Daraus kann der Empfänger schließen, wie lange ein Kanal belegt sein wird, auch für den Fall, dass der Empfänger anschließend die Kanalnachführung verliert (Physical-Carrier-Sense). Durch diese Technik wird die Performanz eines Netzwerks wesentlich verbessert, was gerade Powerline-Netzwerken zu gute kommt, in welchen die Stationen sehr unterschiedliche Signalstärken empfangen können. 26 2 GRUNDLAGEN DER PLC Paket-Kollisionen können vom Powerline-Modem nicht direkt während der Aussendung erkannt werden, da der Sender sich selbst mit einer wesentlich höheren Stärke hört als die Aussendungen entfernterer Stationen. Daher werden Kollisionen aus dem Fehlen von erwarteten Empfangsbestätigungen gefolgert. Alle Unicast-Aussendungen werden durch einen ResponseDelimiter bestätigt. Die PowerPacket-Technologie erlaubt dem Empfänger aber auch negative Bestätigungen (NACK oder FAIL) zu senden, je nachdem, ob ein Paket mit Fehlern empfangen wurde oder nicht verarbeitet werden konnte. Neu hinzukommende Stationen erhalten Zugriff auf den Kanal durch ein Wettbewerbs-Zeitfenster mit exponentiellem Backoff, ähnlich wie bei Ethernet. Dem Wettbewerbsfenster geht ein Priority-Resolution-Zeitintervall voraus, welches mehreren Stationen die Möglichkeit gibt, entsprechend ihren Sende-Prioritäten den Kanal zu beanspruchen. Nachdem eine Station ihre Aussendung vollzogen hat, signalisieren andere in der Warteschlange stehende Stationen ihre Prioritäten während dieses Priority-Resolution-Zeitintervalls. Die Absicht, im nächsten Zeitfenster zu senden, wird durch eine binäre Codierung der Priorität signalisiert. Jede Station wählt zufällig einen Zeitschlitz unter Berücksichtigung ihrer Priorität im Wettbewerbsfenster aus, zählt die Zeitschlitze herunter bis der gewählte Zeitschlitz an der Reihe ist und beginnt ihre Aussendung. Das Wettbewerbsfenster wächst mit zunehmender Anzahl erfolgloser Versuche Zugang zum Kanal zu erhalten. Wenn eine Station eine Aussendung einer anderen Station erkennt, bevor ihr eigener Zeitschlitz an der Reihe ist, wird der Zähler angehalten und das Modem schaltet in den Empfangsmodus. Sobald die Aussendung der anderen Station vorüber ist, setzt die Station ihre Zählung wieder fort. Da sich die Paketgröße der Datenrate und den Kanaleigenschaften anpasst, variiert die Zeit für eine Paketaussendung. Übermittlungszeiten von langen Paketen wirken der Einhaltung von Quality-of-Service entgegen, weil ein Paket mit einer höheren Priorität nicht immer rechtzeitig ausgesendet werden kann, wenn es auf die Beendigung einer langen Aussendung warten muss. PowerPacket umgeht diese Problematik durch eine Segmentierung von Paketen, die eine gewisse Länge überschreiten. Pakete mit höherer Priorität können dadurch zwischen längere Aussendungen springen. Um die Kollisionswahrscheinlichkeit von Paketen gleicher Priorität zu vermeiden, benutzt PowerPacket das Segment-Bursting-Verfahren. In diesem Verfahren werden alle Pakete gleicher Priorität direkt hintereinander gesendet bis ein Paket höherer Priorität diesen Vorgang unterbricht. Eine Erweiterung dieser Verfahren ist der wettbewerbsfreier Zugriff auf den Kanal, in welchem die Stationen eine begrenzte Anzahl von Paketen zu verschiedenen Stationen senden darf ohne dabei unterbrochen zu werden. Der wettbewerbsfreie Zugriff verbessert die QoS bei bestimmten Multimedia-Anwendungen. Kanalanpassung geschieht bei jeder erstmaligen Aussendung zu einer anderen Station sowie gelegentlich auch danach, wenn ein Timeout stattfindet oder sich die Kanalübertragungsfunktion ändert. Die Kanalanpassung hat direkten Einfluss auf die Anzahl benutzter Träger, Modu- 27 2 GRUNDLAGEN DER PLC lationsart und FEC-Codierung nachfolgender Aussendungen. Sie wird vom Empfänger bestimmt und kann sich in umgekehrter Kanalrichtung unterscheiden. PowerPacket erstellt logische Netwerkstrukturen, die auf einem Privacy-Mechanismus basieren. Dabei teilen sich alle teilnehmenden Stationen einen gemeinsamen Schlüssel. Verschlüsselung wird erreicht durch einen 56-Bit-DES Algorithmus. 28 2 GRUNDLAGEN DER PLC 2.4 Das OSI-Referenzmodell Das OSI-Sieben-Schichten-Modell [15] (Open System for Interconnection), von der Standardisierungs-Kommission ISO (International Standardisation Organisation) 1983 als Standard ISO 7498 entworfen, ist ein allen Kommunikationssystemen zugrunde liegendes Referenz-Modell. Als Referenz-Modell beschreibt es den strukturellen und funktionellen Aufbau von Telekommunikationssystemen. Ziel des OSI-Sieben-Schichten-Modell (OSI-Referenzmodell) ist es, jedes Telekommuniktionssystem in sieben Schichten zu unterteilen. Das Modell stellt somit eine offene Architektur bereit, damit Systeme unterschiedlicher Hersteller miteinander kommunizieren können [28]. Endsystem A Transitsystem Endsystem B 7 Application Application 7 6 Presentation Presentation 6 5 Session Session 5 4 Transport Transport 4 3 Network Router Network 3 2 Data Link Bridge, Switch Data Link 2 1 Physical Repeater, Hub Physical 1 Übertragungsmedium Bild 2.19: OSI-Referenzmodell mit Transitsystem und Übertragungsmedium [28] Die unteren vier Schichten 1 - 4 werden als Transportschichten bezeichnet, da sich diese nur mit der gesicherten Übertragung der Daten von einem Endsystem zu einem anderen beschäfti- 29 2 GRUNDLAGEN DER PLC gen. Ergänzt werden die Transportschichten durch die Schichten 5 - 7. Diese oberen Schichten werden als anwendungsorientierte Schichten bezeichnet, da diese nicht die Aufgabe der Datenübertragung, sondern die der Datenverarbeitung haben. Vertikale Kommunikation im Modell findet ausschließlich zwischen den Schichten statt, d.h. es kann z.B. keinen direkten Austausch von Informationen der Schicht 4 auf Gerät A und der Schicht 3 auf Gerät B erfolgen. Die Kommunikation erfolgt innerhalb des OSI Modells mittels so genannten Dienstprimitiven (Service Primitives) die den jeweiligen Schichten erlauben, Dienstanweisungen an die über oder untergeordnete Schicht weiterzugeben. Die andere Möglichkeit im OSI Modell zu kommunizieren ist die Kommunikation über Protokolle. Dabei handelt es sich nicht um die Kommunikation innerhalb eines Endgerätes, sondern die Kommunikation zweier Endgeräte auf derselben Schicht, den sog. Partnerinstanzen. Diese bauen über die darunterliegenden Schichten eine logische Verbindung auf. Die Protokolle regeln dann in welcher Weise welches Endgerät über diese Verbindung Daten senden darf. 2.4.1 Die Bitübertragungsschicht Schicht 1, Physical Layer, P Die Bitübertragungsschicht stellt ungesicherte Verbindungen für die Übertragung von Bits zur Verfügung. Deswegen hat die physikalische Schicht auch exklusiven Zugriff auf das Übertragungsmedium, d.h. sie ist allein für das Einschreiben der Informationen auf die Trägersignale zuständig (Modulation), aber auch für das Lesen der Informationen von selbigen (Demodulation). Dies geschieht beispielsweise auf einem elektrischen Kabel in geeigneter Weise, z.B. durch anheben oder Wechsel des Spannungspegels. Die Physikalische Schicht ist aber nicht nur für die Modulation und Demodulation zuständig, sondern auch für die Signalverbesserung, welche vonnöten ist, wenn durch schlechte Übertragungen die Signale verzerrt oder abgeschwächt (durch Leitungsdämpfung) werden. Es kann aber auch noch die Aufgabe der Kanalcodierung hinzukommen, beispielsweise im Mobilfunk oder im Funknetzwerk, wo oft stark gestörte Kanäle vorherrschen. 30 2 GRUNDLAGEN DER PLC 2.4.2 Die Sicherungsschicht Schicht 2, Data Link Control Layer, D Die Sicherungsschicht verbessert ungesicherte Verbindungen auf Teilstrecken zu gesicherten Verbindungen. Diese Schicht wird in der Regel in eine obere und untere Schicht eingeteilt. Die untere Schicht wird in der Regel als Medium Access Control Schicht (MAC) bezeichnet. Sie hat die alleinige Aufgabe den Zugriff der oberen Schichten auf das Übertragungsmedium zu regeln, da normalerweise ein Medium nicht exklusiv dem Endgerät zugeteilt ist (und genau aus diesem Grund kann die Schicht entfallen wenn ein Exklusiver Zugriff besteht). Aus diesem Grund ist es vonnöten, den Zugriff zu regeln, damit es nicht zu Kollisionen kommen kann. Die obere Schicht wird als Logical Link Control (LLC) bezeichnet. Mit dieser Schicht kann man schon Datenübertragungen unabhängig von Medium realisieren, da diese nur noch abstrakt für die LLC Schicht erscheint. Wenn aber Übertragungsfehler auf dem Medium auftreten, gibt die P-Schicht diese Fehler ungefiltert an die LLC Schicht weiter. Diese hat dann die Aufgabe, diese Übertragungsfehler zu entdecken und diese Fehler zu korrigieren, d.h. den übergeordneten Schichten eine möglichst fehlerfreie Übertragung zur Verfügung zu stellen. Dies geschieht auf der D-Schicht indem sie Daten im sog. Rahmen einpackt, mit Header und Trailer. Der Trailer enthält z.B. eine Prüfsumme zur Verifikation der im Rahmen enthaltenen Informationen. Weiterhin werden die Rahmen auch mit Sequenznummern versehen, und eventuelle fehlerhafte Pakete wieder anfordern zu können. 2.4.3 Die Vermittlungsschicht Schicht 3, Network Layer, N Die Vermittlungsschicht transportiert Datenpakete über Teilstrecken des Netzes von einem Endsystem zum anderen, dies ist das so genannte Routing. Für den Transport über verschiedene Knoten werden auf diesen so genannte Routingtabellen geführt. In diesen steht an welchen Netzknoten das Paket als nächstes geschickt werden soll. Nicht nur das Routing, sondern auch das Finden eines optimalen Weges durch das Netz ist Aufgabe der N-Schicht. Hier kann man auch nochmals zwischen der schnellsten Route oder der kürzesten Route unterscheiden, in der Regel wird aber in der Praxis immer nach der schnellsten Route gesucht, da man in der Telekommunikation lange Verzögerungen vermeiden will. 31 2 GRUNDLAGEN DER PLC 2.4.4 Die Transportschicht Schicht 4, Transport Layer, T Die Transportschicht nimmt Anforderungen von Anwendungsprozessen an, stellt Anforderungen an darunterliegenden Schichten und gleicht eventuell ungenügende Leistungen dieser Schichten aus. Sie hat daher eine ähnliche Ausgabe wie die D-Schicht, übernimmt die Fehlerkorrektur aber nicht von einem Netzknoten zu einem anderem, sondern stellt die gesicherte Übertragung der Daten zwischen zwei Endgeräten sicher. Auch der Aufbau und Abbau von virtuellen Kanälen zwischen 2 Endgeräten wird über die TSchicht gesteuert. Durch diese Steuerungsaufgabe hat sie die Möglichkeit, mehrere Sitzungen zwischen 2 Endgeräten auf einen virtuellen Kanal zu leiten, (upward Multiplexing) aber auch das Verteilen von Daten einer Sitzung auf mehrere virtuelle Kanäle, um beispielsweise eine höhere Bandbreite zu erreichen (downward Multiplexing). Auch die Aufgabe, dass der angebotene Dienst in der vereinbarten Güte erbracht wird (Quality of Service, QoS) gehört zu der Transportschicht. 2.4.5 Die Sitzungsschicht Schicht 5, Session Layer, S Die Sitzungsschicht regelt den Gesprächswechsel und liefert Vorkehrungen für das Wiederanlaufen der Verbindungen nach Abbruch. Sie betrachtet die gesamte Kommunikation als Einheit, der Anfang und das Ende einer Sitzung werden als Hauptsynchronisationspunkte bezeichnet. Es gibt aber nicht nur diese zwei Punkte, sondern eventuell mehr, so genannte Nebensynchronisationspunkte. Dies hat den Vorteil, dass eine Kommunikation wieder aufgenommen werden kann, wenn ein Abbruch vor dem Ende der eigentlichen Sitzung erfolgt ist. 2.4.6 Die Darstellungsschicht Schicht 6, Presentation Layer, P Die Darstellungsschicht stellt Ausdrucksmittel zur Verfügung, die es den Anwendungsinstanzen ermöglichen, Datentypen zu definieren und legt die Regeln fest, nach denen die Informationen auszutauschen sind. Dies beinhaltet in welcher Weise die übertragenen Informationen auf den jeweiligen Endgeräten dargestellt werden. Daher erhält in dieser Schicht auch die Quellcodierung der Informationen tragende Bedeutung, denn die Codierung ist nichts anderes 32 2 GRUNDLAGEN DER PLC als eine Abbildung von Informationseinheiten auf die jeweiligen Repräsentanten. Aber auch die Datenkompression sowie die Kryptographie während der Kommunikation wird von der PSchicht erledigt. 2.4.7 Die Anwendungsschicht Schicht 7, Application Layer, A Die Anwendungsschicht stellt Mittel für die Kooperation zwischen verteilten Anwendungsprozessen zur Verfügung. Im OSI Modell finden dabei vornehmlich Protokolle für Dienste, die in Computernetzen vonnöten sind, Beachtung. Die bei diesen Protokollen mitgebracht Funktionalität bezüglich des Dateizugriffs und der Verwaltung (File Transfer, Access and Management, FTAM) stehen im Vordergrund. Meistens können diese Protokolle aber noch weit mehr. Ein weiterer Dienst, der auf der A-Schicht angeboten wird, ist das so genannte virtuelle Terminal (VT), das es einem Benutzer ermöglicht, sich an entfernten Computern anzumelden und dort zu arbeiten, als säße er am lokalen Rechner. Zu den wichtigsten Diensten der A-Schicht des OSI Modells gehören Hypertext Transfer Protocol (HTTP), Simple Mail Transfer Protocol (SMTP), das File Transfer Protocol (FTP), Telnet und SSH. 33 3 KANALCODIERUNG [3] 3 Kanalcodierung [3] Dieses Kapitel gibt eine kurze Einführung in die Codierung mit Faltungscodes. Dabei beschränken wir uns auf den binären Fall, d.h. Codes über das Galois-Feld GF(2). Bild 3.1 zeigt das allgemeine Übertragungssystem mit Codierung und Decodierung. Digitale Quelle u x Codierer Rauschen Digitale Senke Bild 3.1: û Decodierer n Kanal y Einfaches Modell eines Codierungs-/Decodierungssystems Eine Informationsquelle sendet eine Sequenz von binären Daten, die uncodierte Sequenz u. Diese Sequenz wird im Codierer in die codierte Sequenz x transformiert. Während der Übertragung über den Kanal wird die codierte Sequenz x durch den Rauschvektor n verfälscht. Diese Annahme ist korrekt, solange die Störung von additiver Natur ist und keine Intersymbolinterferenz präsent ist. Aus der gestörten Sequenz y schätzt der Decodierer die am wahrscheinlichsten gesendete Datensequenz û. Codearten Im Allgemeinen unterscheidet man zwei Hauptarten von Codes, die Blockcodes und die Faltungscodes. Der Ausgang eines Blockcodierers teilt den Datenstrom in einzelne Blöcke und fügt zusätzliche Bits zur Fehlerkorrektur an. Dagegen erzeugt ein Faltungscodierer einen kontinuierlichen Datenstrom von theoretisch unendlicher Länge. Die Information zur Fehlerkorrektur wird hier mit den eigentlichen Daten verrechnet. 34 3 KANALCODIERUNG [3] 3.1 Faltungscodierung Faltungscodes (convolutional codes) bieten neben der Gruppe der Blockcodes eine weitere Art der Fehlerkorrektur in der Kanalcodierung. Im Gegensatz zu Blockcodes besitzt der Encoder bei Faltungscodes ein Gedächtnis, d. h., dass ein Codeblock nicht nur vom aktuellen Informationsblock abhängt, sondern auch von den vorhergehenden Blöcken. Faltungscodes lassen sich durch eine lineare Abbildung einer Menge von Informationswörtern auf eine Menge von Codewörtern beschreiben. Dabei werden die Codewörter durch Faltung einer Informationssequenz mit einem Satz von Generatorkoeffizienten gebildet. Im Folgenden beschränken wir uns auf binäre Faltungscodes. Die Informationssequenz durchläuft ein Schieberegister, welches aus L k-Bit-Blöcken und n Exclusiv-Oder-Gliedern besteht, wie in Bild 3.2 gezeigt wird. Der Startzustand der Register ist immer Null. In jedem Zeittakt werden also k Bits in die Register geschoben und n Bits bilden das zugehörige Ausgangscodewort. Daraus ergibt sich eine Coderate von R = k/n. L k-Bit Blöcke Informationssequenz 1 2 ... k 1 2 ... k 1 2 ... k + + + + 1 2 3 n Codesequenz Bild 3.2: Faltungscodierer Die Einflusslänge (constraint length) L beschreibt die „Länge“ des Faltungscodierers - sie entspricht die Anzahl der k-Bit-Blöcke. Nah verwandt mit dem Parameter L ist der Parameter m, der die Dauer beschreibt, wie lange ein Eingangsbit im Faltungscodierer verbleibt und für die weitere Codierung verwendet wird. Der Parameter m gibt somit die Gedächtnislänge (memory length) des Codierers an und ist mit der Einflusslänge über L = m + 1 verknüpft. Um die Struktur eines Faltungscodierers zu beschreiben, gibt man einen Satz von Generatorsequenzen an, für jedes der n Exklusiv-Oder-Glieder jeweils eine. Die Generatorsequenz gibt an, welche der L × k Registerblöcke mit dem zugehörigen Exklusiv-Oder-Glied verbunden sind. Eine Eins in der Generatorsequenz deutet auf eine Verbindung hin und eine Null bedeutet 35 3 KANALCODIERUNG [3] keine Verbindung. Bild 3.3 zeigt einen einfachen Faltungscodierer der Einflusslänge 3 und der 1 2 + Input Output + 3 Coderate 1/3. Bild 3.3: Einfacher Faltungscodierer mit L = 3, k = 1, n = 3 Die zugehörigen Generatorsequenzen lauten: g 1 = [ 100 ] g 2 = [ 101 ] g 3 = [ 111 ] Die Generatorsequenzen werden in der Literatur meist in oktaler Schreibweise dargestellt. Für diesen Faltungscodierer erhalten wir dann die Form (4, 5, 7). Um einen Faltungscodierer darzustellen, gibt es weitere Möglichkeiten, die in den folgenden Abschnitten behandelt werden. In dieser Diplomarbeit beschränken wir uns auf Codierer der Coderate 1/2. 3.1.1 Zustandsdiagramm Das Zustandsdiagramm (state diagram) in Abbildung 3.4 stellt die Zusammenhänge bei einem Faltungscodierer als deterministischen Automaten (Mealy-Automat) dar. Die durchgehenden Pfeillinien kennzeichnen Übergänge, die durch eine Eins als Eingabebit hervorgerufen werden und die gestrichelten Pfeile stehen für Übergänge aus Null-Bit-Eingaben. Die zugehörigen Ausgangscodewörter stehen neben den Pfeilen. Das Zustandsdiagramm beginnt und endet im Allgemeinen im Nullzustand. Die Schleife am Nullzustand für eine Null-Bit-Eingabe besitzen alle Diagramme von Faltungscodierern. 36 3 KANALCODIERUNG [3] 011 100 Zustand 01 011 010 Zustand 00 011 Zustand 10 000 Zustand 11 110 101 Bild 3.4: 3.1.2 Zustandsdiagramm des Faltungscodierers aus Bild 3.3 Codebaum Eine weitere Möglichkeit der Darstellung ist der Codebaum in Form eines Baumdiagramms (tree diagram). Mit ihm werden sämtliche Codesequenzen in Abhängigkeit der Eingangsfolge dargestellt. Bild 3.5 zeigt den Codebaum zum Faltungscodierer aus Bild 3.3. 000 000 111 000 111 000 001 111 0 110 011 1 001 100 111 010 110 101 Bild 3.5: Codebaum des Faltungscodierers aus Bild 3.3 37 3 KANALCODIERUNG [3] Der Weg der Eingangsfolge u = [ 010 ] ist im Codebaum hervorgehoben und liefert die Ausgangsfolge v = [ 000111001 ] . Der Codebaum zeigt die Codegeneration in zeitlicher Abfolge auf. Zu einem Zeitpunkt t besteht der Codebaum aus 2 kt Knoten. Dies führt jedoch mit zunehmender Zeit zu einer Komplexität, die die Darstellung im Baumdiagramm unpraktikabel macht. In Bild 3.5 erkennt man, dass sich Teile des Codebaumes periodisch wiederholen. Knoten mit gleichem Zustand können zusammengefasst werden, weil von ihnen immer die gleichen Zweige ausgehen. Dies führt zu der einfacheren Darstellungsform, zum so genannten Trellisdiagramm. 3.1.3 Trellisdiagramm Das Trellisdiagramm ist eine kompaktere Darstellungsart eines Faltungsdecodierer als der Codebaum. Periodisch wiederkehrende Teile des Codebaumes sind im Trellisdiagramm zusammengefasst. Diese Darstellung wird besonders bei der ML-Decodierung mittels ViterbiAlgorithmus verwendet. Das Diagramm zeigt die möglichen Pfadverläufe der Codewörter von Zustand zu Zustand über der Zeit. Die Anzahl der Zustände beträgt 2 L und entspricht der Anzahl der Zustände des Schieberegisters im Faltungscodierer. Ein Beispiel eines Trellisdiagramms ist in Abbildung 3.6 zu sehen. Zustand 00 000 111 000 111 000 000 000 111 111 111 011 011 011 Zustand 01 100 001 100 001 100 001 001 Zustand 10 110 110 110 010 010 Zustand 11 101 t=0 Bild 3.6: t=1 t=2 110 010 101 t=3 101 t=4 t=5 Trellisdiagramm des Faltungscodierers aus Bild 3.3 Pfade, welche von vom Eingangsbit Null herrühren werden im Diagramm mit einer durchgezogenen Line dargestellt und gestrichelte Linien verdeutlichen eine Eins als Eingabebit. Das Trellisdiagramm beginnt gewöhnlich im Nullzustand. Auffallend ist das anfängliche expo- 38 3 KANALCODIERUNG [3] nentielle Wachstum der Pfadanzahl mit der Zeit, welches zu Zeitpunkten t ³ L konstant wird. In jedem Zustand nach der Aufbauphase beginnen und enden jeweils 2 k Pfade. 3.1.4 Polynominale Darstellung Lineare Faltungscodes lassen sich durch Generatoren gj beschreiben. Sie werden in der Literatur meist in otkaler Schreiweise angegeben. Für die Einflusslänge Lc=3 und eine Rate von R=1/2 sind nachfolgend zwei Generatoren angegeben. g 1 = ( g 1, 0, g 1, 1, g 1, 2 ) = ( 1, 1, 1 ) = 7 8 (3.1) g 2 = ( g 2, 0, g 2, 1, g 2, 2 ) = ( 1, 0, 1 ) = 5 8 (3.2) Mit Hilfe der diskreten Faltung lässt sich aus der Eingangssequenz u und den Generatoren gj die Codierung nach Gleichung (3.3) berechnen. x1 = u * g1 und x2 = u * g2 (3.3) Es gilt der allgemeine Zusammenhang nach Gleichung (3.4): m xu( l) = åg u × u l – i mod2 (3.4) i=0 Die Signalfolgen und Generatoren lassen sich im Spektralbereich auch mit der Z-Transformation beschreiben. Die Z-Transformation ist durch folgenden Zusammenhang gegeben: ¥ Z(x) = åx u ×z –u (3.5) u=0 In der Nachrichtentechnik verwendet man anstelle des z-1-Operators meist den Operator D (Delay). Damit lässt sich die Gleichung (3.5) auch als Gleichung (3.6) schreiben. ¥ X( D) = åx u ×D u (3.6) u=0 Die Generatoren werden dann folgendermaßen beschrieben: 2 G 1 ( D ) = g 10 + g 11 D + g 12 D = 1 + D + D 2 (3.7) 39 3 KANALCODIERUNG [3] 2 G 2 ( D ) = g 20 + g 21 D + g 22 D = 1 + D 2 (3.8) Für das u -te Polynom und die zugehörige Ausgangsfolge X u ( D ) ergibt sich der allgemeine Zusammenhang: m Gu ( D ) = åg ui ×D u und X u ( D ) = U ( D ) × G u ( D ) (3.9) i=0 Die gesamte codierte Sequenz kann in der Polynomschreibweise durch X ( D ) = X1 ( D ) X2 ( D ) ¼ Xn ( D ) = U ( D ) × G ( D ) (3.10) mit der Generatormatrix G ( D ) = G 1 ( D ) G 2 ( D ) ¼ G n ( D ) dargestellt werden. 3.1.5 Katastrophale Faltungscodierer Katastrophale Faltungscodierer sind in der Lage unendlich lange Sequenzen mit endlichem Gewicht zu erzeugen. Diese kehren nicht wieder auf den Null-Pfad zurück. Dadurch kann diese Art von Faltungscodierern bei endlich vielen Übertragungsfehlern unendlich viele Fehler nach der Decodierung mit dem Viterbi-Algorithmus erzeugen. Aufgrund dessen sind katastrophale Faltungscodierer nicht zur sicheren Datenübertragung geeignet. Man erkennt katastrophale Faltungscodierer an folgenden Eigenschaften: • Alle Generatorpolynome besitzen einen gemeinsamen irreduziblen Faktor • Im Zustandsdiagramm existiert eine geschlossene Schleife mit Gewicht Null außer dem Nullzustand • Alle XOR-Glieder haben eine gerade Anzahl von Verbindungen (Die Schleife im Zustand 1...1 besitzt Gewicht Null) 40 3 KANALCODIERUNG [3] Abbildung 3.7 zeigt ein Beispiel für einen katastrophalen Faltungscodierer mit den Generatoren g1 = 58 und g2 = 38. x1 u D D x2 Bild 3.7: Katastrophaler Faltungscodierer Abbildung 3.8 zeigt das zugehörige Zustandsdiagramm mit der charakteristischen Schleife im Zustand 11. 0/00 00 1/11 0/10 1/01 10 01 0/01 1/10 0/11 11 1/00 Bild 3.8: Zustandsdiagramm des katastrophalen Faltungscodierers aus Abbildung 3.7 41 3 KANALCODIERUNG [3] 3.1.6 Endliche Faltungscodes In der Theorie sind Faltungscodes unendlich lange Folgen. In der Praxis hingegen werden meist endliche Codesequenzen benutzt. Es existieren verschiedene Methoden endliche Codes zu übertragen. Nachfolgend wird daher die Terminierung, Truncation und das Tail-Biting behandelt [29]. Truncation Bei der Decodierung von Faltungscodes benötigt der Viterbi-Algorithmus die gesamte bzw. eine ausreichend lange Codesequenz. Lässt man die Informationssequenz unbestimmt enden, ist jeder Zustand am Ende des Trellisdiagramms möglich. Der Endzustand ist somit dem Decodierer nicht bekannt. Da sich die letzten Bits der Informationssequenz nur sehr wage schätzen lassen, bewirkt dies eine unsichere Decodierung der letzten Bits. Terminierung Bei der Terminierung fügt man am Ende der zu übertragenden Informationsbitfolge eine vorher bestimmte Bitfolge an. Diese so genannte Terminierung bringt den Faltungscodierer am Ende der Informationssequenz in einen definierten Zustand. Mit der Kenntnis dieses Endzustandes ist der Empfänger in der Lage, mit Hilfe des Viterbi-Algorithmus die empfangene Codesequenz richtig zu decodieren. Die Terminierungsbits werden meist zu Null gewählt, um am Ende der Informationssequenz in den Nullzustand zu gelangen. Die Länge der Terminierung sollte mindestens k × m Bits betragen, wobei m die Gedächtnisordnung des Faltungscodierers entspricht. Die Rate der terminierten Codes verringert sich geringfügig um den so genannten Fractional-Rate-Loss K / (K + m). Die Coderate ergibt sich damit zu Gleichung (3.11). K kK R T = ---------------------- = R -------------K+m n(K + m) (3.11) K ist hierbei die Anzahl der codierten Informationsblöcke. Für den Fall, dass K sehr groß ist, ergibt sich R T » R . Tailbiting Heutige Datenübertragungssysteme erfordern oftmals eine sehr kleine Paketgröße. Das Anfügen von Terminierungsbits kann für derartige Systeme eine Verringerung der Datenrate zur 42 3 KANALCODIERUNG [3] Folge haben und das Verfahren ineffizient machen. Daher gibt es noch eine dritte Möglichkeit - das so genannte Tailbiting. Bei diesem Verfahren wird die zu sendende Informationsbitfolge codiert und der Endzustand bestimmt. Anschließend wird der erhaltene Endzustand als Anfangszustand gewählt und die Informationsbitfolge erneut codiert [29]. 3.1.7 Punktierte Faltungscodes Um höhere Coderaten d.h. ein besseres Verhältnis von k zu n zu erreichen, werden Faltungscodes gewöhnlich punktiert. Zu diesem Zweck werden nLP Codebits zu jeweils LP Codeblöcken zusammengefasst. L P ist die so genannte Punktierungslänge. Man erhält punktierte 1 Codes aus Faltungscodes der Rate --n- , indem man aus dieser Gruppe der Ausgangscodeworte l 1 Bits ausgeblendet und nicht überträgt. Hierbei wird der ursprüngliche --n- Code als Muttercode bezeichnet. Zur Decodierung muss dem Empfänger das Punktierungsschema selbstverständlich bekannt sein. Der Vorteil der Punktierung ist die einfache Anpassung der Coderate an die aktuellen Übertragungsbedingungen. Die Punktierung erfolgt normalerweise periodisch mit der Periode LP und lässt sich mit Hilfe einer Punktierungsmatrix P beschreiben: p 1, 0 p 1, 1 ¼ p 1, LP P = p 2, 0 p 2, 1 ¼ p 2, LP ¼ ¼ ¼ ¼ p n, 0 p n, 1 ¼ p n, LP = ( p 0, p 1, ¼, p L P ) (3.12) (3.13) Jede Spalte p i von P enthält das Punktierungsschema für ein Codewort und besteht somit aus n Elementen. Die Coderate nach der Punktierung ergibt sich aus der Anzahl der Infobits L P und der Anzahl der übertragenen Codebits nLP – l zu LP 1 - , æ R > --- = Rö R P = ---------------ø nL P – l è P n (3.14) unter der Bedingung das l < ( n – 1 )P sein muss, um Coderaten kleiner eins zu erhalten. Die Struktur von P ist nur in den einfachsten Fällen trivial. So kann beispielsweise durch die Punktierung ein katastrophaler Code entstehen. In diesem Fall ist die Punktierung auf die jeweiligen Generatoren abzustimmen. Numerisch optimierte Punktierungs-Schemata zeigen die Tabellen 3.1 und 3.2. Verwendbare Punktierungsmasken erhält man durch systematische Suche. 43 3 KANALCODIERUNG [3] Um punktierte Codes zu decodieren, fügt man im Viterbi-Algorithmus anstelle der nichtübertragenen Bits beliebige Bits ein, ohne sie bei der Berechnung der Hamming-Distanzen zu berücksichtigen. Tabelle 3.1: Punktierungs-Schemata 1, [20], [30] Originalcode R = 2/3 R = 3/4 R = 4/5 m g(1), g(2) P d free , A dfree , B dfree P d free , A d free , B d free P d free , A dfree , B dfree 2 5, 7 10 11 3, 1, 1 101 110 3, 6, 15 1011 1100 2, 1, 1 3 15, 17 11 10 4, 3, 10 110 101 4, 29, 124 1011 1100 3, 5, 14 4 23, 35 11 10 4, 1, 1 101 110 3, 1, 1 1010 1101 3, 3, 11 5 53, 75 10 11 6, 1, 3 100 111 4, 1, 3 1000 1111 4, 7, 40 6 133, 171 11 10 6, 1, 3 110 101 5, 8, 42 1111 1000 4, 3, 12 7 247, 371 10 11 7, 9, 47 110 101 6, 36, 239 1010 1101 5, 20, 168 8 561, 753 11 10 7, 3, 11 111 100 6, 10, 52 1101 1010 5, 7, 31 Tabelle 3.2: Punktierungs-Schemata 2, [20], [30] Originalcode R = 5/6 R = 6/7 R = 7/8 m g(1), g(2) P d free , A dfree , B dfree P d free , A d free , B d free P d free , A dfree , B dfree 2 5, 7 10111 11000 2, 2, 2 101111 110000 2, 4, 5 1011111 1100000 2, 6, 8 3 15, 17 10100 11011 3, 15, 63 100011 111100 2, 1, 2 1000010 1111101 2, 2, 4 4 23, 35 10111 11000 3, 5, 20 101010 110101 3, 14, 69 1010011 1101100 3, 13, 49 44 3 KANALCODIERUNG [3] Originalcode R = 5/6 R = 6/7 R = 7/8 5 53, 75 10000 11111 4, 19, 100 110110 101001 3, 5, 25 1011101 1100010 3, 9, 60 6 133, 171 11010 10101 4, 14, 92 111010 100101 3, 1, 5 1111010 1000101 3, 2, 9 7 247, 371 11100 10011 4, 2, 7 101001 110110 4, 11, 85 1010100 1101011 4, 26, 258 8 561, 753 10110 11001 5, 19, 168 110110 101001 4, 2, 9 1101011 1010100 4, 6, 70 = freie Distanz A dfree = Anzahl von Sequenzen bei der Mindestdistanz d free B dfree = Koeffizient zur Abschätzung der Bitfehlerwahrscheinlichkeit 45 3 KANALCODIERUNG [3] 3.2 Viterbi-Algorithmus Der Viterbi-Algorithmus findet Anwendung bei der Decodierung von Faltungscodes. Er arbeitet nach dem Prinzip eines Maximum-Likelihood Sequence Estimators (MLSE), in dem er zu der empfangenen Codewortfolge eine möglichst ähnliche Codewortfolge sucht. Die Ähnlichkeit zweier Codewörter wird bei Hard-Decision-Decodierung über die Hamming-Distanz und bei Soft-Decision-Decodierung über die Euklidische Distanz bestimmt. Theoretisch müsste ein Decodierer alle möglichen Codewortfolgen mit der empfangenen Codewortfolge vergleichen. Da die Anzahl der Codewortfolgen jedoch mit der Zeit exponentiell anwächst (siehe Codebaum zur Faltungscodierung), verwendet man den Viterbi-Algorithmus, um den Decodierungsaufwand gering zu halten. Dieser lässt sich am einfachsten am Trellisdiagramm nachvollziehen. Das folgende Beispiel soll die Viterbi-Decodierung verdeutlichen. Der Faltungscodierer aus Abbildung 3.3 wandelt die terminierte Info-Bit-Folge u = ( 1, 0, 1, 0, 0 ) in die Codefolge v = ( 111, 001, 100, 001, 011 ) um. Durch Übertragungsfehler kommt am Empfänger die Codefolge y = ( 111, 101, 000, 001, 001 ) an. Die hier angewandte Metrik soll den Pfadkosten entsprechen, welche durch die Anzahl der unterschiedlichen Bits einer Codefolge ausgedrückt werden. Die Decodierung beginnt üblicherweise mit dem Zustand 00. Im ersten Schritt werden die Pfadkosten der Zustandsübergänge 00 ® 00 und 00 ® 10 berechnet. Die Pfadkosten des Übergangs 00 ® 00 betragen 3, da sich das erste empfangene Codewort y 0 = 111 von dem Codewort des Zustandüberganges im Trellis c 00 ® 00 = 000 um 3 Bitstellen unterscheidet. Analog dazu erhält man für den Übergang 00 ® 10 Pfadkosten von 0. Abbildung 3.9 erläutert den ersten Schritt: 000 Zustand 00 Pfadkosten = 3 111 Zustand 01 Zustand 10 Pfadkosten = 0 Zustand 11 t=0 Bild 3.9: t=1 Schritt 1 der Viterbi-Decodierung Im zweiten Schritt (Abbildung 3.10) steigt die Anzahl der möglichen Pfade auf das Doppelte. Die weiteren Pfadkosten setzen sich aus den neuen Kosten des Zustandübergangs vom Zeitpunkt t = 1 zum Zeitpunkt t = 2 und den im vorherigen Schritt berechneten Pfadkosten des 46 3 KANALCODIERUNG [3] Vorgängerzustands zusammen. Die Pfadkosten aus Schritt 1 stehen in Klammern neben den zugehörigen Zuständen. (3) 000 000 Zustand 00 111 Pfadkosten = 5 111 Pfadkosten = 1 Zustand 01 001 (0) Zustand 10 Pfadkosten = 4 110 Pfadkosten = 2 Zustand 11 t=0 t=1 t=2 Bild 3.10: Schritt 2 der Viterbi-Decodierung Im dritten Schritt hat das Trellis seine maximale Komplexität erreicht. Zu jedem Zustand um Zeitpunkt t = 3 führen nun zwei Pfade mit den zugehörigen Pfadkosten. Der Pfad mit den geringsten Pfadkosten wird für die weiteren Berechnungen weitergeführt und der Pfad mit den höheren Pfadkosten wird nicht mehr weiterverfolgt. 000 Zustand 00 111 000 111 000 (5) Pfadkosten = 3 (1) Pfadkosten = 3 111 011 Zustand 01 100 001 001 Zustand 10 110 (4) Pfadkosten = 2 (2) 101 Pfadkosten = 4 110 010 Zustand 11 t=0 t=1 t=2 t=3 Bild 3.11: Schritt 3 der Viterbi-Decodierung Im vierten Schritt (Abbildung 3.12) tritt ein Sonderfall in der Pfadentscheidung auf. Zu den Zuständen 00 und 10 führen jeweils zwei Pfade mit der gleichen Metrik. In diesem Fall wird eine Zufallsentscheidung getroffen, welcher Pfad weitergeführt werden soll. 47 3 KANALCODIERUNG [3] Zufallsentscheidung! Zustand 00 000 (3) 111 Pfadkosten = 4 111 011 011 (3) Zustand 01 Pfadkosten = 3 100 100 001 001 Zustand 10 (2) 110 010 Zustand 11 010 (4) 101 t=0 Pfadkosten = 5 110 t=1 t=2 Pfadkosten = 5 101 t=3 t=4 Bild 3.12: Schritt 4 der Viterbi-Decodierung Im fünften Schritt (Abbildung 3.13) wurde die gesendete Datenfolge vollständig empfangen. Da die gesendete Datenfolge mit 00 terminiert wurde, lässt sich die ursprüngliche Datenfolge decodieren, indem man den Pfad zurückverfolgt, welcher im Zustand 00 (entsprechend der Terminierung) endet. 000 Zustand 00 000 000 Pfadkosten = 4 (4) 111 111 011 111 011 Zustand 01 011 Pfadkosten = 5 (3) 100 001 100 100 001 Zustand 10 001 Pfadkosten = 5 (5) 110 110 110 010 Zustand 11 (5) t=0 t=1 t=2 t=3 t=4 Pfadkosten = 6 101 t=5 Bild 3.13: Schritt 5 der Viterbi-Decodierung 48 3 KANALCODIERUNG [3] 3.3 Checksummen Im Rahmen der Fehlererkennung hat der Empfänger die Aufgabe festzustellen, ob das gesendete Signal durch Störungen auf dem Übertragungsweg verfälscht wurde. Zu diesem Zweck berechnet der Sender über eine Funktion aus den Daten einen Wert, die so genannte Checksumme und fügt sie dem Datenpaket an. Auf der Empfangsseite wird mit der gleichen Funktion die Checksumme über die Daten berechnet und mit der angehängten Checksumme verglichen. Wenn die empfangseitig berechnete Checksumme mit der sendeseitigen Checksumme übereinstimmen, wird die Nachricht mit einer bestimmten Wahrscheinlichkeit als unverfälscht angenommen, andernfalls wurde die Nachricht wahrscheinlich fehlerhaft übertragen. Für den Fall, dass die Nachricht fehlerfrei übermittelt wurde und nur die Checksumme Fehler enthält, werden die Daten ebenfalls für fehlerhaft gehalten, weil sich ein Fehler nicht lokalisieren lässt. 3.3.1 CRC - Cyclic Redundancy Checksums Heute übliche Checksummen arbeiten mit dem CRC-Algorithmus [32]. Vereinfacht ausgedrückt, behandelt er die zu sendenden Daten als eine lange binäre Zahl, die durch eine feststehende binäre Zahl dividiert wird. Der Divisionsrest ergibt die zugehörige Checksumme. CRC-Algorithmen benutzten Modulo-2-Arithmetik und werden durch Generatorpolynome charakterisiert. Die Addition und Subtraktion in der Modulo-2-Arithmetik entspricht der gewöhnlichen Bitaddition mit der Ausnahme, dass es keinen Übertrag gibt. Auf jede Bitstelle wird eine Exklusiv-Oder-Operation angewendet. Ein Beispiel wird in Abbildung 3.14 gezeigt. 1011010 +0111011 1100001 1011010 -0111011 1100001 Bild 3.14: Beispiel einer Modulo-2 Addition und Subtraktion Der divisions-ähnliche CRC-Algorithmus lässt sich folgendermaßen beschreiben. Sei c der Grad des Generatorpolynoms. Die Generatorbitfolge ist also c + 1 Bit lang. Dann werden c Nullen den Daten angefügt und der CRC über die damit erweiterte Bitfolge berechnet. Übernehme die höchstwertigsten c + 1 Bits der Datenfolge als den Rest in das Schieberegister. Beginne mit dem höchstwertigsten Bit in der Orginaldatenfolge und betrachte für jede Bitposition die c + 1 Bits des Restes. Wiederhole folgende Operationen bis letztes Bit der Datenfolge bearbeitet wurde: Falls das höchstwertigste Bit des Restes eine Eins ist, wende eine XOR-Operation auf den 49 3 KANALCODIERUNG [3] Rest mit der Generatorbitfolge an, andernfalls wende eine XOR-Operation auf den Rest mit einer c + 1 langen Null-Bitfolge an. Schiebe das Ergebnis dieser Berechnung um ein Bit nach links, sodass das höchstwertigste Bit entfällt und schiebe von rechts das nächste Bit der Datenfolge nach. Der Rest nach der letzten Berechnung ergibt die Checksumme. Der Quotient bei diesem divisions-ähnlichen Algorithmus interessiert nicht. Da eine Bitfolge A bitweise mit einer Nullbitfolge exklusiv-geodert wieder die ursprüngliche Bitfolge A ergibt, kann man die XOR-Operation bei einer Null als höchstwertigstem Bit im Rest überspringen. Ein Beispiel soll den CRCAlgorithmus verdeutlichen. 111001010000 11011 01111 00000 11110 11011 01011 00000 10110 11011 11010 11011 00010 00000 00100 00000 0100 Teiler/Generatorpolynom:11011 Rest/CRC Bild 3.15: Beispiel des CRC-Algorithmus Nach der CRC-Berechnung werden die hinzugefügten Nullbits am Ende der Datenfolge durch den CRC ersetzt und die gesamte Bitfolge übertragen. Der Empfänger berechnet über diese Bitfolge mit der gleichen Generatorbitfolge wieder einen CRC. Ist der Wert dieser Checksumme Null, wurde die Datenfolge mit hoher Wahrscheinlichkeit richtig übertragen, andernfalls wird sie als fehlerhaft angenommen. Die CRC-Längen betragen meist 8, 16 oder 32 Bit. Das bedeutet, dass die Generatorpolynome Längen von 9, 17 oder 33 Bit haben. Für die Implementierung des Schieberegisters benötigt man jedoch nur die Länge des CRCs, weil das höchstwertigste Bit eines Generatorpolynoms immer Eins ist und das höchstwertigste Bit nach der XOR-Operation immer Null ist. Daher lässt sich die CRC-Berechnung auch mit 8-, 16- oder 32-Bit-Register durchführen. 50 3 KANALCODIERUNG [3] Die zur CRC-Berechnung benötigten Parameter finden sich in Tabelle 3.3. Sie entsprechen internationalen Standards, welche zum Teil vom CITT (Comité Consultatif International de Télégraphique et Téléphonique) genormt wurden. CRC-8 CITT CRC-16 CITT CRC-16 CRC-32 Breite [Bit] 8 16 16 32 Generatorpolynom [HEX] 07 1021 8005 04C11DB7 Initialwert [HEX] ? FFFF 0000 FFFFFFFF Letzter XOR-Wert [HEX] ? 0000 0000 FFFFFFFF Reflect Data ? nein ja ja Reflect Rest ? nein ja ja Prüfwert [HEX] ? 29B1 BB3D CBF43926 Tabelle 3.3: Parameter zur CRC-Berechnung nach internationalen Standards [32, 33, 34] Der Initialwert wird vor Beginn des CRC-Algorithmus in das Schieberegister geladen. Mit dem XOR-Wert wird das Schieberegister nach Beendigung des CRC-Algorithmus exklusiv verodert. Der Reflect-Data- bzw. Reflect-Rest-Parameter gibt an, ob die Bitreihenfolge der Eingangsbytes bzw. des Teilerrest-Bytes invertiert werden soll. Der Grund für diese Invertierung ist die Kompatibilität zu früheren UARTs (Universal Asynchronous Receiver Transmitter), welche ebenfalls mit invertierter Bitreihenfolge innerhalb eines Bytes arbeiteten. Der Prüfwert kann als ein schwacher Indikator zur Implementierung eines CRC-Algorithmus benutzt werden. Er gibt die resultierende Prüfsumme für den Fall an, dass der Algorithmus auf die ASCII-Zeichenfolge “123456789” angewendet wird. 51 3 KANALCODIERUNG [3] 3.4 Rahmensynchronisation Die Rahmensynchronisation (frame synchronization) versucht, den Paketanfang in Zeitmultiplexsystemen herauszufinden. Voraussetzung für eine Rahmensynchronisation ist eine erfolgreiche Bitsynchronisation. Eine mögliche Realisierung besteht in der Verwendung von Startbits am Paketanfang. Jedes Mal, wenn der Empfänger diese Startbits erhält, detektiert er den Anfang eines neuen Datenpaketes. Als Startbits eigenen sich besonders gut so genannte Barkersequenzen. Diese Bitfolgen haben die Eigenschaft, dass ihre Autokorrellationskoeffizienten für jede Taktverschiebung sehr klein werden. Zur Detektion von Barkersequenzen verwendet man die Schaltung aus Abbildung 3.16. Die Schaltung detektiert die 7-Bit-lange Barkersequenz 1110010. Schieberegister Eingang 1 2 3 4 5 6 Ausgang 7 Takt Q1 Q1 + - Q2 Q2 + - Q3 Q3 + - Q4 Q4 - + Q5 Q5 - + Q6 Q6 + - Q7 Q7 - + Summe Korrelationskoeffizient Bild 3.16: Schaltung zur Detektion von Barkersequenzen, [21] Die Schaltung besteht aus einem Schieberegister mit der Länge der Barkersequenz. Die einzelnen Schieberegister sind Flipflops mit jeweils zwei Ausgängen Q i und Q i (i=1...7). Die Ausgänge der Flipflops sind über Vorzeichenglieder mit einem Summierglied verbunden. Am Ausgang des Summierglieds liegt die Rahmeninformation an. Die Barkerdetektion lässt sich verstehen, wenn man folgendes Beispiel betrachtet: Beispiel: Es wird von links nach rechts die Barkersequenz 1110010 durch das Register geschoben. Zum Taktzeitpunkt n tritt die letzte Null der Barkersequenz an Stelle 1 des Registers und es befinden sich im Schieberegister nur Nullen. Der zugehörige Korrelationskoeffizient beträgt in diesem Fall -1. Nun folgt zum Taktzeitpunkt n + 1 eine Eins in das Schieberegister, wobei alle Bits um eine Stelle nach rechts rücken. Der zugehörige Ausgang nimmt den Wert +1 an. Alle weiteren Schritte lassen sich mit Tabelle 3.4 nachvollziehen. Es 52 3 KANALCODIERUNG [3] fällt auf, dass zu allen Taktzeiten außer dem Zeitpunkt n + 6 die Ausgangswerte zwischen -1 und +1 liegen. Zum Zeitpunkt n + 6 des vollständigen Eintritts der Barkersequenz ergibt sich eine Korrelationsspitze vom Wert +7. Nach dem Passieren der Barkersequenz geht das Ausgangssignal wieder auf Werte zwischen -1 und +1 zurück. Anhand dieses kurzzeitigen Spitzenwerts lässt sich die Barkersequenz detektieren und somit einen Paketanfang feststellen. Tabelle 3.4: Zwischenergebnisse der Schaltung aus Abbildung 3.16, [21] Taktzeit Q1 Q 1 Q 2 Q2 Q 3 Q3 Q4 Q4 Q5 Q 5 Q6 Q6 Q7 Q 7 Summe n 01 -1 01 -1 01 -1 01 +1 01 +1 01 -1 01 +1 -1 n+1 10 +1 01 -1 01 -1 01 +1 01 +1 01 -1 01 +1 +1 n+2 01 -1 10 +1 01 -1 01 +1 01 +1 01 -1 01 +1 +1 n+3 01 -1 01 -1 10 +1 01 +1 01 -1 01 -1 01 +1 +1 n+4 10 +1 01 -1 01 -1 10 -1 01 +1 01 -1 01 +1 -1 n+5 10 +1 10 +1 01 -1 01 +1 10 -1 01 -1 01 +1 +1 n+6 10 +1 10 +1 10 +1 01 +1 01 +1 10 +1 01 +1 +7 n+7 01 -1 10 +1 10 +1 10 -1 01 +1 01 -1 10 -1 -1 53 3 KANALCODIERUNG [3] Einige mögliche Barkersequenzen gibt Tabelle 3.5 wieder. Barkersequenzen existieren nicht für beliebige Stellenanzahlen, sondern nur für einige wenige. Weitere Barkersequenzen erhält man durch Bitinversion sowie durch Vertauschen der Bitreihenfolge von gültigen Barkersequenzen. Tabelle 3.5: Barkersequenzen verschiedener Längen, [21] 3.4.1 m Barkersequenzen 3 110 4 1 1 0 1, 1110 5 11101 7 1110010 11 11100010010 13 1111100110101 Implementierung Zur Programmierung der Schaltung aus Abbildung 3.16 sind folgende Vereinfachungen hilfreich. Es gibt nur vier Möglichkeiten wie das Ausgangssignal eines Flipflops mit Vorzeichengliedern zustande kommt. Das Register kann entweder den Zustand Eins oder Null annehmen und es gibt nur zwei Möglichkeiten der Anordnung der Vorzeichenglieder. Bild 3.17 gibt diese Kombinationen wieder. Barker: 1 Barker: 1 Barker: 0 Barker: 0 Input: 1 Input: 0 Input: 1 Input: 0 Q1 Q1 Q1 Q1 + - Output: +1 + - Output: -1 Q3 Q3 + - Output: -1 Q3 Q3 + - Output: +1 Bild 3.17: Vier Möglichkeiten von Eingangssignal und Vorzeichenglieder-Anordnung eines Flipflops 54 3 KANALCODIERUNG [3] Eine logische Ersatzschaltung lässt sich durch die tabellarische Analyse der Eingangs- und Ausgangssignale gewinnen. Tabelle 3.6 verdeutlicht diesen Sachverhalt. Tabelle 3.6: Logische Analyse eines Flipflops mit Vorzeichengliedern Registerzustand R Barker B Ausgang A 1 1 1 0 1 -1 (0) 1 0 -1 (0) 0 0 1 Die Vorzeichengliederanordnung ist direkt abhängig von der Stelle der Barkersequenz. Daher ist in Tabelle 3.6 diese Abhängigkeit unter “Barker” vermerkt. Betrachtet man das Ausgangssignal als ein logisches Signal, kann man den Wert -1 mit Null identifizieren. Mit dieser Vereinfachung lässt sich das Ausgangssignal der Schaltung nach Gleichung (3.15) programmieren. A = RÅB (3.15) 55 3 KANALCODIERUNG [3] 3.5 Forward Error Correction Die typische Anwendung der Forward Error Correction (FEC) liegt in einer sicheren Übertragung der Daten über einen Kanal durch Hinzufügen von redundanter Information. Das Hinzufügen der redundanten Information wird auch Kanalcodierung genannt. Die zwei gebräuchlichsten Kanalcodierungsarten sind die Faltungs- und Blockcodierung. Faltungscodes verarbeiten die zu übertragende Information seriell mit einem oder wenigen Bits zur gleichen Zeit. Blockcodes dagegen verarbeiten die Information in relativ großen Blocken, typischerweise mehrere 100 Bytes. Es gibt eine Vielzahl von nützlichen Faltungs- und Blockcodes und eine Vielzahl von Decodier-Algorithmen, um die Information möglichst fehlerfrei zurückzugewinnen. Faltungscodierung in Kombination mit Viterbi-Decodierung ist ein weit verbreitetes Verfahren bei Kanälen, die durch weißes Gaußrauschen (AWGN) gestört werden. FEC und ARQ Die typische Anwendung für Powerline-Modems ist die Datenübertragung zwischen zwei Rechnern. Dabei sollen die Daten selbstverständlich unverfälscht beim Zielrechner ankommen. In einem Powerline-Modem stellen zwei unabhängig voneinander arbeitende Mechanismen die Datenintegrität sicher: Zuerst teilt das Modem die Daten in einzelne Pakete auf und fügt mittels der CRC zusätzliche Sicherungsbits in den Datenstrom ein. Diese zusätzlichen Bits stellen sicher, dass der Empfänger Datenverfälschungen nicht nur erkennen, sondern - in begrenztem Umfang - auch korrigieren kann. Je mehr Sicherungsbits eingefügt werden, desto mehr Fehler können behoben werden. Datenübertragung per Powerline setzt auf Forward Error Correction (FEC) und Wiederholung fehlerhaft empfangener Daten (ARQ, Automatic Repeat Request), wie es in Abbildung 3.18 dargestellt wird. Bild 3.18: Wiederholung fehlerhaft empfangener Daten mittels ARQ Bei Musikübertragung an mehrere Empfänger ist ein Quittungsbetrieb jedoch hinderlich. Der Verzicht auf ARQ ermöglicht zudem einen höheren Durchsatz (Abbildung 3.19). 56 3 KANALCODIERUNG [3] Bild 3.19: Datenübertragung bei echtzeitrelevanten Informationen Der zweite Mechanismus zur Fehlervermeidung setzt auf der Empfängerseite an: Lief die Übertragung fehlerfrei - oder korrigiert dank FEC - ab, dann schickt der Empfänger eine Erfolgsmeldung zurück. Bei Datenverlusten setzt er jedoch eine negative Quittung ab und veranlasst so den Sender, das defekt empfangene Paket noch einmal zu übermitteln; bei positiver Rückmeldung gibt der Sender das nächste Paket auf die Leitung. Wird die Übertragung auf dem Spannungsnetz durch kurzzeitige Störungen beeinträchtigt, dann verringert sich zwar die Datenübertragungsrate aufgrund von Paketwiederholungen, es gehen aber keine Daten verloren. Bei der echtzeitfähigen Übertragung muss die Datensicherung anders erfolgen: Ein Übertragungsverfahren mit Quittierung ist praktisch nicht machbar. Ein Sender könnte zwar fehlerhafte Datenpakete an mehrere Dutzend oder Hunderte von Empfängern wiederholen, aber das Datenmanagement und das ständige Umschalten des Übertragungskanals würden laufende Verzögerungen verursachen. Eine störungsfreie Echtzeitübertragung wäre unmöglich. Daher wurde in den Powerline-Modems speziell für die Echtzeitübertragung der Quittierungsbetrieb deaktiviert. Die Sicherung der Daten erfolgt nur noch mittels des eingebauten FECMechanismus. Können die Empfänger-Modems sporadisch auftretende Fehler nicht beheben, dann werden die fehlerhaften Datenpakete verworfen. 57 4 POWERLINE-COMMUNICATION-CHIPSETS 4 Powerline-Communication-Chipsets Dieses Kapitel gibt einen Überblick über zurzeit verfügbare Powerline-Modems. Sie unterscheiden sich hauptsächlich durch ihre Übertragungsrate und ihr Modulationsverfahren. Die Übertragungsrate hängt wesentlich davon ab, für welche Normen die jeweiligen Modems konzipiert wurden, da die Normen die für die Übertragung nutzbare Bandbreite festschreiben. Im Rahmen des fächerübergreifenden Projektes wurden Powerline-Modems der Firmen Austria Mikro Systeme (Abschnitt 4.1) und Intellon (Abschnitt 4.2) verwendet. Diese Modems werden daher eingehender vorgestellt. 4.1 Austria Mikro Systeme Austria Mikro Systeme bietet mit dem AS5501/02 ein Powerline-Modem an, welches den CENELEC EN50065-1 und FCC Standards entspricht. Es arbeitet mit Frequency Shift Keying (FSK) auf einer einstellbaren Frequenz zwischen 95 kHz und 140 kHz und erreicht damit eine Datenrate von 2,4 kbit/s. Die Evaluation-Kits dieser Firma bestehen aus zwei Boards mit zugehöriger Evaluation Software. Die wichtigsten technischen Merkmale des AS5501/02 lassen sich wie folgt zusammenfassen. • Synchroner und Asynchroner Datentransfer • Halb-Duplex, FSK-Modulation • Programmierbare Bitrate 600, 1200, 2400 bit/s. • Sendesignalamplitude 7 Vpp (AS5501) bzw. 14 Vpp (AS5502) • Programmierbare Trägerfrequenz im Bereich von 95 kHz bis 140 kHz (standardmäßige Einstellung ist 132,45 kHz) • Trägererkennung (Carrier Detect) • Referenzspannungs- und Master-Clock-Ausgänge • Kompatibel mit dem CENELEC EN50065-1 und FCC-Standard (siehe Abschnitt 2.3) • Schutz gegen Sendefehler (Dauerträger) Konzipiert wurde das Powerline-Modem ursprünglich für folgende Anwendungen: • Fernauslesung für Zähler (Automatic Meter Reading, AMR) 58 4 POWERLINE-COMMUNICATION-CHIPSETS • Gebäudeautomation und Prozessleittechnik • Alarm- und Sicherheitssysteme • Industrielle Kontrollsysteme Im Rahmen der vorliegenden Diplomarbeit wurde das Powerline-Modem zur Kommunikation eingesetzt. Seine Anwendung lag in der Übermittlung von Daten eines Chatprogramms. Zur besseren Handhabung wurde das Modem in ein Gehäuse mit internem Netzteil eingebaut. Die Kommunikation sowie die Energieversorgung des Modems kann somit über eine Leitung erfolgen. Die Datenkommunikation zum PC geschieht via serielle Schnittstelle. Über den Parallelport lassen sich gegebenenfalls Modem-Einstellungen vornehmen. In Bild 1.1 wird ein Foto des AS5501/02 wiedergegeben. Bild 4.1: Powerline-Modem AS5501/02 von Austria Mikro Systeme Ein Nachteil des Modems ist die fehlende Stummsschaltung der Datenübertragung an der seriellen Schnittstelle, wenn kein Träger im Stromnetz vorhanden ist. Das Modem sendet permanent Daten über die serielle Schnittstelle an den PC unabhängig davon, ob ein Träger anliegt oder nicht. Auch die Carrier-Detect-Signalisierung (CD) über die serielle Schnittstelle funktioniert nicht zuverlässig. Der Zeitpunkt des Einsetzens des CD-Signals stimmt nicht exakt mit dem Zeitpunkt eines Paketbeginns überein. Dadurch ist die softwareseitige Verwendung von Startbits bzw. Barkersequenzen notwendig. 59 4 POWERLINE-COMMUNICATION-CHIPSETS 4.2 Intellon Die Firma Intellon bietet mit dem INT5130 Chipsatz ein Hochgeschwindigkeitsmodem an, welches Datenraten bis zu 14 Mbit/s über die Stromleitung erlaubt. Die verwendete Modulationsart hierbei ist OFDM, welche sich dem gestörten Powerline-Kanal anpasst, um maximalen Durchsatz zu erzielen. Dieser Chipsatz wird in einem Evaluation-Kit für etwa 1000$ angeboten. Intellons Technologie ist kompatibel zur HomePlug-Spezifikation 1.0 der Powerline Alliance und unterstützt Quality-of-Service sowie eine 56-bit DES-Link-Verschlüsselung. MAC- und Physical-Layer sind bereits vollständig im Chipsatz integriert. Die PCI-Steckkarten des Evaluation-Kits basieren auf dem AMD79C972-Ethernet-Treiber und lassen sich praktisch wie gewöhnliche Netzwerkkarten betreiben. Neben einer umfangreichen Dokumentation wird auch ein Testprogramm mitgeliefert, um den Durchsatz einer Verbindung zu testen. Weitere Einzelheiten zum PowerPacket-Verfahren von Intellon, welches den Physical- und MAC-Layer reglementiert, ist Abschnitt 2.3.7 zu entnehmen. Ein funktionales Blockdiagramm findet sich in Abbildung 4.2. Bild 4.2: Funktionales Blockdiagramm des Chips INT5130 60 4 POWERLINE-COMMUNICATION-CHIPSETS Eine schematische Ansicht der Evaluationkarte ist in Abbildung 4.3 abgebildet. Bild 4.3: Blockschaltbild der EK5130-Evaluation-PCI-Karte 61 4 POWERLINE-COMMUNICATION-CHIPSETS 4.3 Echelon Der PLT-22 Powerline Transceiver von Echelon [10] folgt dem CENELEC Standard EN50065-1 und den FCC-Standard (siehe Abschnitt 2.3). Er bietet eine Datenrate von 5,4 kbit/ s bzw. 3,6 kbit/s im CENELEC-Band und verwendet zwei Trägerfrequenzen bei BPSK-Modulation. Die Trägerfrequenzen sind 132 und 115 kHz sowie 86 und 75 kHz. Bild 1.1 erläutert den Aufbau des PLT-22. Bild 4.4: Blockdiagramm des PLT-22 von Echelon 62 4 POWERLINE-COMMUNICATION-CHIPSETS 4.4 Adaptive Networks Adaptive Networks [6] bietet drei Powerline-Chipsets mit verschiedenen Datenübertragungsraten an: Der AN1000-Chipset erlaubt eine Datenrate von 100 kbit/s (Raw-Datenrate 268,8 kbit/s), der AN192-Chipset 19,2 kbit/s (Raw-Datenrate 134,4 kbit/s) und der AN48-Chipset 4,8 kbit/s (Raw-Datenrate 23,75 kbit/s). Alle Chipsets halten eine Bit-Error-Rate von < 10-9 ein, unterstützen bis zu 65534 Powerline-Stationen pro Netzwerk und verwenden SpreadSpectrum Technik. Weitere Eigenschaften sind Token Passing MAC-Layer und eine integrierte Forward Error Correction und Error Detection (FEC, Abschnitt 3.5). Das gemeinsame Blockdiagramm der Chipsets von Adaptive Networks ist in Bild 4.5 dargestellt. Bild 4.5: Gemeinsames Blockdiagramm der Chipsets von Adaptive Networks 63 4 POWERLINE-COMMUNICATION-CHIPSETS 4.5 Itran Communications Itran Communications [7] bietet das IT800 „SCP Ready“ Evaluation-Kit an. Ein EvaluationKit kostet 2500 US $ und beinhaltet zwei Evaluation Boards mit technischer Dokumentation und zugehöriger Software. Der IT800 moduliert die Signale mit DCSK (Differential Code Shift Keying) und verwendet Forward Error Correction (FEC). Die Aussendungen beschränken sich auf den Frequenzbereich 100-400 kHz nach den „USA FCC part 15 restrictions“. Sie können allerdings auch auf die europäischen CENELEC A-Frequenzen (20-80 kHz, Outdoor) und CENELEC B-Frequenzen (95-125 kHz, Indoor) angepasst werden (siehe Abschnitt 2.3). Die verfügbare Datenrate beträgt 7,5 kbit/s. Itrancomm bietet auch einen schnelleren Chip mit 2,5 Mbit/s an - den ITM1-B. Er arbeitet mit dem Adaptive Code Shift Keying (ACSK) Modulationsverfahren [8]. Ein Blockschaltbild wird in Bild 4.6 gezeigt. Bild 4.6: Blockdiagramm des ITM1-B von Itran Communications 64 4 POWERLINE-COMMUNICATION-CHIPSETS 4.6 Inari Inari’s Technologie [5] verspricht 2 Mbit/s (später auch 12 Mbit/s) mit Quality-of-Service Unterstützung für multimediale Anwendungen. Als 2 Mbit/s-Variante bietet Inari den Chip IPL0202 mit integriertem MAC/PHY-Controller an. Der IPL0202 ist über ein externes Powerline Frontend (PFE) mit der Energieversorgungsleitung verbunden. Siehe hierzu Abbildung 8.1. Das System wird gesteuert durch einen internen 8051-Mikrocontroller, der den Code aus einem externen ROM ausführt. Daten werden über Energieversorgungskabel mit Hilfe von vier modulierten Trägern in BPSK oder QPSK übertragen. Bild 4.7: Blockdiagramm des IPL0202 von Inari Von Inari wird ein Software Development Kit (SDK) angeboten, welches ein einfaches Application Programmer Interface (API) zur Verfügung stellt. Es erlaubt Entwicklern die schnelle Programmierung von PC-Anwendungen. Das Hardware Development Kit (HDK) besteht aus drei Boards konfiguriert als externe Powerline-Netzwerk-Adapter für PCs. Es beinhaltet weiterhin USB- und Parallelport-Treiber sowie Software für alle Windows-Betriebssysteme. Die HDKs kosten je nach Leistungsumfang 2000 US $ bzw. 3800 US $. 65 4 POWERLINE-COMMUNICATION-CHIPSETS 4.7 Cogency Cogency bietet den so genannten Piranha-Chipsatz mit ähnlicher Leistung an wie Intellon. Er verspricht Datenraten von bis zu 14 Mbit/s und benutzt das OFDM-Modulationsverfahren mit FEC, um eine verlässliche Datenübertragung zu gewährleisten. Die FEC arbeitet mit Faltungscodierung der Rate 1/2, die in guten Kanälen auf eine Rate von 3/4 punktiert werden kann. MAC- und Physical-Layer sind ebenfalls direkt im Chipsatz integriert. Die Kompatibilität zur HomePlug-Spezifikation v1.0 wird garantiert. Das funktionale Blockschaltbild findet sich in Abbildung 4.8 wieder. Bild 4.8: Funktionales Blockschaltbild des Piranha-Chipsatzes 66 4 POWERLINE-COMMUNICATION-CHIPSETS 4.8 Überblick der Anbieter Tabelle 4.1 gibt zusammenfassend wichtige technische Eckdaten der vorhin vorgestellten Chipsätze wieder. Tabelle 4.1: Vergleich heutiger Anbieter von Powerline-Modems Firma Chipsatz Modulation Datenrate Standard (siehe Abschnitt 2.3) EVKPreis Austria Micro Systeme AS5501/02 FSK 2,4 kbit/s CENELEC/ FCC ~400 Euro Echelon PLT-22 Dual carrier 3 kbit/s CENELEC Lizenzen Itran Communication IT800 DCSK 7,5 kbit/s CENELEC/ FCC 2500$ ITM1-B ACSK 2,5 Mbit/s AN48 SpreadSpectrum 4,8 kbit/s AN192 SpreadSpectrum 19,2 kbit/s AN1000 SpreadSpecttrum 100 kbit/s IPL0202 DBSK, DQPSK 2 Mbit/s Adaptive Networks Inari angekündigt 134,4-403,2 kHz 2000$/ 3800$ 12 Mbit/s Intellon INT5130 OFDM 14 Mbit/s HomePlug 1.0 Cogency Piranha OFDM 14 Mbit/s HomePlug 1.0 1000$ 67 5 PROGRAMMIERUNG DES PHY-LAYERS 5 Programmierung des PHY-Layers 5.1 Aufgabenstellung Im Rahmen des fächerübergreifenden Projektes „Chatroom over Powerline“ soll ein PhysicalLayer als Schnittstelle zwischen Powerline-Modem und MAC-Layer erstellt werden. Die Programmierung erfolgt unter MS Visual Studio 6.0 C++ als Konsolenanwendung. Der zu programmierende Physical Layer (siehe Kapitel 2.4.1) soll folgende Aufgaben erfüllen: • Anbindung an die serielle Schnittstelle des PCs • Anbindung an den MAC-Layer • Forward Error Correction mittels Faltungscodierung und Viteri-Algorithmus • Variable Codierungsrate durch Punktierung • Verifikation des Paket-Headers und der Payload durch Cyclic Redundancy Checksums • Rahmensynchronisation • Feststellen der Qualität der Verbindung Die verwendete Hardware sind Powerline-Modems der Firma Austria Mikro Systeme. Eine ausführliche Beschreibung dieser Modems befindet sich in Abschnitt 4.1. 68 5 PROGRAMMIERUNG DES PHY-LAYERS 5.2 Paketaufbau Die Pakete bestehen aus einem Header- und einem Payload-Abschnitt. Der Header besitzt eine feste Länge von 10 Byte. Er beginnt mit einer 2-Byte-langen Barkersequenz zur Feststellung des Paketbeginns aus dem laufenden Datenstrom. Im darauf folgenden Byte befindet sich die Information über die Punktierungsrate in den 3 höchstwertigsten Bit. In den restlichen 5 Bit wird die Längeninformation des Datenteils transportiert. Daraufhin folgt eine jeweils 2-Byte lange Ziel- und Absender-Adresse. Das nächste Byte beinhaltet MAC-Schicht relevante Informationen. Abgeschlossen wird der Header durch eine Headerprüfsumme der Länge 1 Byte und einem Terminierungsbyte, um einen definierten Endzustand im Viteri-Algorithmus zu erhalten. Die Länge der Payload ist variabel zwischen 7 und 131 Byte. Daten werden in Bytelängen von mindestens 4 Byte bis maximal 128 Byte transportiert, wobei die Datenlänge stets ein Vielfaches von 4 Byte betragen muss. Die restlichen 3 Byte der Payload entfallen auf die Prüfsumme der Daten sowie auf ein Terminierungsbyte. Eine anschauliche Darstellung des Paketschemas zeigt Abbildung 5.1. 32 Bit 8 16 Barkercode Source Address CRC8 P Length 32 Bit Source Address Destination Address Termination1 Data Bild 5.1: 24 MAC Data CRC16 Termination2 Paketschema Nach der Faltungscodierung mit der Coderate 1/2 beträgt die Länge des gesamten Paketes das Doppelte, wenn man von der Barkersequenz absieht, welche uncodiert bleibt. Dies ist in Abbildung 5.2 verdeutlicht. min. 32, max. 280 Byte 2 B Bild 5.2: 32-280 Byte 18 Header Payload Paketschema nach der Codierung (Rate: 1/2, unpunktiert) 69 5 PROGRAMMIERUNG DES PHY-LAYERS • Barkercode: Enthält eine 13 Bit lange Barkersequenz zur Rahmensynchronisation. Die 3 niederwertigsten Bit des 2. Byte werden mit Nullen aufgefüllt. • P: 3 Bit: Gibt die Punktierung an zur Dekodierung der Daten (Payload) • Length: 5 Bit: Übermittelt die Länge der Payload in einer linearen Schrittweite von 4 Byte. Es gibt 25 = 32 Möglichkeiten der Paketgröße bei einer minimalen Anzahl der Datenbytes von 4 Byte bis zu der maximalen Datenlänge von 25*4 = 128 Byte. • Source-/Destination Adress: Enthalten die eindeutigen Adressen für Sender und Empfänger. Auch Multicast- und Broadcast-Adressen für Destination-Adress sind möglich. • MAC: Beinhaltet 8 Kontroll-Bits für die MAC-Schicht • 1 Bit Retry Flag: Wird bei nochmaligem Senden des gleichen Pakets gesetzt, damit der Empfänger keine Duplikate erhält. • 7 Bit Reserved: frei zur zukünftigen Verwendung • CRC8: 8 Bit CRC über den Header (von Coderate bis MAC-CTRL) • Termination1: 8 vordefinierte Bits zur Terminierung der Codierung • Data: Enthält die Daten der KOM-Schicht. Die maximale Länge von 128 Bytes wird von der COM Schicht sichergestellt. • CRC16: 16 Bit CRC über die Datenbytes • Termination2: 8 vordefinierte Bits für den Abschluss Codierung der Payload. 5.3 Schnittstelle PHY-/MAC-Layer Die PHY-Schicht stellt dem MAC-Layer folgende Funktionen zur Verfügung: • int PHY_init(int comport) Wird von der MAC-Schicht einmalig aufgerufen bei Programmstart. Übergibt die Nummer des COM-Ports und ruft die Empfangsroutine der PHY-Schicht auf. • bool PHY_send(Header h, byte* payload, int size) a) Gibt den Header h und die Payload payload der Größe size an die PHY-Schicht zum Senden weiter. Anschließend liefert die Methode einen Fehlercode zurück, 0 bei fehlerfreier Ausführung. b) Synchron, d.h. die Methode blockiert, bis das Paket gesendet wurde. • boolean PHY_IsCarrier() Liefert true zurück, wenn der Bus belegt ist, ansonsten false. 70 5 PROGRAMMIERUNG DES PHY-LAYERS Umgekehrt hält die MAC-Schicht folgende Funktionen für die PHY-Schicht bereit: • int receive(Header* h, byte* payload, int *received) a) Empfängt Header h und die Payload payload von der PHY Schicht. Die Größe der Payload wird in received zurückgeliefert. Liefert aufgetretene Fehleranzahl zurück, -1 bei fehlerfreier Ausführung (inactivity), 0..n: Anzahl aufgetretener Fehler (ermöglicht Anpassung der Kodierungsparameter) b) Puffer wird von PHY Schicht allokiert. • void CarrierStateChange(boolean carrierstate) Wird von der PHY Schicht aufgerufen, wenn sich der Zustand des Carriersignals ändert. Übergibt true, wenn der Bus belegt ist, ansonsten false. Diese Funktionen befinden sich in derselben Bibliothek wie die Funktionen des MAC-Layers. 71 5 PROGRAMMIERUNG DES PHY-LAYERS 5.4 Die serielle Schnittstelle Die Programmierung der seriellen Schnittstelle in MS Visual C++ unter Windows erfordert die Kenntnis spezieller Funktionen. Empfehlenswert hierzu sind die Internetseiten des MSDN (Microsoft Developer Network) [17], speziell der Artikel “Serial Communication in Win32” [18]. Das Öffnen der seriellen Schnittstelle geschieht ähnlich dem Öffnen einer Datei mit der Funktion CreateFile(). Ebenso verhält es sich mit dem Schreiben bzw. Lesen der seriellen Schnittstelle. Man verwendet die Funktionen WriteFile() und ReadFile(). 5.4.1 Overlapped/Nonoverlapped Modus Grundsätzlich können alle Funktionen, die eine Aktion des Systems abwarten müssen, im Overlapped- oder Nonoverlapped-Modus aufgerufen werden: Der Nonoverlapped-Ansatz ist programmiertechnisch sehr einfach, hat aber gewisse Nachteile. Während der Abarbeitung eines Befehls, wie z. B. dem Schreiben auf die serielle Schnittstelle, wird der aufrufende Thread blockiert. Sobald die Funktion ausgeführt wurde, kehrt sie zum aufrufenden Thread zurück, der seine Arbeit dann fortführen kann. Diese Art, die Schnittstelle zu benutzen, ist nützlich bei Anwendungen mit mehreren Threads, weil während ein Thread aufgrund einer I/O-Operation blockiert ist, andere Threads weiterarbeiten können. Die Zugriffssteuerung auf die Schnittstelle muss in diesem Fall vom Programm selbst übernommen werden. Wenn ein Thread durch eine I/O-Operation blockiert ist, wird in allen anderen Threads die Ausführung von I/O-Operationen ebenfalls blockiert, bis die ursprüngliche Operation beendet ist. Zum Beispiel, wenn ein Thread auf die Beendigung der Funktion ReadFile() wartet, werden I/O-Operationen in allen anderen Threads blockiert. Der Overlapped-Ansatz ist etwas aufwendiger in der Programmierung, erlaubt aber größere Effizienz und Flexibilität. Ein für overlapped Operationen geöffneter Port erlaubt mehreren Threads zur gleichen Zeit I/O-Operationen auszuführen, ohne Threads zu blockieren. Darüber hinaus erlaubt er einem einzelnen Thread mehrere unterschiedliche Anfragen auszuführen und während der Abarbeitung Hintergrundarbeit zu leisten. Overlapped I/O-Operationen bestehen aus zwei Teilen: der Erstellung einer Operation und der Detektion ihrer Beendigung. Um die Operation durchzuführen, wird eine Overlapped-Structure, ein manual-reset Event zur Synchronisation sowie der Aufruf der entsprechenden Funktion (ReadFile(), WriteFile()) benötigt. Die Detektion der Beendigung einer I/O-Operation erfordert das Warten auf einen Event-Handle, die Überprüfung des Operationsergebnisses und die Verarbeitung der Daten. Der Grund, warum eine Overlapped-Operation mehr Programmieraufwand erfordert, liegt darin, dass es mehr Fehlerquellen geben kann. Wenn eine 72 5 PROGRAMMIERUNG DES PHY-LAYERS Nonoverlapped Operation fehlschlägt, gibt die Funktion einen Error-Code zurück. Wenn eine Overlapped-Funktion fehlschlägt, kann sich ein Fehler bei der Erstellung der Operation oder während der Ausführung ereignen. Ebenfalls sollte man beim Warten auf die Beendigung einer I/O-Operation Time-Out-Kriterien verwenden. In beiden Anwendungen, single-threaded als auch multi-threaded, muss eine Synchronisation zwischen den I/O-Operationen und der Verarbeitung der Daten stattfinden. Ein Thread muss blockiert werden bis ein Ergebnis der I/O-Operation verfügbar ist. Der Vorteil der overlappedOperationen liegt darin, dass der Thread zwischen dem Aufruf und der Beendigung der I/OOperation Hintergrundarbeit verrichten kann. Wenn man sich zwischen Nonoverlapped und Overlapped Modus entscheiden muss, sollte man bedenken, dass Overlapped-Operationen auf den meisten Betriebssystemen nicht unterstützt wird. In diesem Fall muss dem Nonoverlapped Modus unter Anwendung von Threads den Vorzug gegeben werden. 5.5 Multithreading Es gibt viele Situationen in einem Betriebssystem, die vorteilhaft geregelt werden können, wenn in einem Programm oder einem Prozess bestimmte Aktionen parallel ausgeführt werden können. Zu diesem Zweck verwendet man Multithreading. Ein Thread (Kontrollfaden, Abarbeitungsfaden) kann somit eine sequentiell abzuarbeitende Befehlsfolge innerhalb eines Programms oder Prozesses definieren. Man spricht von Multithreading, wenn innerhalb eines Programms zwei oder mehr nebenläufige Befehlsfolgen abgearbeitet werden. Ein derartiges Programm wird als "nebenläufig" bezeichnet. Für die Programmierung von Threads gibt es spezielle Befehle oder Bibliotheksfunktionen innerhalb einer Programmierumgebung. Bei Multithreading wird ein einzelnes Programm in mehrere Unterprogramme (= Threads) aufgeteilt, die sich gleichzeitig einen gemeinsamen Speicher teilen. Das Umschalten geschieht weitgehend automatisch durch das System. Multithreading bietet eine sehr feinkörnige Parallelität. Innerhalb eines Programms sind die Interaktionen zwischen Threads auch sehr viel intensiver als zwischen zwei völlig verschiedenen Programmen. Da die Programmentwickler den Überblick über das gesamte Programm haben, sind sie auch verantwortlich dafür, dass sich zwei Threads nicht gegenseitig beeinträchtigen. Ein Programm ist hierbei ein Prozess, jeder Prozess hat einen Hauptthread (primary thread) und jeder Hauptthread kann untergeordnete Threads starten, die wiederum auch Threads star- 73 5 PROGRAMMIERUNG DES PHY-LAYERS ten können. Windows teilt dabei jedem Thread Rechenzeit zu. Wenn diese Zeit verstrichen ist, wird dieser Thread angehalten und der nächste Thread wird ausgeführt. Dabei wechselt das Betriebsystem so schnell, dass der Anwender glaubt, die Programme laufen gleichzeitig ab. Vorteile von Threads: • Je mehr Prozesse/Threads eine Anwendung hat, desto mehr Rechenzeit bekommt die Anwendung vom Betriebsystem. • Es können mehrere Programme gleichzeitig ausgeführt werden (Multitasking). • Jedes Programm kann mehrere Arbeiten gleichzeitig ausführen. Einen Thread erzeugt man dadurch, dass man die Funktion CreateThread() aufruft. Sie ist folgendermaßen definiert: HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAdress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadID, ); Parameter: lpThreadAttributes Zeiger auf die Sicherheitsattribute für den Thread. Der Standardwert ist NULL. Damit wird der Thread mit dem gleichen Sicherheitsprofil wie die Anwendung erzeugt. Der Standardwert ist eigentlich zu bevorzugen. dwStackSize Stack-Größe, die für den neuen Thread bereitgestellt wird. Bei einer Angabe von 0 erhält der Thread die gleiche Stack-Größe wie der aufrufende Thread. lpStartAdress Hier wird die Adresse der Funktion angegeben, die der Thread beim Start aufrufen soll. lpParameter Zeiger auf eine 32-bit Parameter, der der Threadfunktion als Wert übergeben wird. dwCreationFlags Ein Flag zum Erzeugen des Threads. Dieses Flag kann einen von zwei Werten enthalten. Wenn man den Wert CREATE_SUSPENDED übergibt, wir der Thread in einem ange- 74 5 PROGRAMMIERUNG DES PHY-LAYERS haltenen Zustand erzeugt. Der Thread startet erst dann, wenn die Funktion ResumeThread() für den Thread aufgerufen wird. Übergibt man den Wert 0 (der Standardwert), beginnt der Thread die Ausführung in dem Moment, zu dem er erzeugt wird. lpThreadId Zeiger auf eine 32-bit Variable, in der die Thread ID gespeichert wird. Jeder Thread besitzt auch einen privaten Kontext, nämlich: • seinen Registerstatus, insbesondere den Programmcounter, • seinen Stack, • seine Thread-ID, • seine Priorität. 5.6 Synchronisation von Threads In dem Maße wie die Synchronisierungsmechanismen für Threads dafür ausgelegt sind, den Zugriff auf begrenzte Ressourcen zu steuern, sind sie auch dafür vorgesehen, unnötige Prozessorzeit in Threads zu unterbinden. Je mehr Threads gleichzeitig laufen, desto langsamer führt jeder einzelne Thread seine Aufgaben aus. Wenn ein Thread also nichts zu tun hat, blockiert man ihn, und belässt ihn im Leerlauf. Damit erhalten andere Threads mehr Prozessorzeit und laufen deshalb schneller, bis die Bedingungen erfüllt sind, dass der Thread im Leerlauf etwas zu tun bekommt. Aus diesem Grund verwendet man Ereignisse - um Threads den Leerlauf zu ermöglichen, bis die Bedingungen erfüllt sind, dass sie etwas zu tun bekommen. Die Ereignisse zur Synchronisation von Threads arbeiten nicht nach den Mechanismen der Ereigniswarteschlangen. Statt eine Nummer zu erhalten und dann darauf zu warten, dass diese Nummer an die Behandlungsroutine von Windows übergeben wird, sind Ereignisse der Thread-Synchronisierung eigentliche Objekte, die sich im Speicher befinden. Jeder Thread, der auf ein Ereignis warten muss, teilt dem Ereignis mit, dass er auf dessen Auslösung wartet, und nimmt dann einen Ruhezustand ein. Wird das Ereignis ausgelöst, geht ein Signal an jeden Thread, der dem Ereignis seinen Wartezustand bekannt gegeben hat. Die Threads nehmen die Verarbeitung genau an dem Punkt auf, wo sie dem Ereignis die Warteabsicht mitgeteilt haben. 75 5 PROGRAMMIERUNG DES PHY-LAYERS Die insgesamt vier Mechanismen zur Synchronisation von Threads sind: Critical Sections Mit Hilfe von kritischen Bereichen erreicht man einen wechselseitigen Ausschluss von Threads, sodass bestimmte Programmabschnitte immer nur von einem Thread ausgeführt werden können. Ein oder mehrere andere Threads, die den kritischen Bereich betreten wollen, müssen warten bis der Thread den kritischen Bereich wieder verlässt, wie in Abbildung 5.3 dargestellt. Bild 5.3: Critical Section Mutexe Mutexe haben wie die im vorigen Abschnitt besprochenen Critical Sections die Aufgabe, gegenseitigen Ausschluss (mutual exclusion) zu gewährleisten. Der Hauptunterschied zu den Critical Sections ist, dass Mutexe auch von Threads mehrerer Prozesse genutzt werden können. Semaphore Ein allgemeineres Konzept sind die so genannten Semaphoren (Signalmasten, Leuchttürme), die im Gegensatz zu Mutexen nicht nur die Zustände signaled und unsignaled einnehmen können, sondern beliebig viele (abzählbar viele). Es sind Zähler deren Werte erhöht oder herabgezählt werden je nachdem welche Operation auf einen Semaphor einwirkt. Ist der interne Zähler NULL muss ein Thread warten, wenn er mit seiner Operation den internen Zähler herabsetzen will. Ereignisse Events (Ereignisse) sind eine sehr einfache Form von Synchronisationsobjekten. Sie dienen der Information über den Abschluss einer Operation. Die Art der Operation oder des Ereignis- 76 5 PROGRAMMIERUNG DES PHY-LAYERS ses kann dabei beliebig sein, denn ein Event kann nur explizit von einem Programm ausgelöst, d. h. das entsprechende Objekt in den “signaled State” versetzt werden. Bild 5.4: Ereignisse Ein Ereignis kann in Windows NT zwei Zustände besitzen. • signalisierend: Dieser Zustand bedeutet, dass ein Thread, der eine Anfrage stellt eine Antwort erhält und so der anfragende Thread sein Programm weiter ausführen kann. • nicht signalisierend: dieser Zustand bedeutet, dass ein Thread, der eine Anfrage stellt keine Antwort erhält und so der anfragende Thread blockiert bis das das Ereignis in den Zustand signalisierend wechselt. Bei der Synchronisation mit Hilfe von Ereignissen muss man als erstes einen so genannten Ereignis-Handler erstellen. Dies geschieht durch die Funktion CreateEvent(), welche auch bei der Programmierung der seriellen Schnittstelle verwendet wurde: HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName ); Parameter: lpEventAttributes Ein Pointer auf SECURITY_ATTRIBUTES-Struktur. NULL kann eingesetzt werden wenn keine Sicherheitsaspekte berücksichtigt werden müssen. 77 5 PROGRAMMIERUNG DES PHY-LAYERS bManualReset Der Parameter bManualReset legt fest, um welche von zwei verschiedenen Arten von Event-Objekten es sich handeln soll: TRUE = Auto-Reset, FALSE = Manual-Reset bInitialState Diese Flag gibt den Anfangsstatus des Ereignisses an: TRUE = signalisierend, FALSE = nicht signalisierend. lpName Hier kann dem Ereignis ein Namen geben werden, damit auch andere Prozesse mit diesem Ereignis arbeiten können. Man muss allerdings beachten, dass der verwendete Name nicht bereits vergeben ist. Ereignisse, Mutex und Datei-Mapping-Objekte verwenden dabei denselben Namensbereich. Ist dieser Wert NULL so kann das Ereignis nur innerhalb des Prozesses verwendet werden. Als Rückgabewert dieser Funktion erhält man einen Handle auf das Ereignis oder NULL falls ein Fehler aufgetreten ist. Bei einem Manual-Reset Event werden alle wartenden Threads geweckt, und das Event-Objekt bleibt im Signalled State, bis es explizit - eben manuell - wieder in den Nonsignalled State versetzt wird. Dagegen verhält sich ein Auto-Reset Event ähnlich wie ein Mutex: geht das Objekt in den Signalled State, so wird ein Thread, der auf das Objekt wartet, geweckt, und das Event-Objekt wird automatisch wieder in den Nonsignalled State zurückgesetzt. Wenn im Moment kein Thread auf das Auto-Reset Event wartet, so bleibt dieses im Signalled State, bis ein Thread eine Wartefunktion für es beendet, und wird dann automatisch wieder in den Nonsignalled State gesetzt. Welche Art von Event-Objekt benötigt wird, hängt ganz von der Logik der Applikation ab. Ein Synchronisationsobjekt befindet sich zu jedem Zeitpunkt in einem von zwei Zuständen: • Signalled State • Nonsignalled State Die Bedeutung dieser beiden Zustände ist vom Typ des Objektes abhängig. Die Gemeinsamkeit ist, dass ein Thread mit Hilfe der Wait Services des Objektmanagers darauf warten kann, dass ein Objekt in den Signalled State übergeht. Solange das Objekt im Nonsignalled State ist, ist der Thread blockiert. Sobald das Objekt in den Signalled State übergeht, weckt das Betriebssystem einen oder alle (je nach Typ des Objekts) auf dieses Objekt wartenden Threads auf. 78 5 PROGRAMMIERUNG DES PHY-LAYERS 5.7 Eventgesteuerte Threads Um eine reibungslose Kommunikation über die serielle Schnittstelle zu gewährleisten, verwendet das Programm zwei Threads - einen für den Empfang und einen für die Aussendung von Paketen. Diese nebenläufige Programmierung bietet eine ständige Empfangsbereitschaft bei gleichzeitiger Bereitschaft zur Aussendung von Paketen. Damit eine versehentliche Aussendung während des Empfangs eines Paketes ausgeschlossen wird, verwenden die beiden Threads Events. Durch Events wird der nebenläufige Programmablauf von Threads geregelt. In Abbildung 5.5 und 5.6 werden Ablaufdiagramme des Sende- und Empfangsthreads dargestellt. Der Sendethread stellt hierbei den von Anfang an vorhandenen Hauptthread dar. Er startet in der Routine PHY_Init() den Empfangsthread und übernimmt anschließend selbst die Funktion des Sendethreads. Zur Synchronisation der Kommunikation in den Threads werden insgesamt fünf Events definiert. • EventSendRoutineStart: Signalisiert den Aufruf der Sende-Routine • EventSendRoutineEnd: Signalisiert die Beendigung der Sende-Routine • EventCarrierDetect: Signalisiert wenn das Carrier-Detect-Signal anliegt • EventReceive: Signalisiert das Ende des Lesens von der seriellen Schnittstelle • EventSend: Signalisiert das Ende des Schreibens in die serielle Schnittstelle 79 5 PROGRAMMIERUNG DES PHY-LAYERS Beginn Sendethread Receive Thread Starte Receive-Thread Warte auf Sendebefehl Set Event SendRoutineStart Sende Paket Warte auf Sende-Ende Set Event SendRoutineEnd Bild 5.5: Ablaufdiagramm des Haupt- bzw. Sendethreads Die Events zur Signalisierung des Starts und des Endes der Sende-Routine sowie das CarrierDetect-Event werden durch das Programm gesetzt bzw. zurückgesetzt. Bei den Events EventSend und EventReceive handelt es sich um Events, welche nach der Ausführung der Funktionen WriteFile() und ReadFile() automatisch gesetzt und zurückgesetzt werden. Diese Events sind eine Folge der Programmierung der seriellen Schnittstelle im Overlapped-Modus (siehe Kapitel 5.4.1). 80 5 PROGRAMMIERUNG DES PHY-LAYERS Aufruf von Send-Thread Warte auf CD oder SendRoutineStart Welches Event? CD-Event SendRoutine-Event Reset Event Reset SendRoutineStart CD Lese Bild 5.6: Paket Warte auf SendRoutineEnd Warte auf Lese-Ende Reset SendRoutineEnd Ablaufdiagramm des Empfangsthreads Der Aufruf des Empfangsthreads erfolgt durch den Hauptthread. Der Empfangsthread wartet auf zwei Ereignisse. Wenn ein Träger signalisiert wird, liest er das ankommende Paket, decodiert, überprüft und leitet es an die MAC-Schicht weiter. Falls ein zu sendendes Paket signalisiert wird, wartet die Routine solange bis der Sendevorgang abgeschlossen ist und beginnt von vorne. 81 5 PROGRAMMIERUNG DES PHY-LAYERS 5.8 Programmbeschreibung Die Funktionen des Physical-Layers können auf zwei verschiedene Arten genutzt werden. Die erste Nutzungungsmöglichkeit ist in Zusammenarbeit mit dem MAC-Layer. Der MAC-Layer ruft die Funktionen des Physical-Layers eigenständig auf bzw. wird durch Funktionen des Physical-Layers benachrichtigt, z. B. wenn ein neues Datenpaket empfangen wird. Zu Test- und Demonstrationszwecken kann der Physical-Layer auch als eigenständig angesprochen werden. Hierzu ist der Aufruf der Routine main() notwendig. Das Programm kommuniziert mit dem Benutzer über die Kommandozeilen-Konsole. Beim Start bietet es in einem Hauptmenü verschiedene Möglichkeiten, die Datenübertragungsstrecke zu testen: • Chatmodus • Monitormodus • Test-Sendemodus • Test-Empfangsmodus Im Chatmodus wird dem Benutzer die Möglichkeit gegeben, mit Benutzern anderer Terminals zu chatten. Es wird keine Information über die Kanalgüte und keine Fehlerstastatistik der Pakete angezeigt. Im Monitormodus können ähnlich wie im Chatmodus Zeichenketten versendet werden. Beim Absenden einer Nachricht werden zusätzliche Informationen wie Checksummen, Header sowie Datenblock in hexadezimaler Schreibweise vor und nach der Faltungscodierung und die Länge des Paketes in Bytes wiedergegeben. Gleiches gilt auch für den Fall eines empfangenen Paketes. Hier werden jedoch zusätzlich noch das original empfangene Paket und eventuelle Fehler angezeigt. Angezeigte Fehler können sein: • Checksummenfehler im Header oder Datenblock • Paket, welches die Mindestpaketlänge unterschreitet oder Maximallänge überschreitet • Fehlgeschlagene Rahmensynchronisation Die Testmodi liefern eine ausführliche Fehlerstatistik über eine Vielzahl von Paketen, um die Störungen eines Kanals und die Codierung beurteilen zu können. Ein solcher Test wird durchgeführt, indem genau eine Station in den Test-Sendemodus versetzt wird und alle anderen verbundenen Stationen in den Test-Empfangsmodus versetzt werden. Im Sendemodus kann eine bestimmte Anzahl von Paketen festgelegt werden, die zu Testzwecken ausgesendet werden sollen. Die Länge und Punktierung der Pakete ist dabei stufenweise frei wählbar. Die gleichen Angaben müssen auch empfangsseitig eingestellt werden, damit dem Empfänger die Pakete 82 5 PROGRAMMIERUNG DES PHY-LAYERS vorher bekannt sind und er eine genaue Fehlerstatistik erstellen kann. Auf der Sendeseite wird die zu testende Rohbitfehlerrate eingegeben. Die Fehlerstatistik besteht aus: • Rohbitfehlerrate • Innere Bitfehlerrate • Checksummen-Fehler im Header und Datenblock • Paketlängenfehler • Rahmensynchronisationsfehler • Anzahl der empfangenen Pakete • Anzahl der empfangenen Bytes Messergebnisse über den Zusammenhang der Rohbitfehlerrate mit der inneren Bitfehlerrate bei verschiedenen Punktierungen können dem Abschnitt 5.9 entnommen werden. 83 5 PROGRAMMIERUNG DES PHY-LAYERS 5.9 Test der Bitfehlerrate Um die Bitfehlerrate des Powerline-Übertragungssystems zu messen, wurde der Versuchsaufbau aus Abbildung 5.7 nachgebaut. Rauschgenerator Leistungsmesser PLCModem Bild 5.7: PLCModem Versuchsaufbau zur Messung der Bitfehlerwahrscheinlichkeit Mit dem Rauschgenerator sollte das Signal-Stör-Verhältnis auf der Übertragungsstrecke derart verändert werden, dass es durch Fehlentscheidungen in den PLC-Modems zu Bitfehlern kommt. Der Leistungsmesser diente der Bestimmung des Signal-Stör-Verhältnisses. Wurde der Rauschanteil erhöht, kam es ab einem Schwellwert (Störleistungsdichte 2 mW/kHz, Signal 4 dB) zu nicht erkannten Paketen auf der Empfangsseite. Der Empfänger konnte keine Barkersequenz zur Rahmensynchronisation finden und lieferte somit keine Pakete zur Ermittlung der Bitfehlerwahrscheinlichkeit. Die Pakete, die empfangsseitig synchronisiert werden konnten, wiesen jedoch keine Rohbitfehler auf. In einem zweiten Versuch wurden die PLC-Modems nur durch eine Zweidrahtleitung miteinander verbunden. Die Bitfehler wurden auf der Empfangsseite durch die Software hinzugefügt. Die Roh-Bitfehlerrate konnte als Parameter dem Physical-Layer vorgegeben werden, um die Auswirkungen auf die innere Bitfehlerrate zu beobachten. Mit dieser Methode wurden mehrere Messreihen mit verschiedenartig punktierten Faltungscodes durchgeführt. Die Faltungscodierung hatte folgende Eigenschaften: • Rate 1/2 • Generatoren (133, 171) • Einflusslänge 7 Die verwendeten Punktierungen können in Abschnitt 3.1.7 nachgeschlagen werden. Die Ergebnisse dieser Messungen gibt Abbildung 5.8 wieder. 84 5 PROGRAMMIERUNG DES PHY-LAYERS Bild 5.8: Messung der Bit-Error-Rate in Abhängigkeit vom Signal-Stör-Verhältnis Die BER (Bit Error Rate) gibt die innere Bitfehlerrate wieder und das Signal-Stör-Verhältnis entspricht der Roh-Bitfehlerrate. Die Umrechnung der Roh-Bitfehlerrate in das SNR erfolgte mit Hilfe des gaußschen Fehlerintegrals unter Matlab. Deutlich zu erkennen ist die niedrigere Bitfehlerrate (BER) des unpunktierten Codes gegenüber den punktierten Codes. Die Bitfehlerraten der punktierten Codes liegen relativ dicht beieinander, so dass man für die Datenübertragung besser unterschiedlichere Punktierungsraten auswählt. Die Kurven entsprechen im Wesentlichen dem Verhalten von Faltungscodes, wie es der Literatur beschrieben ist [3], [30]. Bei der Messung der inneren Bitfehlerrate wurde bei großen Roh-Bitfehlerraten 400 Pakete maximaler Länge ausgesendet und bei sehr kleinen Roh-Bitfehlerraten bis zu 40000 Pakete maximaler Länge. Dadurch wurde sichergestellt, dass genügend innere Bitfehler (>200) auftreten, um die innere Bitfehlerrate auch bei einer sehr kleinen Roh-Bitfehlerrate zuverlässig zu messen. 85 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10 Übersicht der Funktionen Die folgenden Funktionen stellen einen Physical-Layer bereit. Seine Funktionalität umfasst FEC mittels Faltungscodierung und Viteri-Decodierung, Prüfsummenberechnung, Paketaufbau, Carrier-Detect, Rahmensynchronisation, Sende- und Empfangssteuerung, Errorhandling und Bitfehlermessung. 5.10.1 CRC8( ) Diese Funktion berechnet die 8-Bit-Prüfsumme über die Headerdaten und liefert sie zurück. unsigned char CRC8( unsigned char pointer indata, ); Parameter: indata Ein Pointer auf die Daten, über welche der CRC berechnet werden soll. In der Regel sollten diese Daten auf den Header des Pakets zeigen. Rückgabewert: 8-Bit-Prüfsumme der Headerdaten. Bemerkungen: Die Angabe der Länge der Daten erübrigt sich bei dieser Funktion, da die Länge des Headers konstant ist. Das Schieberegister wird mit Einsen initialisiert. 86 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.2 CRC16( ) Diese Funktion berechnet die 16-Bit-Prüfsumme über die Nutzdaten und liefert sie zurück. unsigned short CRC16( unsigned char pointer indata, int datalen, ); Parameter: indata Ein Pointer auf die Daten, über welche der CRC berechnet werden soll. In der Regel sollten diese Daten auf die Nutzdaten des Pakets zeigen. datalen Länge der Nutzdaten in Byte. Rückgabewert: 16-Bit-Prüfsumme der Headerdaten. Bemerkungen: Diese Routine arbeitet nach dem Standard CRC-16 der CCITT und verhält sich normgerecht. Überprüft wurde diese Routine durch die Zeichenkette „123456789“ mit anschließenden 16 Nullbits. Der resultierende CRC-Wert entspricht dem in [35] genannten Wert 0xE5CC. Das Schieberegister wird mit Einsen initialisiert. 87 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.3 FrameSync( ) Diese Funktion findet anhand einer definierten Barkersequenz den Beginn des gesendeten Datenpakets. Die per Pointer übergebenen Daten werden derart verschoben, dass der Pointer auf das erste Byte des gesendeten Datenpakets zeigt. bool FrameSync( unsigned char pointer data, int datal, ); Parameter: data Ein Pointer auf die Empfangsdaten, welche ein Paket enthalten. datal Länge der Empfangsdaten in Byte. Rückgabewert: TRUE, falls Paketanfang gefunden wurde. FALSE, falls Barkersequenz nicht ermittelt werden konnte oder die Paketlänge die Mindestlänge unterschreitet. Bemerkungen: FrameSync() korrigiert dabei nicht nur byteverschobene Daten, sondern auch bitverschobene Daten. 88 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.4 Encode( ) Diese Funktion faltungscodiert die übergebenen Daten. void Encode( unsigned char pointer indata, unsigned char pointer outdata, int length ); Parameter: indata Ein Pointer auf die zu codierenden Daten. outdata Ein Pointer auf die codiererten Daten der Funktion. length Länge der zu codierenden Daten in Byte. Rückgabewert: kein Rückgabewert Bemerkungen: Diese Funktion gibt nicht die neue Länge der codierten Daten zurück, da sie leicht aus der Coderate zu berechnen ist. Die verwendeten Generatoren sind in oktaler Schreibweise (133, 171) bei einer Einflusslänge von 7. Der Codierer hat somit die Rate 1/2. 89 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.5 Puncture( ) Diese Funktion punktiert die codierten Daten. bool Puncture( unsigned char pointer data, int pointer datalen, int mode, ); Parameter: data Ein Pointer auf die codierten Daten, die punktiert werden sollen. datalen Länge der zu punktierenden codierten Daten in Byte. Rückgabewert: TRUE Bemerkungen: Diese Funktion benutzt folgende Punktierungen: Tabelle 5.1: Verwendete Punktierungs-Schemata, [20], [30] Originalcode R = 5/6 R = 6/7 R = 7/8 m g(1), g(2) P d free , A dfree , B dfree P d free , A d free , B d free P d free , A dfree , B dfree 6 133, 171 11010 10101 4, 14, 92 111010 100101 3, 1, 5 1111010 1000101 3, 2, 9 = freie Distanz A dfree = Anzahl von Sequenzen bei der Mindestdistanz d free B dfree = Koeffizient zur Abschätzung der Bitfehlerwahrscheinlichkeit 90 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.6 Decode( ) Diese Funktion decodiert die codierten und eventuell auch punktierten Daten. void Decode( unsigned char pointer indata, unsigned char pointer outdata, int length, int mode ); Parameter: indata Ein Pointer auf die codierten und eventuell auch punktierten Daten. outdata Ein Pointer auf die decodierten Daten. length Länge der decodierten Daten in Byte. mode Gibt die Art der Punktierung an. 0 - keine 1 - Rate 5/6 2 - Rate 6/7 3 - Rate 7/8 Rückgabewert: kein Rückgabewert Bemerkungen: Vor dem ersten Aufruf von Decode() muss einmalig die Routine GenerateTrellis() aufgerufen werden, um die benötigten Trellisdaten zur Verfügung zu haben. 91 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.7 GenerateTrellis( ) Generiert die Trellisdatenstruktur insbesondere die Codewörter. void GenerateTrellis( void ); Parameter: keine Rückgabewert: kein Rückgabewert Bemerkungen: Wird nur einmal zum Programmstart aufgerufen und ist Vorraussetzung für die Routine Decode(). Die generierten Daten befinden sich in globalen Variablen, damit keine Argumente übergeben werden müssen. 92 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.8 Distance( ) Diese Funktion gibt die Hamming-Distanz zwischen Codewort a und b unter Berücksichtigung der Punktierung zurück. int Distance( unsigned char a, unsigned char b, unsigned char puncmask ); Parameter: a Erstes Codewort zur Distanzberechnung. b Zweites Codewort zur Distanzberechnung. puncmask Gibt an, welche Bits der Codewörter gewichtet werden sollen. Punkmask ist ein Ausschnitt aus der Punktierungsmaske. Eine Eins bedeutet, dass ein Bit an dieser Stelle des Codeworts gewichtet wird. Eine Null bedeutet, dass ein Bit an dieser Stelle des Codeworts nicht gewichtet wird. Rückgabewert: Rückgabewerte ist die Hamming-Distanz zwischen Codewort a und b unter Berücksichtigung der Punktierung. Bemerkungen: 93 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.9 Compare( ) Diese Funktion vergleicht bitweise zwei Bytefolgen und gibt die Anzahl der unterschiedlichen Bits zurück. int Compare( unsigned char a, unsigned char b, int length ); Parameter: a Erste zu vergleichende Bytefolge. b Zweite zu vergleichende Bytefolge. length Gibt die Länge der Bytefolge in Bytes an. Rückgabewert: Rückgabewerte ist die Anzahl Bits, in denen sich die beiden Bytefolgen unterscheiden. Bemerkungen: 94 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.10AddErrors( ) Diese Funktion generiert in eine Bytefolge Bitfehler nach einer vorgegebenen Bitfehlerwahrscheinlichkeit. int AddErrors( unsigned char a, int length, double error_rate ); Parameter: a Bytefolge, der Bitfehler hinzugefügt werden soll. length Länge der Bytefolge in Bytes. error_rate Gibt die Bitfehlerrate an. [0..1] Rückgabewert: Rückgabewerte ist die Anzahl der Bitfehler, die tatsächlich hinzugefügt wurden. Bemerkungen: 95 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.11OpenComPort( ) Diese Funktion öffnet die angegebene serielle Schnittstelle. void OpenComPort( int comport ); Parameter: comport Nummer der seriellen Schnittstelle, an der das Modem angeschlossen ist. Mögliche Werte sind [1, 2]. Rückgabewert: kein Rückgabewert Bemerkungen: 96 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.12PHY_Init( ) Diese Funktion wird als Initialisierungs-Routine vom MAC-Layer aufgerufen. Der MAC-Layer übergibt dabei den Port der seriellen Schnittstelle. void PHY_Init( int comport ); Parameter: comport Nummer der seriellen Schnittstelle, an der das Modem angeschlossen ist. Mögliche Werte sind [1, 2]. Rückgabewert: kein Rückgabewert Bemerkungen: Zu Beginn öffnet diese Funktion die serielle Schnittstelle, generiert die für die Decodierung erforderlichen Trellisdaten und initialisiert den Zufallsprozess für den Viterbi-Algorithmus mit der aktuellen Systemzeit des Rechners. Der Zufallsprozess wird benötigt für den Fall, dass an einen Knoten des Trellisdiagramms zwei Pfade gleicher Metrik reichen. PHY_Init() stellt somit den Hauptthread dar, der anschließend den Empfangsthread durch den Aufruf der Funktion PHY_Receive() startet. PHY_Init() endet zu Demonstrationszwecken in einer Warteschleife, welche auf Sendepakete von der Funktion KeyboardInput() wartet. Diese Warteschleife ist beim Einsatz der PHY-Funktionen durch den MACLayer überflüssig, da dieser eigenständig die Sende Pakete an die Funktion PHY_Send() übermittelt. Ein Ablaufdiagramm von PHY_Init findet sich in Abbildung 5.9. 97 5 PROGRAMMIERUNG DES PHY-LAYERS Beginn PHY_Init Öffne COM-Port Generiere Trellisdaten Initialisiere Zufallsgenerator Starte Empfangsthread Lese Sendedaten Starte Sende-Routine nur zur Demonstration Bild 5.9: Ablaufdiagramm der Funktion PHY_Init() 98 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.13PHY_Receive( ) Diese Funktion stellt den Empfangsthread dar. Er wartet auf empfangene Pakete, decodiert, überprüft und leitet sie an die MAC-Schicht weiter. unsigned long _stdcall PHY_Receive( void* pdata ); Parameter: pData Pointer-Dummy. Rückgabewert: kein Rückgabewert Bemerkungen: PHY_Receive wird durch die Routine PHY_Init als Empfangsthread aufgerufen. Er mündet in eine Warteschleife, die auf die Ereignisse CarrierDetect oder StartRoutine wartet. Die Synchronisation des Empfangsthreads mit dem Sendethread mittels Events wird in Kapitel 5.7 ausführlich behandelt. Abbildung 5.10 zeigt ein Ablaufdiagramm der Funktion PHY_Receive. Nach dem Empfang eines Paketes erfolgt zuerst eine Validierung bezüglich der Paketlänge. Darauf folgt die Rahmensynchronisation durch die Erkennung eines Barkercodes. Nachdem der Paketanfang bekannt ist, wird der Header decodiert und mit Hilfe der Header-Checksumme überprüft. Gleiches geschieht anschließend mit dem Datenteil. Wenn alle Validierungen positiv verlaufen sind, wird das decodierte Paket an den MAC-Layer weitergereicht und die Routine wartet auf das nächste Paket. 99 5 PROGRAMMIERUNG DES PHY-LAYERS Warte auf CD nein CD-ON Mitteilung an MAC Framesynchronisierung Lösche Empfangsbuffer OK? Lese Paket ja Decodierung Data nein Data CRC-Check ja Warte auf Lese-Ende Decodierung Header OK? nein nein ja ja CD-OFF Mitteilung an MAC Header CRC-Check Paketlänge OK? OK? Paketübergabe an MAC Bild 5.10: Ablaufdiagramm der Funktion PHY_Receive() 100 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.14PHY_Send( ) Diese Funktion stellt den Sendethread dar. Er wartet auf die Sendeaufforderung durch den MAC-Layer bzw. durch den User, codiert die Daten und sendet das Paket aus. void PHY_Send( unsigned char* wheader unsigned char* wdata ); Parameter: wheader Pointer auf die zu sendenden Headerbytes ohne Barkercode, Terminierung und Checksumme. Die Länge der Headerdaten beträgt 5 Bytes. Das erste Byte gibt die Datenlänge und die Punktierung an. Danach folgen jeweils 2 Bytes für die Absender- und Zieladresse. Eine ausführliche Beschreibung des Paketaufbaus findet sich in Kapitel 5.2. wdata Pointer auf die zu sendenden Datenbytes ohne Terminierung und Checksumme. Die maximale Länge der Sendedaten wird durch die Konstante RECEIVELEN zu Programmbeginn festgelegt. Rückgabewert: kein Rückgabewert Bemerkungen: Die Hauptaufgabe der Funktion PHY_Send ist es, die übergebenen Daten mit einer Prüfsumme zu versehen und zu encodieren. Nachdem die Information fehlergesichert in ein Paket gepackt wurde, wird sie ausgesendet. Die Funktion PHY_Send wird nebenläufig zur Funktion PHY_Receive ausgeführt. Die Synchronisation des Empfangsthreads mit dem Sendethread mittels Events wird in Kapitel 5.7 ausführlich behandelt. Abbildung 5.10 zeigt ein Ablaufdiagramm der Funktion PHY_Send. 101 5 PROGRAMMIERUNG DES PHY-LAYERS Warte Sendepaket Füge Barkercode an Encodiere Data Berechne/füge an Header-CRC Punktiere Data Terminierung an Header Lösche Sendebuffer Encodiere Header Sende Paket Berechne/füge an Data-CRC Warte auf Sende-Ende Terminierung an Data Bild 5.11: Ablaufdiagramm der Funktion PHY_Send() 102 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.15PHY_IsCarrier( ) Mit Hilfe dieser Funktion kann der MAC-Layer feststellen, ob derzeit ein Träger detektiert wurde. bool PHY_IsCarrier( ); Parameter: keine Rückgabewert: Der Rückgabewert ist Eins bei detektiertem Träger und Null, wenn kein Träger erkannt wurde. Bemerkungen: keine 103 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.16PHY_TestReceive( ) Diese Funktion stellt den Empfangsthread für den Test der Bitfehlerraten dar. Er wartet auf empfangene Pakete, decodiert, überprüft und zählt die Bitfehler. Am Ende eines Testdurchlaufs wird eine Fehlerstatistik erzeugt, die folgende Angeaben enthält: • Roh-Bitfehlerrate • innere Bitfehlerrate • Fehlerhafte Pakete (CRC-Fehler, Synchronisationsfehler, zu kurze Pakete) • Anzahl der empfangenen Roh- und Nutzdaten Im Test-Empfangsmodus muss die gleiche Paketlänge und Punktierung angegeben werden wie auf der Sendeseite, damit dem Empfänger die ausgesendeten Pakete bekannt sind. unsigned long _stdcall PHY_TestReceive( void* pdata ); Parameter: pdata Zeiger-Dummy. Rückgabewert: kein Rückgabewert Bemerkungen: PHY_Receive wird durch die Routine PHY_Init als Empfangsthread aufgerufen. Er mündet in eine Warteschleife, die Ereignisse CarrierDetect oder StartRoutine wartet. Die Synchronisation des Empfangsthreads mit dem Sendethread mittels Events wird in Kapitel 5.7 ausführlich behandelt. 104 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.17PHY_TestSend( ) Diese Funktion stellt den Sendethread zum Test der inneren Bitfehlerrate dar. Er fragt nach einer Anzahl von Paketen, die zu Testzwecken ausgesendet werden soll. Weitere Angaben beeinflussen die Paketlänge und Punktierung. Die Angaben müssen mit denen im Empfangsmodus auf der Empfangsseite übereinstimmen, damit dem Empfänger die ausgesendeten Pakete bekannt sind und eine zuverlässige Fehlerstatistik aufstellen kann. void PHY_TestSend( unsigned char* wheader unsigned char* wdata ); Parameter: wheader Pointer auf die zu sendenden Headerbytes ohne Barkercode, Terminierung und Checksumme. Die Länge der Headerdaten beträgt 5 Bytes. Das erste Byte gibt die Datenlänge und die Punktierung an. Danach folgen jeweils 2 Bytes für die Absender- und Zieladresse. Eine ausführliche Beschreibung des Paketaufbaus findet sich in Kapitel 5.2. wdata Pointer auf die zu sendenden Datenbytes ohne Terminierung und Checksumme. Die maximale Länge der Sendedaten wird durch die Konstante RECEIVELEN zu Programmbeginn festgelegt. Rückgabewert: kein Rückgabewert Bemerkungen: Die Hauptaufgabe der Funktion PHY_Send ist es, die übergebenen Daten mit einer Prüfsumme zu versehen und zu encodieren. Nachdem die Information fehlergesichert in ein Paket gepackt wurde, wird sie ausgesendet. Die Funktion PHY_Send wird nebenläufig zur Funktion PHY_Receive ausgeführt. Die Synchronisation des Empfangsthreads mit dem Sendethread mittels Events wird in Kapitel 5.7 ausführlich behandelt. 105 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.18MAC_CarrierStateChange( ) Mit Hilfe dieser Funktion kann der MAC-Layer feststellen, ob derzeit ein Träger detektiert wurde. bool MAC_CarrierStateChange( bool carrierstate ); Parameter: carrierstate Dieser Parameter ist Eins, wenn ein Träger detektiert wird und Null wenn kein Träger anliegt. Rückgabewert: keiner Bemerkungen: Mit dieser Funktion teilt der Physical-Layer dem MAC-Layer aktiv mit, dass ein Trägerwechsel erfolgt. Normalerweise wird MAC_CarrierStateChange() vom MAC-Layer bereitgestellt und ist hier nur zu Demonstrationszwecken als Dummy-Funktion implementiert. 106 5 PROGRAMMIERUNG DES PHY-LAYERS 5.10.19MAC_Receive( ) Durch den Aufruf dieser Funktion wird das empfangene Paket an den MAC-Layer weitergeleitet. void MAC_Receive( unsigned char* header unsigned char* data ); Parameter: header Pointer auf die decodierten Header-Daten des empfangenen Paketes. Die Headerlänge beträgt 5 Bytes. Der Header wird ohne Barkersequenz, Terminierung und Prüfsumme übergeben. data Pointer auf die decodierten Payload-Daten des empfangenen Paketes. Die Information über die Datenlänge der Payload ergibt sich aus dem ersten Byte der Headerdaten. Die Payloaddaten werden ohne Terminierung und Prüfsumme übergeben. Rückgabewert: keiner Bemerkungen: Mit dieser Funktion übergibt der Physical-Layer dem MAC-Layer das empfangene und decodierte Paket. Normalerweise wird MAC_Receive() vom MAC-Layer bereitgestellt und ist hier nur zu Demonstrationszwecken als Dummy-Funktion implementiert. 107 6 AUSBLICK 6 Ausblick Um einen Ausblick zu geben, wie das Projekt „Chatroom over Powerline“ fortgeführt werden kann, wird im folgenden Abschnitt eine mögliche Realisierung eines Powerline-Modems vorgestellt. 6.1 Mögliche Realisierung eines Powerline-Modems Am Lehrstuhl für Nachrichtentechnik der Universität Kaiserslautern laufen derzeit mehrere Arbeiten zu einer OFDM-basierten Kommunikation über die Powerline. Die OFDM-Übertragungstechnik wird heutzutage in vielen Broadcastanwendungen wie beispielsweise im digitalen terrestrischen Hörfunk DAB (Digital Audio Broadcasting) und im digitalen Fernsehen DVB-T (Digital Terrestrial Video Broadcasting) verwendet. Auch für Kommunikationsanwendungen wie die Nachfolgegeneration UMTS (Universal Mobile Telecommunication System) wird OFDM als Übertragungsverfahren diskutiert. Die Powerline stellt daher nur ein Medium unter vielen dar, für das ein OFDM-System entwickelt wird. Im Folgenden soll nun eine mögliche Realisierung eines OFDM-basierten Powerline-Modems in Anlehnung an Forschungsarbeiten [22] des Instituts für Industrielle Informationstechnik der Universität Karlsruhe vorgestellt werden. Das OFDM-Verfahren kann beispielsweise mit 256 Unterträgern realisiert werden, welche jeweils mit DQPSK moduliert werden. Bei dieser Modulationsart werden immer zwei Bits zu einem Symbol umgewandelt. Da bei DQPSK die Symbole alle eine gleiche Amplitude besitzen, wird die Information in der Phase übertragen. Hierbei zählt jedoch nicht die absolute Phase, sondern die Phasendifferenz zum vorhergehenden Symbol, da es sich um eine differenzielle Modulationsart handelt. Dies hat den Vorteil, dass Störungen, welche sich auf mehrere aufeinander folgende Symbole auswirken, die Demodulation am Empfänger weniger beeinträchtigen als bei einer absoluten Modulationsart. Die Wahl von DQPSK geschieht auch aufgrund der Tatsache, dass niederwertige Modulationsverfahren sich robuster gegenüber Störeinflüsse verhalten als höherwertige Modulationsverfahren. Im Gegenzug ist die Datenrate jedoch bei niederwertigerer Modulation geringer. Es lassen sich Netto-Datenraten bis zu 1 Mbit/s durch diese Verfahren erreichen. 108 6 AUSBLICK Vorgeschlagen wird die Entwicklung einer Platine mit einem integriertem DSP und einer USBSchnittstelle zum Anschluss an einen Personal Computer. Die Platine gliedert sich in drei Hauptteile wie in Abbildung 6.1 zu erkennen ist. PC USB Mikrocontroller Bild 6.1: AD/-D/A-Platine DSP FPGA Hauptplatine Analog-Frontend D/A Empfangsprozessor Signalkopplung, analoge Filterung, Mischerstufe Powerline A/D Schematischer Aufbau eines OFDM-Powerline-Modems Hauptplatine Die Hauptplatine besteht aus einem USB-Mikrocontroller, der die Schnittstelle zum PC bereitstellt. Neben dem USB-Mikrocontroller befindet sich noch ein DSP auf der Hauptplatine, der zur Kontrolle der AD/DA-Wandler zuständig ist sowie Aufgaben der digitalen Signalverarbeitung wahrnimmt. Darunter fallen beispielsweise die Codierung und Decodierung des Datenstromes, das Symbolmapping, die Synchronisation und die Modulation/Demodulation der OFDM-Unterträger durch die FFT bzw. IFFT. AD-/DA-Platine Auf der AD-/DA-Platine befindet sich ein FPGA, ein digitaler Empfangsprozessor und AD-/ DA-Wandler. Ihre Aufgabe ist es, die komplexen digitalen Signale der Hauptplatine in die zugehörigen reellwertigen analogen Signale und umgekehrt umzuwandeln. Der Empfangsprozessor wird durch den FPGA kontrolliert und entlastet den DSP in der digitalen Signalverarbeitung. Der Sende- und Empfangspuffer wird ebenfalls durch den FPGA übernommen. Den Takt für die gesamte Schaltung stellt eine auf der AD-/DA-Platine vorhandene PLL-Schaltung bereit, welche mit dem DSP gesteuert werden kann. Die unterschiedlichen Frequenzen, die für die Hardwarekomponenten wie beispielsweise Empfangsprozessor und Abtastrate des Modems auf der Platine benötigt werden, lassen sich mit Hilfe von Frequenzteilern im FPGA einstellen. Analog-Frontend Die Hauptaufgabe des Analog-Frontends besteht in der Ein- und Auskopplung des Signals in bzw. aus dem Stromnetz. Auf dieser Platine sind ebenfalls zwei analoge Filter zur Bandbegrenzung untergebracht, jeweils eines für Sende- und Empfangsbetrieb. Außerdem findet auf dieser Platine die Mischung des Sendesignals in das gewünschte Übertragungsband statt. Für die notwendige Signalleistung auf dem Übertragungsmedium sorgt eine einstellbare Endstufe. Auch 109 6 AUSBLICK die Pegelanpassung für die Abtastung des empfangenen Signals ist in diesem Abschnitt untergebracht. Zur Entwicklung eines solchen Powerline-Modems empfiehlt sich folgende Aufteilung: • Entwicklung der einzelnen Hardwareeinheiten des Modems, der Hauptplatine, der AD/ DA-Platine, des Analog-Frontends sowie des Netzteils • Implementierung eines FPGAs und Umsetzung von Algorithmen zur digitalen Signalverarbeitung • Programmierung eines USB-Mikrocontrollers für die Anbindung an den Universal Serial Bus eines PCs • Programmierung eines DSPs zur digitalen Signalverarbeitung • Entwicklung einer windows-basierten Kommunikationsschicht für die Steuerung des OFDM-Modems. 110 7 QUELLCODE FÜR DEN PHYSICAL-LAYER 7 Quellcode für den Physical-Layer /* * DIPLOMARBEIT * * * Denis Geiter * * Implementierung des Physical-Layers * (Kanalcodierung & Ansteuerung der seriellen Schnittstelle) * * * im Rahmen des * F‰cher¸bergreifenden Projekts * Powerline Communication * * * Sommersemester 2002 * */ #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <time.h> #include <windows.h> #include <iostream.h> #include <sys/timeb.h> #include <math.h> #include <string.h> #include <conio.h> // getche #define HEADERLEN 8 //L‰nge des Paketheaders in Byte mit CRC und Terminierung, ohne Barkercode(8), uncodiert #define PAYLOADLEN 131//L‰nge der Daten mit CRC16 und Terminierung #define MINPAKETLEN 26//Minimale Paketl‰nge (Barker+Header+Data, codiert, maximale Punktierung) (18Header+8Data) #define MAXPAKETLEN 280//Maximale Paketl‰nge (Barker+Header+Data, codiert) #define RECEIVELEN 4000//L‰nge des Lesepuffers #define BARKERCODE 0xF9A8//Barkercode zur Rahmensyncronisation: 1111 1001 1010 1(000) #define BARKERDEPTH 40//Anzahl der zu durchsuchenden Bytes ab Anfang #define TERMINIERUNG 0xFF//Terminierungsbyte f¸r Faltungscode #define CONSTRAINTLEN 7 //Einflu?l‰nge = Anzahl der Register+1 #define N 2 //Anzahl der Generatorsequenzen #define STATES 1<<(CONSTRAINTLEN-1)//Anzahl der Zust‰nde #define ERRORCHECKCOUNT 8//Anzahl der auszusendenden Testpakete #define ERRORCHECKCHAR 0x55//Testbyte mit aus dem die Daten bestehen //Faltungscode K=7, G(133,171) 1011011, 1111001 const int LEN=7; //Einflu?l‰nge const unsigned char GEN1=0xB6;//1011 0110 (octal 133) const unsigned char GEN2=0xF2;//1111 0010(octal 171) struct statetable{ int int }; uppercode; lowercode; struct pathtable{ int prevstate; bool output; doublepathcost; }; //Trelliszustandsvariablen //Codewort des oberen Pfades //Codewort des unteren Pfades //Trelliszustandsvariablen //wahrscheinliche Ausgangsfolge //Pfadkosten struct stat{ int packets_correct; int packets_lost_crc8; int packets_lost_crc16; int packets_lost_barker; int packets_lost_cut; int bit_errors_per_paket; }; struct statetable state[STATES]; 111 7 QUELLCODE FÜR DEN PHYSICAL-LAYER struct pathtable pathstate[RECEIVELEN][STATES]; struct stat paketstat; int verbosity=1; //"Geschw‰tzigkeit" der Ausgaben HANDLE hCom; //Handle der seriellen Schnittstelle HANDLE FUPhThread=0; //Handle f¸r Read-Thread HANDLE KeyPressThread=0; //Handle f¸r KeyPressBreak HANDLE FUPhandle[2]; //Handle-Array f¸r WaitForMultibleObjects-Funktion HANDLE EventSendRoutineStart;//Event wenn Sende-Routine aufgerufen wird HANDLE EventSendRoutineEnd;//Event wenn Sende-Routine fertig ist HANDLE EventKeyBreak; //Event wenn Tastendruck f¸r Abbruch OVERLAPPED EventCarrierDetect;//Event wenn Carrier Detect OVERLAPPED EventReceive; //Event wenn Lese-Vorgang zu Ende OVERLAPPED EventSend; //Event wenn Schreib-Vorgang zu Ende //********************************************************************************************* void ErrorHandler(char *message, DWORD error) { //cout << "\nFEHLER -> "<< message << ", Fehlercode: " << error; } //********************************************************************************************* void OpenComPort(int comport) { DCB dcb; char comstring[6]; switch(comport){ case 1: strcpy(comstring,"COM1\0"); break; case 2: strcpy(comstring,"COM2\0"); break; } hCom=CreateFile(comstring, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,0); //*hCom if(hCom==INVALID_HANDLE_VALUE) ErrorHandler("CreateFile: COM-Port-Handler nicht erhalten",GetLastError()); if(!GetCommState(hCom, &dcb)) ErrorHandler("GetCommState: COM-Status nicht erhalten",GetLastError()); dcb.BaudRate=2400; dcb.ByteSize=8; if(!SetCommState(hCom, &dcb)) ErrorHandler("SetCommState: Fehler beim ƒndern des COM-Status",GetLastError()); EscapeCommFunction(hCom,CLRRTS);//Setze Modem in Empfangsmodus } //********************************************************************************************* void CloseComPort() { CloseHandle(hCom); } //********************************************************************************************* //Wartet auf Tastendruck und sendet Abbruchbefehl unsigned long _stdcall KeyPressBreak(void* pData) { char dummy; dummy=getch(); SetEvent(EventKeyBreak); return 0; } //********************************************************************************************* int Compare(unsigned char* a, unsigned char* b, int length){ int i, j, biterrors=0; /*printf("\n Compare A"); for(i=0;i<length;i++)printf(" %2X",a[i]); printf("\n Compare B"); for(i=0;i<length;i++)printf(" %2X",b[i]); */ for(i=0;i<length;i++) for(j=0;j<8;j++) if( (a[i]&(1<<j)) != (b[i]&(1<<j)) )biterrors++; return biterrors; } //********************************************************************************************* 112 7 QUELLCODE FÜR DEN PHYSICAL-LAYER int AddErrors(unsigned char* a, int strlength, double error_rate){ int i, j=0, r, biterrors=0; double k; // // printf("\nOriginal:"); for(i=0;i<strlength;i++)printf(" %2X",a[i]); for(i=0;i<strlength;i++) for(j=0;j<8;j++) if( rand() <= (32767*error_rate) ){ biterrors++; if( (a[i] & (1<<j)) > 0 )a[i]&=~(1<<j); else a[i]|=(1<<j); } // // printf("\nerrorness:"); for(i=0;i<strlength;i++)printf(" %2X",a[i]); // // // printf("\nbiterrors: %i", biterrors); printf("\ntotalbits: %i", strlength*8); printf("\nbiterrorrate: %f",((float)biterrors)/strlength/8); return biterrors; } //********************************************************************************************* int Distance(unsigned char a, unsigned char b, unsigned char puncmask){ //puncmask: z.B. 1111101, wegen Punktierung wird ein Bit nicht ber¸cksichtigt bei der Berechnung int i, dist=0; a&=puncmask; //Lˆsche Bits, die wegen Punktierung nicht ber¸cksichtigt werden b&=puncmask; a^=b; for(i=0;i<8;i++)//Z‰hle Einsen dist+=(a&(1<<i))>0; return dist; } //********************************************************************************************* bool PHY_IsCarrier(){ DWORD lpModemStat; GetCommModemStatus(hCom,&lpModemStat); return lpModemStat&MS_RLSD_ON>0; } //********************************************************************************************* void MAC_CarrierStateChange(bool carierstate){}//Dummy-Funktion //********************************************************************************************* int MAC_Receive(unsigned char* header, unsigned char* data){return 0;}//Dummy-Funktion //********************************************************************************************* void GenerateTrellis(void){ unsigned char shiftreg=0; unsigned char temp; int j, k, isodd; //Trellis-Codewˆrter ausrechnen for(j=0;j<STATES;j++){ //Codewˆrter f¸r obere Zweige berechnen state[j].uppercode=0; shiftreg=0; shiftreg=(char) ((j*2)%(STATES))<<(8-CONSTRAINTLEN);//Leite den Zustand des Registers aus der Zustandszahl ab if(j>=(STATES)/2) //f¸r die ersten STATE/2 Zust‰nde 0, sonst 1 shiftreg|=0x80; isodd=0; temp=shiftreg&GEN1; //Shiftregister AND Generatorpolynom1 for(k=0;k<CONSTRAINTLEN;k++)//Schleife ¸ber die relevanten Bits im Register isodd^=(temp&(1<<(7-k)))>0;//XOR Bits aus vorheriger AND-Berechnung if(isodd==1) state[j].uppercode|=0x80;//Falls XOR-Rechnung=1, dann setze 1.Bit in Ausgabedaten else state[j].uppercode&=~0x80;//Falls XOR-Rechnung=0, dann lˆsche 1.Bit in Ausgabedaten isodd=0; temp=shiftreg&GEN2; for(k=0;k<CONSTRAINTLEN;k++) isodd^=(temp&(1<<(7-k)))>0; if(isodd==1) state[j].uppercode|=0x40;//Falls XOR-Rechnung=1, dann setze 2.Bit in Ausgabedaten 113 7 QUELLCODE FÜR DEN PHYSICAL-LAYER else state[j].uppercode&=~0x40;//Falls XOR-Rechnung=0, dann lˆsche 2.Bit in Ausgabedaten //printf("\nState:%i, Up:%X",j, state[j].uppercode>>6); //Codewˆrter f¸r untere Zweige berechnen state[j].lowercode=0; shiftreg=0; shiftreg=(char) ((j*2+1)%(STATES))<<(8-CONSTRAINTLEN);//Leite den Zustand des Registers aus der Zustandszahl ab if(j>=(STATES)/2) //f¸r die ersten STATE/2 Zust‰nde 0, sonst 1 shiftreg|=0x80; isodd=0; temp=shiftreg&GEN1; //Shiftregister AND Generatorpolynom1 for(k=0;k<CONSTRAINTLEN;k++)//Schleife ¸ber die relevanten Bits im Register isodd^=(temp&(1<<(7-k)))>0;//XOR Bits aus vorheriger AND-Berechnung if(isodd==1) state[j].lowercode|=0x80;//Falls XOR-Rechnung=1, dann setze 1.Bit in Ausgabedaten else state[j].lowercode&=~0x80;//Falls XOR-Rechnung=0, dann lˆsche 1.Bit in Ausgabedaten isodd=0; temp=shiftreg&GEN2; for(k=0;k<CONSTRAINTLEN;k++) isodd^=(temp&(1<<(7-k)))>0; if(isodd==1) state[j].lowercode|=0x40;//Falls XOR-Rechnung=1, dann setze 2.Bit in Ausgabedaten else state[j].lowercode&=~0x40;//Falls XOR-Rechnung=0, dann lˆsche 2.Bit in Ausgabedaten //printf("\nState: %i, Low:%X",j, state[j].lowercode>>6); } } //********************************************************************************************* void Encode(unsigned char* indata, unsigned char* outdata, int length){ //length: L‰nge der Eingangsdaten in Byte unsigned char shiftreg=0x00; unsigned char temp; int i, j, isodd; for(i=0;i<length*8;i++){ shiftreg>>=1; if(indata[i/8]&(1<<(7-(i%8))))//Schiebe Datenbits von links ins Register nach shiftreg+=0x80; isodd=0; temp=shiftreg&GEN1; //Shiftregister AND Generatorpolynom1 for(j=0;j<LEN;j++) //Schleife ¸ber die relevanten Bits im Register isodd^=(temp&(1<<(7-j)))>0;//XOR Bits aus vorheriger AND-Berechnung if(isodd) outdata[(i*2)/8]|=1<<(7-((i*2)%8));//Falls XOR-Rechnung=1, dann setze Bit in Ausgabedaten else outdata[(i*2)/8]&=~(1<<(7-((i*2)%8)));//Falls XOR-Rechnung=0, dann lˆsche Bit in Ausgabedaten isodd=0; temp=shiftreg&GEN2; for(j=0;j<LEN;j++) isodd^=(temp&(1<<(7-j)))>0; if(isodd) outdata[(i*2+1)/8]|=1<<(7-((i*2+1)%8)); else outdata[(i*2+1)/8]&=~(1<<(7-((i*2+1)%8)));//Falls XOR-Rechnung=0, dann lˆsche Bit in Ausgabedaten } } //********************************************************************************************* int Decode(unsigned char* indata, unsigned char* outdata, int length, int mode){ //lenght: l‰nge der codierten Daten in bytes, mode: Punktierungsrate //liefert Pfadkosten zur¸ck int i, j, bitcounter=0; double dist1, dist2; unsigned char temp, prev; float lenfactor=0; unsigned short puncmask; unsigned char masklen, punctemp; //printf("\n[Decode] Punktierung: %i, ",mode); //Auswahl der Punktierungsmaske switch(mode){ 114 7 QUELLCODE FÜR DEN PHYSICAL-LAYER case 1: puncmask=0xE640; masklen=10; break; case 2: puncmask=0xE990; masklen=12; break; case 3: puncmask=0xEA64; masklen=14; break; default: puncmask=0xFFFF; masklen=16; break; //1110011001(000000), Rate:5/6 //111010011001(0000), Rate:6/7 //11101010011001(00), Rate:7/8, //1111111111111111 } //Initialisierung for(i=0;i<length/2;i++)outdata[i]=0;//Lˆsche Ausgangsdaten-Array pathstate[0][0].pathcost=0; //Intitialisierung der Pfadkosten for(i=1;i<(STATES);i++)pathstate[0][i].pathcost=999; //Hauptschleife Viteri //printf("punctemp="); for(i=0;i<length*8;i+=2){ //Schleife ¸ber die decodierte L‰nge in Bit, Schrittweite 2 wegen Anzahl der Bits pro Codewort punctemp=( (puncmask<<(i%masklen)) & 0xC000 )>>8;//Selektiere die 2 relevanten Bits aus Punktierungsmaske, konvertiere short in char //punctemp&=0xC0; //printf("\npunctemp %X, i%%masklen %i, (puncmask<<(i%%masklen))& 0xC000 %X",punctemp, i%masklen,(puncmask<<(i%masklen)) ); //Codebitsgewinnung aus Empfangsdaten mit und ohne Punktierung temp=0; //printf("\npunctemp= %X",punctemp); for(j=0;j<2;j++){ //Schleife ¸ber die Bits in einem Codewort if( (punctemp & (1<<(7-j))) > 0){//‹berall wo in der Punktierungsmaske ein Bit gesetzt ist, f¸ge in temp ein Bit aus indata ein temp+= ( (indata[bitcounter/8] & (1<< (7-(bitcounter%8))) )>0 )<<(7-j); //printf("\n bitcounter %i, indata[bitcounter/8] %X, (1<< (7-(bitcounter%8))) %X, (7-j) %i", bitcounter, indata[bitcounter/8],(1<< (7(bitcounter%8))), (7-j)); bitcounter++; } } //printf("\n temp= %X, punctemp= %X",temp, punctemp); //printf("\nDECO3 %i %i", length, i); //Add-Compare-Select-Schleife for(j=0;j<STATES;j++){ dist1=pathstate[i/2][(j*2 )%(STATES)].pathcost + Distance(temp,state[j].uppercode, punctemp);//bestimme Pfadmetrik des oberen Pfades dist2=pathstate[i/2][(j*2+1)%(STATES)].pathcost + Distance(temp,state[j].lowercode, punctemp);//bestimme Pfadmetrik des unteren Pfades if(dist1<dist2){ pathstate[i/2+1][j].pathcost=dist1; pathstate[i/2+1][j].prevstate=(j*2)%(STATES); } if(dist1>dist2){ pathstate[i/2+1][j].pathcost=dist2; pathstate[i/2+1][j].prevstate=(j*2+1)%(STATES); } if(dist1==dist2){ if(rand()&1){ pathstate[i/2+1][j].pathcost=dist2; pathstate[i/2+1][j].prevstate=(j*2+1)%(STATES);} else{ pathstate[i/2+1][j].pathcost=dist1; pathstate[i/2+1][j].prevstate=(j*2)%(STATES);} } pathstate[i/2+1][j].output=(j>=((STATES)/2)); } } //Ausgabebyte-Rekonstruktion prev=(STATES)-1; //festen Ausgangszustand annehmen, wegen Terminierung for(i=length*8/2;i>0;i--){ outdata[(i-1)/8]+= pathstate[i][prev].output<<((length*8/2-i)%8); prev=pathstate[i][prev].prevstate; } //printf("End-Pfadkosten: %g",pathstate[length*8/2][(STATES)-1].pathcost); // printf("\nin decode:"); //for(i=0;i<20;i++)printf(" %2X", outdata[i]); return (int) pathstate[length*8/2][(STATES)-1].pathcost; } //********************************************************************************************* 115 7 QUELLCODE FÜR DEN PHYSICAL-LAYER unsigned char CRC8(unsigned char* indata) { const unsigned char gen=0x07;//Generatorpolynom f¸r CRC unsigned char shiftreg=0xff; int i, bittest; for(i=0;i<(HEADERLEN-2)*8;i++){//Schleife nur ¸ber Headerdaten bittest=shiftreg&0x80; //Pr¸fe MSB auf 1 shiftreg<<=1; //schiebe Bits um 1 nach links if(indata[i/8]&(1<<(7-(i%8))))//Schiebe Datenbits ins Register nach shiftreg+=1; if(bittest) shiftreg^=gen; //Falls MSB=1, dann XOR mit Generatorpolynom } return shiftreg; //CRC zur¸ck } //********************************************************************************************* //CRC16 arbeitet nach dem Standard CRC-16 der CCITT und verh‰lt sich normgerecht! unsigned short CRC16(unsigned char* indata,int datalen) { const unsigned short gen=0x1021;//Generatorpolynom f¸r CRC, gen=0x1021 unsigned short shiftreg=0xffff; int i, bittest; for(i=0;i<datalen*8;i++){ bittest=shiftreg&0x8000; shiftreg<<=1; //Pr¸fe MSB auf 1 //schiebe Bits um 1 nach links if(indata[i/8]&(1<<(7-(i%8))))//Schiebe Datenbits ins Register nach shiftreg+=1; if(bittest) shiftreg^=gen; //Falls MSB=1, dann XOR mit Generatorpolynom } return shiftreg; //CRC zur¸ck } //********************************************************************************************* //Erkennt am Barkercode den Anfang und am TERMINIERUNG das Ende. Gibt Daten ohne Barkercode mit TERMINIERUNG zur¸ck bool FrameSync(unsigned char* data, int datal) { //datal = L‰nge der Bytefolge data int i,j,k, sum=0, ones=0, maximum=0, byteshift=0, bitshift=0, shiftcounter=0; unsigned short shiftreg=0; //LSB wird nicht beachtet unsigned short tmpreg=0; unsigned char tmpdata[RECEIVELEN]; //Finde Barkersequenz for(k=0;k<BARKERDEPTH;k++) //¸ber alle zu untersuchenden Bits for(j=0;j<8;j++){ //¸ber alle Bits im Byte shiftcounter++; shiftreg<<=1; shiftreg+=( (data[k]&(1<<(7-j)))>0 )<<1;//Schiebe Daten ins Register tmpreg=shiftreg^BARKERCODE; for(i=1;i<16;i++)ones+=(tmpreg&(1<<i))>1;//Z‰hle Einsen sum=(15-ones)-ones; if(sum>maximum){ //Merke wahrscheinlichste Position der Barkersequenz maximum=sum; bitshift=(shiftcounter+1)%8; byteshift=(shiftcounter-7)/8; //printf("\nMaximum bei: %X, Maximum: %i", shiftreg, maximum); } //printf("\nSumme: %i \t ,bitshift: %i, byteshift: %i, maximum: %i, shiftcounter: %i", sum, bitshift, byteshift, maximum, shiftcounter); sum=0;ones=0; } if(maximum<14){ //Schwelle, ab wann Pakete als nicht erkannt werden paketstat.packets_lost_barker++;//Erhˆhe PaketLoss-Statistik return FALSE; //Fehler: Barkersequenz nicht gefunden } //Schneide Datenfolge aus for(i=0;i<datal;i++) tmpdata[i]=(unsigned char) (data[i+byteshift+1]<<bitshift) + (data[i+byteshift+2] >>(8-bitshift)); i=0; //printf("\nByteshift: %i, Bitshift: %i",byteshift, bitshift); for(i=0;i<datal;i++)data[i]=tmpdata[i];//Kopiere Daten zur¸ck return TRUE; } //********************************************************************************************* 116 7 QUELLCODE FÜR DEN PHYSICAL-LAYER bool Puncture(unsigned char* data,//zu punktierenden Daten int* datalen, //L‰nge der Daten in Byte mit CRC und Terminierung nach Faltungscodierung int mode) //W‰hlt Punktierung aus { int i, bitpos=0; unsigned short puncmask; unsigned char masklen; switch(mode){ //Auswahl der Punktierungsmaske case 1: puncmask=0xE640;//1110011001(000000), Rate:5/6 (6 von 10 Bit werden ¸bertragen) masklen=10; break; case 2: puncmask=0xE990;//111010011001(0000), Rate:6/7 masklen=12; break; case 3: puncmask=0xEA64;//11101010011001(00), Rate:7/8 masklen=14; break; default: return FALSE; } for(i=0;i<(*datalen * 8);i++) if(( puncmask & (1<<(15-i%masklen)) )>0){//Wird Bit ¸bertragen? if(data[i/8] & (1<<(7-i%8)) ){ data[bitpos/8] |= (1<<(7-bitpos%8));//Setze Datenbit, wenn 1 ¸bertragen werden soll } else{ data[bitpos/8] &= (~(1<<(7-bitpos%8)));//Lˆsche Datenbit, wenn 0 ¸bertragen werden soll } bitpos++; } *datalen=bitpos/8; if((bitpos%8) != 0) (*datalen)++; return TRUE; } //********************************************************************************************* bool PHY_Send(unsigned char * wheader, unsigned char * wdata) { DWORD bytes_written; int i; const stime=80; int wdatalen; //L‰nge der uncodierten Payload in Byte mit CRC16 und Terminierung unsigned short tmpcrc=0; //Hilfsvariable f¸r CRC-Berechnung unsigned char wbuffer[RECEIVELEN];//Gesamter Sendebuffer if(verbosity>0)printf("\n-----------------------------------------------------------\n"); wdatalen=((wheader[0] & 0x1F)+1)*4;//Bestimme L‰nge der Daten //if(verbosity>0)printf("\n[wdatalen] %i",wdatalen); /*if(verbosity>0){ printf("\n[soll gesendet werden] "); for(i=0;i<wdatalen;i++) printf("%c",wdata[i]); printf("<-Ende"); }*/ //Vorbereitungen if(verbosity>0){ for(i=0;i<RECEIVELEN;i++)wbuffer[i]=0; printf("\nCRC Header: \t%X",CRC8(wheader)); } //Setze Header zusammen wbuffer[0]=(unsigned char) ((BARKERCODE)>>8);//Setze Barkercode an den Anfang wbuffer[1]=(unsigned char) (BARKERCODE); wheader[6]=CRC8(wheader); //Errechne und setze CRC des Headers wheader[7]=TERMINIERUNG; //F¸ge Terminierung an den Header Encode(wheader, &wbuffer[2],(HEADERLEN));//Codiere den Header //Setze Payload zusammen tmpcrc=CRC16(wdata,wdatalen); 117 7 QUELLCODE FÜR DEN PHYSICAL-LAYER if(verbosity>0)printf("\nCRC Daten: \t%X",tmpcrc); wdata[wdatalen]=(unsigned char) (tmpcrc>>8); wdata[wdatalen+1]=(unsigned char) tmpcrc;//F¸ge CRC16 ein wdata[wdatalen+2]=TERMINIERUNG;//F¸ge Terminierung an die Daten //Print Header vor Codierung if(verbosity>0){ printf("\n\n[Paket vor Codierung]\n\nHeader(%i):\t%2X %2X ",(HEADERLEN)+2, (unsigned char)((BARKERCODE)>>8), (unsigned char)(BARKERCODE)); for(i=0;i<(HEADERLEN);i++)printf("%2X ", wheader[i],i); } //Print Daten vor Codierung if(verbosity>0){ printf("\nDaten(%i):\t",wdatalen+3); for(i=0;i<wdatalen+3;i++){ if((!(i%18))&&(i>20))printf("\n\t\t"); printf("%2X ", wdata[i],i); } } Encode(wdata,&wbuffer[(HEADERLEN)*2+2],wdatalen+3);//Codiere die Daten //Print Paket vor Punktierung if(verbosity>1){ printf("\n\n[Vor Punktierung]\n\nHeader(%i):\t",2+(HEADERLEN)*2); for(i=0;i<( 2+(HEADERLEN)*2+ 2*(wdatalen+3) );i++){ if( i==2+((HEADERLEN)*2) ) printf("\nData(%i): \t",2*(wdatalen+3)); if((!(i%18))&&(i>20))printf("\n\t\t"); printf("%2X ", wbuffer[i],i); } } wdatalen=(wdatalen+3)*2; //Neue L‰nge der Daten: (+CRC16, +Terminierung)*Faltungscodierung Puncture(&wbuffer[(HEADERLEN)*2+2],&wdatalen,wheader[0]>>5);//Punktiere die Daten //Print zu sendendes Paket if(verbosity>0){ printf("\n\n[gesendetes Paket]\n\nHeader(%i): \t",2+(HEADERLEN)*2); for(i=0;i<( 2+(HEADERLEN)*2 + wdatalen );i++){ if( i==2+((HEADERLEN)*2) ) printf("\nData(%i): \t",wdatalen); if((!(i%18))&&(i>20))printf("\n\t\t"); printf("%2X ", wbuffer[i],i); } //printf("\n[wdatalen] \t%i",wdatalen); } //Bereite Senden vor SetEvent(EventSendRoutineStart); //Signalisiere Anfang der Send-Routine um Empfang auszusetzen EscapeCommFunction(hCom,SETRTS);//Setze Modem in Sendemodus Sleep(stime); if(!PurgeComm(hCom,PURGE_TXCLEAR)) ErrorHandler("PurgeComm in TX: error", GetLastError());//Lˆsche Sendebuffer //Sende Daten WriteFile(hCom,wbuffer, 2 + ((HEADERLEN)*2) + wdatalen, &bytes_written, &EventSend); if(WaitForSingleObject(EventSend.hEvent, 500)==WAIT_TIMEOUT) ErrorHandler("Wait_TimeOut in WaitForSingleObject nach WriteFile: ",GetLastError()); if(!GetOverlappedResult(hCom, &EventSend, &bytes_written, TRUE)) ErrorHandler("GetOverlappedResult: ",GetLastError()); //Nachbereite Senden if(verbosity>0){ printf("\n\nPaketlaenge: \t%i", bytes_written); printf("\n\n-------------------- PAKET GESENDET -----------------------\n"); } Sleep(stime); EscapeCommFunction(hCom,CLRRTS);//Setze Modem in Empfangsmodus SetEvent(EventSendRoutineEnd); //Signalisiere Ende der Send-Routine Sleep(500); return 1; } //********************************************************************************************* //Liest von COM, Wartet auf Event RLSD, 4 Zeichen M¸ll zu Beginn, am Ende korrekt abgeschnitten, Bufferlˆschen unsigned long _stdcall PHY_Receive(void* pData) { DWORD dwEvtMask; DWORD lpModemStat; DWORD bytes_read; unsigned long dummy; int i, t=0, startpos=0, endpos=0; 118 7 QUELLCODE FÜR DEN PHYSICAL-LAYER int rdatalen; unsigned char rheader[RECEIVELEN]; unsigned char rdata[RECEIVELEN]; unsigned char rbuffer[RECEIVELEN]; //if(verbosity>0)printf("\nEmpfangsbereit im FUPreceive-Thread...\n"); //Initialisiere Events EventCarrierDetect.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);//CD-Event EventReceive.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);//CD-Event EventSend.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);//Send-Event EventSendRoutineStart=CreateEvent(NULL, TRUE, FALSE, NULL);// EventSendRoutineEnd=CreateEvent(NULL, TRUE, FALSE, NULL);// FUPhandle[0]=EventCarrierDetect.hEvent; FUPhandle[1]=EventSendRoutineStart; while(1){ EscapeCommFunction(hCom,CLRRTS);//Setze Modem in Empfangsbereitschaft //Warte auf Events SetCommMask(hCom,EV_RLSD); WaitCommEvent(hCom, &dwEvtMask, &EventCarrierDetect ); i=WaitForMultipleObjects(2,FUPhandle, FALSE, INFINITE);//Warte auf CD- oder Send-Event if(i==1){ //Falls gesendet wird, warte aufs Ende des Sendens ResetEvent(EventSendRoutineStart); WaitForSingleObject(EventSendRoutineEnd, INFINITE); ResetEvent(EventSendRoutineEnd); continue; } else{ ResetEvent(EventCarrierDetect.hEvent); GetCommModemStatus(hCom,&lpModemStat);//Frage nochmal CarrierDetect ab if(!(lpModemStat & MS_RLSD_ON)) continue;//Falls kein Carrier, Event falsch ausgelˆst, springe zur¸ck } //Bereite Empfang vor MAC_CarrierStateChange(1); //Benachrichtigung an MAC-Layer ¸ber CarrierDetect if(verbosity>0)printf("\n\n\n\n----------- PAKET EMPFANGEN -------------\n"); if(!PurgeComm(hCom,PURGE_RXCLEAR)) ErrorHandler("PurgeComm: error", GetLastError());//Lˆsche Empfangsbuffer GetCommModemStatus(hCom,&lpModemStat);//Frage nochmal CarrierDetect ab //Empfangsschleife while(lpModemStat & MS_RLSD_ON){//Solange CD-Signal, lese byteweise ReadFile(hCom, &rbuffer[t], 1, &bytes_read, &EventReceive); if(WaitForSingleObject(EventReceive.hEvent, 500)==WAIT_TIMEOUT)ErrorHandler("Wait_TimeOut in WaitForSingleObject nach ReadFile: ",GetLastError());; if(!GetOverlappedResult(hCom, &EventReceive, &dummy, TRUE))ErrorHandler("GetOverlappedResult: ",GetLastError()); t++; if(t==RECEIVELEN){ printf("\n‹berlauf des Empfangbuffers!"); break; //Empfangsbuffer darf nicht ¸berlaufen } GetCommModemStatus(hCom,&lpModemStat);//CD-Signal noch vorhanden? } //Bereite Empfang nach MAC_CarrierStateChange(0); //Benachrichtigung an MAC-Layer ¸ber CarrierDetect if(t<(MINPAKETLEN)){ paketstat.packets_lost_cut++; printf("\nMindest-Paketl‰nge(%i) unterschritten! (%i Bytes) -> Abbruch",(MINPAKETLEN), t); continue; //Weniger als MINPAKETLEN Zeichen ist kein Paket -> weiter } //Print empfangene Bytes if(verbosity>0){ printf("\nByteanzahl:\t%i\n\n[Empfangenes Paket]\n\nPaket:\t\t",t); for(i=0;i<t;i++){ if((!(i%18))&&(i>2))printf("\n\t\t"); printf("%2X ",rbuffer[i]); } } if(FrameSync(rbuffer, t)!=TRUE){ printf("\nBarkercode nicht gefunden! -> Abbruch"); t=0; continue; //Finde Paketanfang } t=0; //Lˆsche L‰nge der empfangenen Bytes 119 7 QUELLCODE FÜR DEN PHYSICAL-LAYER //Header-Decodierung: Decode(&rbuffer[0], rheader, (HEADERLEN)*2, 0); rdatalen=((rheader[0] & 0x1F)+1)*4+3; //if(verbosity>0)printf("\n[rdatalen] %i", rdatalen); //Print Paket vor Decodierung if(verbosity>0){ printf("\n\n[Vor Decodierung]\n\nHeader(%i):\t",(HEADERLEN)*2); for(i=0;i<((HEADERLEN)*2+rdatalen*2);i++){ if( i==(HEADERLEN)*2 )printf("\nData(%i):\t", rdatalen*2); if((!(i%18))&&(i>20))printf("\n\t\t"); printf("%2X ", rbuffer[i],i); } } //Print Header if(verbosity>0){ printf("\n\n[Decodiertes Paket]\n\nHeader:\t\t"); for(i=0;i<(HEADERLEN);i++) printf("%2X ", rheader[i]); } //Daten-Decodierung: Decode(&rbuffer[(HEADERLEN)*2], rdata, rdatalen*2, rheader[0]>>5); //CRC8 if(CRC8(rheader)==rheader[6]){ if(verbosity>0)printf("\nCRC Header:\tOK"); } else{ paketstat.packets_lost_crc8++; printf("\nCRC Header:\tERROR (berechnet: %2X, empfangen: %2X) -> Abbruch", CRC8(rheader), rheader[6]); continue; } //Print Daten decodiert HEX if(verbosity>0){ printf("\nDaten:\t\t"); for(i=0;i<rdatalen-3;i++){ if((!(i%18))&&(i>2))printf("\n\t\t"); printf("%2X ", rdata[i]); } } //CRC16 if( CRC16(rdata, rdatalen-3) == (((unsigned short) rdata[rdatalen-3]) <<8) + (unsigned short) rdata[rdatalen-2]){ if(verbosity>0)printf("\nCRC Daten:\tOK"); } else{ paketstat.packets_lost_crc16++; printf("\nCRC Daten:\tERROR -> Abbruch"); continue; } //Print Daten decodiert ASCII if(verbosity>0)printf("\nMessage:\t"); else printf("> "); for(i=0;i<rdatalen-3;i++)printf("%c", rdata[i]); if(verbosity>0)printf("\n\nEingabe der Sendezeichenfolge: "); else printf("\n"); MAC_Receive(rheader, rdata);//‹bergabe der decodierten Daten an MAC-Layer } return 0; } //********************************************************************************************* int KeyboardInput(unsigned char * data, unsigned char * first_header_byte){ //Liefert 1 zur¸ck falls zur¸ck zum Hauptmen¸, sonst Null char string[150]; int i; //Einlesen des zu sendenden Strings Sleep(100); if(verbosity>0)printf("\nEingabe der Sendezeichenfolge: "); gets(string); //String einlesen if (string[0]=='q')return 1; //Falls Eingabe von q - Ende *first_header_byte &= 0xE0; if(strlen(string)>0) //Lˆsche alte Paketl‰nge 120 7 QUELLCODE FÜR DEN PHYSICAL-LAYER *first_header_byte += (strlen(string) -1)/4;//Paketl‰nge bestimmen und im 1. Byte vermerken for(i=0;i<(RECEIVELEN);i++) //Lˆsche Daten aus vorheriger ‹bertragung data[i]=' '; for(i=0;i< (signed) strlen(string);i++)//Eingabestring in Schreibbuffer kopieren data[i]=(unsigned char) string[i]; //Einlesen der Punktierung if(verbosity>0){ printf("\nEingabe der Punktierung [0,1,2,3]: "); gets(string); //String einlesen } if(verbosity==0) string[0]='0'; *first_header_byte &= 0x1F; //Lˆsche alte Punktierungsangabe switch(string[0]){ case '1': *first_header_byte |= 0x20;//Punktierung setzen break; case '2': *first_header_byte |= 0x40;//Punktierung setzen break; case '3': *first_header_byte |= 0x60;//Punktierung setzen break; } return 0; } //********************************************************************************************* void PHY_Init(int comport){ unsigned long threadID=0; unsigned char header[RECEIVELEN]; unsigned char data[RECEIVELEN]; unsigned long ExitCode=0; //Thread Exit Code int end=0; //Vorbereitungen OpenComPort(comport); //÷ffne Serial-Port GenerateTrellis(); //Bereche Trellis srand( (unsigned)time( NULL ) );//Initialisiere Zufallsprozess mit aktueller Zeit //Rufe Empfangsthread auf FUPhThread=reinterpret_cast<HANDLE>(CreateThread(0,0,PHY_Receive,0,0,&threadID)); GetExitCodeThread(FUPhThread, &ExitCode); //Sendethread while(end!=1) { end=KeyboardInput(data, &header[0]);//Lese Sendestring von Tastatur if(end==1){ CloseComPort(); TerminateThread(FUPhThread, ExitCode);//Abbruchsthread beenden return; } PHY_Send(header, data); //Rufe Senderoutine auf } TerminateThread(FUPhThread, ExitCode);//Abbruchsthread beenden CloseComPort(); } //********************************************************************************************* void PHY_TestSend(int comport){ unsigned long threadID=0; unsigned char header[RECEIVELEN]; unsigned char data[RECEIVELEN]; int errormode,puncmode,i,j,packetlen, paketcount; char ; //Vorbereitungen OpenComPort(comport); //÷ffne Serial-Port srand( (unsigned)time( NULL ) );//Initialisiere Zufallsprozess mit aktueller Zeit header[0]= 0x00; //Lˆsche L‰ngen- und Punktierungsdaten for(i=1;i<6;i++)header[i]=(ERRORCHECKCHAR);//Setze Headerbytes printf("\nError-Check-Modus? [1,2,3,4]: ");//Frage Check-Mode ab cin >> errormode; printf("\nPunktierung? [0,1,2,3]: ");//Frage Punktierung ab cin >> puncmode; printf("\nPaketanzahl? [0-32000]: ");//Frage Paketanzahl ab cin >> paketcount; 121 7 QUELLCODE FÜR DEN PHYSICAL-LAYER switch(puncmode){ case 1: header[0] |= 0x20; break; case 2: header[0] |= 0x40; break; case 3: header[0] |= 0x60; break; default: break; } //Punktierung setzen //Punktierung setzen //Punktierung setzen //Auswahl des Errorcheckmodes switch(errormode){ case 1: for(i=0;i<4;i++)data[i] =(ERRORCHECKCHAR); for(i=0;i<(paketcount);i++)PHY_Send(header, data); break; case 2: header[0] |= 0x0F; //Paketl‰nge auf 64 Bytes setzen for(i=0;i<64;i++)data[i] =(ERRORCHECKCHAR); for(i=0;i<(paketcount);i++)PHY_Send(header, data); break; case 3: header[0] |= 0x1F; //Paketl‰nge auf 128 Bytes setzen for(i=0;i<128;i++)data[i] =(ERRORCHECKCHAR); for(i=0;i<(paketcount);i++)PHY_Send(header, data); break; default: for(i=0;i<paketcount;i++) { packetlen=(int) ((double) rand())/32767*31;//Bestimme Paketl‰nge durch Zufall (liefert Zahl zw. 0 und 31) header[0] += (char) packetlen; cout << "\nerrror4"; for(j=0;j<(packetlen+1)*4;j++)data[j] =(char) (((double) rand())/32767*255); PHY_Send(header, data); //Sleep(100); } break; } CloseComPort(); } //********************************************************************************************* void PHY_TestReceive(int comport){ DWORD dwEvtMask; DWORD lpModemStat; DWORD bytes_read; unsigned long ExitCode=0; //Thread Exit Code unsigned long dummy; unsigned long threadID=0; int i,j, t=0, startpos=0, endpos=0; int rdatalen, HeaderErrors, DataErrors; unsigned char rheader[RECEIVELEN]; unsigned char rdata[RECEIVELEN]; unsigned char rbuffer[RECEIVELEN]; int errormode, error_len=0, puncmode,packetlen; float rawbiterrors=0; //Bitfehler eines Paketes float innerbiterrors=0; //innere Bitfehler eines Paketes float totalrawbiterrors=0;//Bitfehler aller Pakete float totalinnerbiterrors=0;//innere Bitfehler aller Pakete double error_rate=0; double inner_error_rate=0; unsigned char cbuffer[RECEIVELEN];//Gesamter Vergleichsbuffer unsigned char cheader[RECEIVELEN]; unsigned char cdata[RECEIVELEN]; unsigned short tmpcrc=0;//Hilfsvariable f¸r CRC-Berechnung int cdatalen; //L‰nge der uncodierten Payload in Byte mit CRC16 und Terminierung int totalpacketlength=0;//Byteanzahl des aktuellen Pakets int totalinnerpacketlength=0;//Byteanzahl der Nutzbytes mit Header int packetcount=0; //Paketz‰hler float totalsendbytes=0; //Byteanzahl aller gesendeten Bytes float totalinnersendbytes=0;//Byteanzahl aller Nutzbytes paketstat.packets_correct=0; paketstat.packets_lost_barker=0; paketstat.packets_lost_crc16=0; paketstat.packets_lost_crc8=0; 122 7 QUELLCODE FÜR DEN PHYSICAL-LAYER paketstat.packets_lost_cut=0; printf("\nTestbetrieb Empfangsmodus... [Abbruch durch Tastendruck]\n"); //Initialisiere Events EventCarrierDetect.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);//CD-Event EventKeyBreak = CreateEvent(NULL, TRUE, FALSE, NULL);//KeyBreak-Event FUPhandle[0]=EventCarrierDetect.hEvent; FUPhandle[1]=EventKeyBreak; //Abfrage der Test-Parameter cheader[0]= 0x00; //Lˆsche L‰ngen- und Punktierungsdaten for(i=1;i<6;i++)cheader[i]=(ERRORCHECKCHAR);//Setze Headerbytes printf("\nError-Check-Modus? \n[1] - minimale Paketlaenge\n[2] - mittlere Paketlaenge\n[3] - maximale Paketlaenge\n? ");//Frage Check-Mode ab cin >> errormode; printf("\nPunktierung? \n[0] - keine\n[1] - Punktierung: 1110011001\n[2] - Punktierung: 111010011001\n[3] - Punktierung: 11101010011001\n? ");//Frage Punktierung ab cin >> puncmode; printf("\nBitfehler-Rate? [0-1]: "); cin >> error_rate; if(error_rate!=0){ printf("\nBarkersequenz fehlerfrei lassen? \n[0] - nein\n[1] - ja\n? "); cin >> error_len; } switch(puncmode){ case 1: cheader[0] |= 0x20; break; case 2: cheader[0] |= 0x40; break; case 3: cheader[0] |= 0x60; break; default: break; } //Punktierung setzen //Punktierung setzen //Punktierung setzen //Auswahl des Errorcheckmodes switch(errormode){ case 1: for(i=0;i<4;i++)cdata[i] =(ERRORCHECKCHAR); switch(puncmode){ case 0: totalpacketlength=32; totalinnerpacketlength=(HEADERLEN)+4+3; break; case 1: totalpacketlength=27; totalinnerpacketlength=(HEADERLEN)+4+3; break; case 2: totalpacketlength=27; totalinnerpacketlength=(HEADERLEN)+4+3; break; case 3: totalpacketlength=26; totalinnerpacketlength=(HEADERLEN)+4+3; break; default: break; } break; case 2: cheader[0] |= 0x0F; //Paketl‰nge auf 64 Bytes setzen for(i=0;i<64;i++)cdata[i] =(ERRORCHECKCHAR); switch(puncmode){ case 0: totalpacketlength=152; totalinnerpacketlength=(HEADERLEN)+64+3; break; case 1: totalpacketlength=99; totalinnerpacketlength=(HEADERLEN)+64+3; break; case 2: totalpacketlength=97; totalinnerpacketlength=(HEADERLEN)+64+3; break; 123 7 QUELLCODE FÜR DEN PHYSICAL-LAYER case 3: totalpacketlength=95; totalinnerpacketlength=(HEADERLEN)+64+3; break; default: break; } break; case 3: cheader[0] |= 0x1F; //Paketl‰nge auf 128 Bytes setzen for(i=0;i<128;i++)cdata[i] =(ERRORCHECKCHAR); switch(puncmode){ case 0: totalpacketlength=280; totalinnerpacketlength=(HEADERLEN)+128+3; break; case 1: totalpacketlength=176; totalinnerpacketlength=(HEADERLEN)+128+3; break; case 2: totalpacketlength=171; totalinnerpacketlength=(HEADERLEN)+128+3; break; case 3: totalpacketlength=168; totalinnerpacketlength=(HEADERLEN)+128+3; break; default: break; } break; default: for(i=0;i<(ERRORCHECKCOUNT);i++) { packetlen=(int) ((double) rand())/32767*31;//Bestimme Paketl‰nge durch Zufall (liefert Zahl zw. 0 und 31) cheader[0] += (char) packetlen; cout << "\nerrror4"; for(j=0;j<(packetlen+1)*4;j++)cdata[j] =(char) (((double) rand())/32767*255); //Sleep(100); } break; } //Setze Header zusammen cbuffer[0]=(unsigned char) ((BARKERCODE)>>8);//Setze Barkercode an den Anfang cbuffer[1]=(unsigned char) (BARKERCODE); cheader[6]=CRC8(cheader); //Errechne und setze CRC des Headers cheader[7]=TERMINIERUNG; //F¸ge Terminierung an den Header Encode(cheader, &cbuffer[2],(HEADERLEN));//Codiere den Header //Setze Payload zusammen cdatalen=((cheader[0] & 0x1F)+1)*4;//Bestimme L‰nge der Daten tmpcrc=CRC16(cdata,cdatalen); cdata[cdatalen]=(unsigned char) (tmpcrc>>8); cdata[cdatalen+1]=(unsigned char) tmpcrc;//F¸ge CRC16 ein cdata[cdatalen+2]=TERMINIERUNG; Encode(cdata,&cbuffer[(HEADERLEN)*2+2],cdatalen+3);//Codiere die Daten cdatalen=(cdatalen+3)*2; //Neue L‰nge der Daten: (+CRC16, +Terminierung)*Faltungscodierung Puncture(&cbuffer[(HEADERLEN)*2+2],&cdatalen,cheader[0]>>5);//Punktiere die Daten //Print zu vergleichendes Paket if(verbosity>0){ printf("\n\n[Vergleichspaket]\n\nHeader(%i): \t",2+(HEADERLEN)*2); for(i=0;i<( 2+(HEADERLEN)*2 + cdatalen );i++){ if( i==2+((HEADERLEN)*2) ) printf("\nData(%i): \t",cdatalen); if((!(i%18))&&(i>20))printf("\n\t\t"); printf("%2X ", cbuffer[i],i); } } //Abbruch per Tastendruck ¸berwachen KeyPressThread=CreateThread(0,0,KeyPressBreak,0,0,&threadID); GetExitCodeThread(KeyPressThread, &ExitCode); while(1) { packetcount++; EscapeCommFunction(hCom,CLRRTS);//Setze Modem in Empfangsbereitschaft 124 7 QUELLCODE FÜR DEN PHYSICAL-LAYER //Warte auf Events SetCommMask(hCom,EV_RLSD); WaitCommEvent(hCom, &dwEvtMask, &EventCarrierDetect ); i=WaitForMultipleObjects(2,FUPhandle, FALSE, INFINITE);//Warte auf CD- oder Send-Event if(i==1){ //Falls Tastendruck, Abbruch der Funktion ResetEvent(EventKeyBreak); TerminateThread(KeyPressThread, ExitCode);//Abbruchsthread beenden break; } else{ ResetEvent(EventCarrierDetect.hEvent); GetCommModemStatus(hCom,&lpModemStat);//Frage nochmal CarrierDetect ab if(!(lpModemStat & MS_RLSD_ON)) continue;//Falls kein Carrier, Event falsch ausgelˆst, springe zur¸ck } //Bereite Empfang vor printf("\n\n----------- PAKET EMPFANGEN -------------\n"); if(!PurgeComm(hCom,PURGE_RXCLEAR)) ErrorHandler("PurgeComm: error", GetLastError());//Lˆsche Empfangsbuffer GetCommModemStatus(hCom,&lpModemStat);//Frage nochmal CarrierDetect ab //Empfangsschleife while(lpModemStat & MS_RLSD_ON){//Solange CD-Signal, lese byteweise ReadFile(hCom, &rbuffer[t], 1, &bytes_read, &EventReceive); if(WaitForSingleObject(EventReceive.hEvent, 500)==WAIT_TIMEOUT)ErrorHandler("Wait_TimeOut in WaitForSingleObject nach ReadFile: ",GetLastError());; if(!GetOverlappedResult(hCom, &EventReceive, &dummy, TRUE))ErrorHandler("GetOverlappedResult: ",GetLastError()); t++; if(t==RECEIVELEN){ printf("\n‹berlauf des Empfangbuffers!"); break; //Empfangsbuffer darf nicht ¸berlaufen } GetCommModemStatus(hCom,&lpModemStat);//CD-Signal noch vorhanden? } //Bereite Empfang nach if(t<(MINPAKETLEN)){ paketstat.packets_lost_cut++; printf("\nMindest-Paketl‰nge(%i) unterschritten! (%i Bytes) -> Abbruch",(MINPAKETLEN), t); continue; //Weniger als MINPAKETLEN Zeichen ist kein Paket -> weiter } //Printe empfangene Bytes if(verbosity>0){ printf("\n\n[Empfangene Bytes]\n\nBytes(%i): \t",t); for(i=0;i<t;i++){ if((!(i%18))&&(i>2))printf("\n\t\t"); printf("%2X ", rbuffer[i],i); } } //F¸ge Fehler ein (mit Barkersequenz) if((error_rate!=0) && (error_len==0)) AddErrors(rbuffer, t, error_rate); //Framesynchronisierung if(FrameSync(rbuffer, t)!=TRUE){ printf("\nBarkercode nicht gefunden! -> Abbruch"); t=0; continue; //Finde Paketanfang } //F¸ge Fehler ein (ohne Barkersequenz) if((error_rate!=0) && (error_len==1)) AddErrors(rbuffer, t, error_rate); t=0; //Printe empfangenes Paket nach AddErrors if(verbosity>0){ printf("\n\n[Empfangene Paket nach Hinzufuegen von Fehlern]\n\nHeader(%i): \t",2+(HEADERLEN)*2); for(i=0;i<totalpacketlength;i++){ if( i==2+((HEADERLEN)*2) ) printf("\nData(%i): \t",cdatalen); if((!(i%18))&&(i>20))printf("\n\t\t"); printf("%2X ", rbuffer[i],i); } } //Header-Decodierung: HeaderErrors=Decode(rbuffer, rheader, (HEADERLEN)*2, 0); //printf("\nrbuffer:"); for(i=0;i<(HEADERLEN)*2;i++)printf(" %2X", rbuffer[i]); if(CRC8(rheader)==rheader[6]) 125 7 QUELLCODE FÜR DEN PHYSICAL-LAYER printf("\n[CRC8] okay"); else{ paketstat.packets_lost_crc8++; printf("\n[CRC8] nicht okay -> Abbruch"); //printf("\nempfangener CRC %X, berechneter CRC %X", rheader[6], CRC8(rheader)); */ } //Print zu vergleichendes Paket /*if(verbosity>0){ printf("\n\n[CRC8-Vergleich]\n\nHeader(%i): \t",2+(HEADERLEN)*2); for(i=0;i<( 2+(HEADERLEN)*2 + cdatalen );i++){ if( i==2+((HEADERLEN)*2) ) printf("\nData(%i): \t",cdatalen); if((!(i%18))&&(i>20))printf("\n\t\t"); printf("%2X ", rbuffer[i],i); } } //continue; //Daten-Decodierung: rdatalen=((rheader[0] & 0x1F)+1)*4+3; DataErrors=Decode(&rbuffer[(HEADERLEN)*2], rdata, rdatalen*2, rheader[0]>>5); if( CRC16(rdata, rdatalen-3) == (((unsigned short) rdata[rdatalen-3]) <<8) + (unsigned short) rdata[rdatalen-2]) printf("\n[CRC16] okay"); else{ paketstat.packets_lost_crc16++; printf("\n[CRC16] nicht okay -> Abbruch"); //continue; } //Vergleich der inneren Fehlern printf("\ncheader"); for(i=0;i<(HEADERLEN);i++)printf(" %2X", cheader[i]); printf("\nrheader"); for(i=0;i<(HEADERLEN);i++)printf(" %2X", rheader[i]); printf("\ncdata"); for(i=0;i<totalinnerpacketlength-(HEADERLEN);i++)printf(" %2X", cdata[i]); printf("\nrdata"); for(i=0;i<totalinnerpacketlength-(HEADERLEN);i++)printf(" %2X", rdata[i]); innerbiterrors=Compare(cheader, rheader,(HEADERLEN)); innerbiterrors+=Compare(cdata, rdata, totalinnerpacketlength-(HEADERLEN)); totalinnerbiterrors+=innerbiterrors; totalinnersendbytes+=totalinnerpacketlength; //Z‰hle Raw-Bitfehler rawbiterrors = Compare(rbuffer, &cbuffer[2], totalpacketlength-2); totalrawbiterrors += rawbiterrors; totalsendbytes += totalpacketlength; paketstat.packets_correct++; printf("\n\nPaket %i korrekt empfangen! (Pfadkosten: Header: %i, Data: %i)", packetcount, HeaderErrors, DataErrors); printf("\n\nBitfehler:\t\tAktuell:\tKumuliert:"); printf("\nRoh-Bitfehler: \t\t%.f\t\t%.f", rawbiterrors, totalrawbiterrors); printf("\nInnere-Bitfehler: \t%.f\t\t%.f", innerbiterrors, totalinnerbiterrors); printf("\nGesendete Bytes: \t%i\t\t%.f", totalpacketlength, totalsendbytes); printf("\nRoh-Bitfehlerrate: \t%e\t%e", ((float) rawbiterrors)/((float) totalpacketlength)/8, ((float) totalrawbiterrors)/((float) totalsendbytes)/8); printf("\nInnere-Bitfehlerrate: \t%e\t%e", ((float) innerbiterrors)/((float) totalinnerpacketlength) /8, ((float) totalinnerbiterrors)/((float) totalinnersendbytes)/8); } system("cls"); printf("\n--------------------------FEHLER-STATISTIK--------------------\n"); printf("\nRoh-Bitfehler: \t\t\t%.f", totalrawbiterrors); printf("\nInnere-Bitfehler: \t\t\t%.f", totalinnerbiterrors); printf("\nGesendete Bytes: \t\t%.f", totalsendbytes); printf("\nNutzbytes:\t\t\t%.f", totalinnersendbytes); printf("\nRoh-Bitfehlerrate: \t\t%e", ((float) totalrawbiterrors)/((float) totalsendbytes)/8); printf("\nInnere-Bitfehlerrate:\t\t%e\n", ((float) totalinnerbiterrors)/((float) totalinnersendbytes)/8); printf("\n\nFehlerhafte Pakete:\nHeader-CRC:\t\t\t%i",paketstat.packets_lost_crc8); printf("\nDaten-CRC:\t\t\t%i",paketstat.packets_lost_crc16); printf("\nzu kurze Pakete:\t\t%i",paketstat.packets_lost_cut); printf("\nkeine Barkersequenz gefunden:\t%i",paketstat.packets_lost_barker); printf("\nkorrekte Pakete:\t\t%i",paketstat.packets_correct); printf("\n\n--------------------------------------------------------------\n"); TerminateThread(KeyPressThread, ExitCode);//Abbruchsthread beenden } //********************************************************************************************* //////////////////////////////// // Hauptprogramm //////////////////////////////// void main(int argc, char* argv[]) { 126 7 QUELLCODE FÜR DEN PHYSICAL-LAYER char mode; //GenerateTrellis(); //Berechne Trellis //srand( (unsigned)time( NULL ) );//Initialisiere Zufallsprozess mit aktueller Zeit system("cls"); printf("\n printf("\n printf("\n printf("\n printf("\n printf("\n printf("\n printf("\n printf("\n //Lˆsche Bildschirm P O W E R L I N E C O M M U N I C A T I O N"); via AMS-Modem"); "); Physical Layer Implementierung"); "); Diplomarbeit"); von"); Denis Geiter"); (Oktober 2002)"); while(mode!='q') { printf("\n\n[c] - Chatmodus\n[m] - Monitormodus\n[s] - Testbetrieb Sendemodus\n[e] - Testbetrieb Empfangsmodus\n[q] - Ende\n\nAuswahl?: "); cin >> mode; //Auswahl des Betriebsmodus switch(mode){ case 'c': system("cls"); //Lˆsche Bildschirm printf("C H A T M O D U S\n\n[Return] - Absenden der Message\n[q + Return] - Zurueck zum Hauptmenue\n\n"); verbosity=0; PHY_Init(2); system("cls"); //Lˆsche Bildschirm break; case 'm': system("cls"); //Lˆsche Bildschirm verbosity=2; printf("M O N I T O R M O D U S\n\n[Return] - Absenden der Message\n[q + Return] - Zurueck zum Hauptmenue"); PHY_Init(2); system("cls"); //Lˆsche Bildschirm break; case 's': system("cls"); //Lˆsche Bildschirm verbosity=1; PHY_TestSend(2); CloseComPort(); break; case 'e': system("cls"); //Lˆsche Bildschirm verbosity=1; OpenComPort(2); PHY_TestReceive(2); CloseComPort(); break; case 'q': system("cls"); //Lˆsche Bildschirm printf("P R O G R A M M E N D E \n\nBye!\n\n"); break; default: system("cls"); //Lˆsche Bildschirm printf("C H A T M O D U S\n\n[Return] - Absenden der Message\n[q + Return] - Zurueck zum Hauptmenue\n\n"); verbosity=0; PHY_Init(2); system("cls"); //Lˆsche Bildschirm break; } } } 127 8 LITERATURVERZEICHNIS 8 Literaturverzeichnis [1] Poly-Trax, www.polytrax.de [2] Cenelec, www.cenelec.org [3] J.G. Proakis, “Digital Communications“, McGraw-Hill, 1995 [4] Cogency, www.cogency.com [5] Inari, www.inari.com [6] Adaptive Networks, www.adaptivenetworks.com [7] Itran Communications Ltd., www.itrancomm.com [8] ITM1-B, “Power Line Modem Product Brief”, ITM1B-DS-010-R1.3 [9] Austria Mikro Systeme, www.austriamicrosystems.com [10] Echelon, www.echelon.com [11] EN50065-1, “Signalübertragung auf elektrischen Niederspannungsnetzen im Frequenzbereich 3 bis 148 kHz”, CENELEC, Genf, Juli 1993 [12] J.G. Proakis, "Digital Communications", McGraw-Hill, 1995 [13] K. D. Kammeyer, “Nachrichtenübertragung”, B. G. Teubner Stuttgart, 1992 [14] K. Dostert, “Powerline Kommunikation”, Franzis’ Verlag, 2000 [15] S. Eiffes, “Wireless LAN Beschreibung und Untersuchung der Übertragungseigenschaften eines Wireless LAN Systems aufbauend auf dem IEEE 802.11 Standard”, Universität Kaiserslautern, Juni 2000 [16] A. J. Viterbi, "Error Bounds for Convolutional Codes and an Asymptotically Optimum Decoding Algorithm", IEEE Transactions on Information Theory, April 1967 [17] Microsoft Developer Network (MSDN), www.microsoft.com/msdn [18] A. Denver, “Serial Communication in Win32”, MSDN, Dezember 1995 128 8 LITERATURVERZEICHNIS [19] “Frequenzbereichszuweisungsplanverordnung - FreqBZPV”, Teil B: Nutzungsbestimmungen, www.bmwi.de/Homepage/download/telekommunikation_post/ FreqBZPV-TeilB1.pdf [20] D. Haccoun, G. Bégin, “High-Rate Punctured Convolutional Codes for Viterbi and Sequential Decoding”, IEEE Transactions on Communications, November 1989. [21] Rupprecht, “Grundlagen der digitalen Signalverarbeitung”, 1975 [22] R. Bräumer, “USB-basierte Kommunikationsschnittstelle für ein OFDMSystem zur schnellen Datenübertragung über Stromnetze”, Diplomarbeit am Institut für Industrielle Informationstechnik der Universität Karlsruhe, November 2000 [23] Intellon Corporation, “PowerPacket Primer”, White Paper [24] D. Wenzel, “Digital Audio Broadcasting”, Elrad, 1996, Heft 2 [25] Heise-Newsticker, “EnBW startet Powerline auf Testmarkt”, 23.3.2001 [26] PolyTrax, “Technische Beschreibung PolyTrax -Verfahren“, Januar 2000 [27] D. Williams, “Turbo Product Code Tutorial“, Mai 2000, grouper.ieee.org/groups/802/16/tutorial/80216t-00_01.pdf [28] P. Gerdsen, “Kommunikationssysteme 2”, Springer-Verlag, 1994 [29] M. Bossert, “Kanalcodierung”, Teubner-Verlag, 1998 [30] W. Henkel, “Theorie und Verfahren der fehlerkorrigierenden Kanalcodierung”, Universität Kaiserslautern, WS 1997/98 [31] PolyTrax, “Technische Beschreibung des PolyTrax Verfahren”, Januar 2000 [32] Ross N. Williams, „A painless guide to CRC error detection algorithms“, August 1993 [33] B. Friedrichs, „Kanalcodierung - Grundlagen und Anwendungen in modernen Kommunikationssystemen“, November 1995 129 8 LITERATURVERZEICHNIS [34] Embedded Systems Programming, „Computational parameters for popular CRC standards“, www.embedded.com/internet/0001/0001contable1.htm [35] J. Geluso, „CRC16-CCITT“, August 2001, www.joegeluso.com/software/articles/ccitt.htm 130 9 GLOSSAR 9 Glossar ARQ - Automatic Repeat Request. Eine Art der Fehlerkontrolle, bei der Pakete mit fehlerhafeter Prüfsumme erneut angefordert werden. BPSK - Binary Phase Shift Keying. Modulationsart mit reiner Urzeichenumtastung. BER - Bit Error Rate - Bitfehlerrate CENELEC - Commitee Europeenne de Normalisation Electrotechnique. Dieses europäische Kommitee für Normung in der Elektrotechnik fasst die diversen nationalen Normungsgremien zusammen. Es wurde 1973 unter belgischem Recht gegründet und verfolgt keine kommerziellen Ziele. COFDM - Coded Orthogonal Frequency Division Multiplexing. Kombination aus FEC und OFDM. DSP - Digitaler Signalprozessor. DSPs verfügen über einen sehr kleinen Befehlssatz, können diesen aber auf einen fortlaufenden Datenstrom in Echtzeit anwenden. Sie werden unter anderem zur Echtzeit-Manipulation von Audio- und Videodaten eingesetzt. ETSI - Das European Telecommunications Standards Institute ist eine nicht-kommerzielle Organisation, deren Aufgabe es ist, Telekommunikationsstandards aufzustellen, die dauerhaft in europäischen Ländern gelten. FCC - Federal Communications Commission. Die FCC ist eine unabhängige amerikanische Regulierungsbehörde, welche direkt dem amerikanischem Kongress unterstellt ist. Sie wurde 1934 gegründet, um die nationale Kommunikation via Radio, Fernsehen, Kabel und Satellit zu regulieren. Ihre Regeln gelten in den 50 Bundesstaaten der USA, im Distrikt Columbia und in den U.S. Besitztümern. FEC - Forward Error Correction. Fehlerkorrektur. Bei FEC werden im Gegensatz zu ARQ keine Pakete wiederholt. Die Anzahl korrigierbarer Fehler hängt von der Redundanz der gesendeten Information ab. Die FEC-Coderate ist gleich der Anzahl der Informations-Symbole vor der Encodierung geteilt durch die Anzahl der Kanal-Symbole nach der Encodierung. HomePlug - Spezifikation der HomePlug Powerline Alliance, einer Gruppe von Firmen der Netzwerkbranche, für Powerline-Produkte. MAC - Media Access Control. Zugriffssteuerung auf das Medium. Teil von OSI-Layer 2. Die MAC-Adresse (Quell- und Zieladresse) bei Ethernet nach IEEE 802 ist eine 48 Bit lange weltweit eindeutige Netzwerkkartenadresse. 131 9 GLOSSAR Mbit/s - Megabits per second. Maß für Datenübertragungsrate. OFDM - Orthogonal Frequency Division Multiplex. Bei der orthogonalen Frequenzmultiplex -Technik handelt es sich um ein Verfahren, das mehrere Trägerfrequenzen für die Übertragung eines Digitalsignals benutzt. Diese Trägerfrequenzen werden allerdings nur mit einer verringerten Übertragungsrate moduliert. Zu diesem Zweck wird bei OFDM das zur Verfügung stehende Frequenzband in mehrere Trägerbänder unterteilt. PHY - Physical Layer. Die unterste Ebene im ISO-sieben-Ebenen-Modell. Es beinhaltet auch die elektrischen und mechanischen Verbindungen. Beispiele eines Physical Layers sind CSMA-CD und Token-Ring. PLC - Powerline Communications. Sammelbegriff für Techniken zur Datenübertragung via Stromversorgungsnetz. PNC - Powerline Network Connection PNR - Powerline Network Repeater PNT - Powerline Network Termination PNU - Powerline Network Unit QAM - Quadrature Amplitude Modulation. Modulationsverfahren, das mehrere Bit mit einem Symbol übertragen kann. Bei n-QAM werden Phase und Amplitude verändert, sodass n Zustände möglich sind. QoS - Quality of Service - Bei Kommunikationsdiensten und -netzen bezeichnet es die relevanten Güteparameter des betreffenden Dienstes oder Netzes. QPSK - Quadrature Phase Shift Keying - Modulationsverfahren mit Sinus- und Cosinusträgern. Enspricht 4-QAM. 132