Einchipmikrorechner und Signalprozessoren: Unterschied zwischen den Versionen
Sonne (Diskussion | Beiträge) |
Pegro (Diskussion | Beiträge) K |
||
(36 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
+ | Für die Gemeinsamkeiten und Unterschiede von EµR und DSP gibt es eine [[Einchipmikrorechner und Signalprozessoren/Zusammenfassung|Zusammenfassung]]. | ||
+ | |||
+ | Wer schon alles gelernt hat, kann sein Wissen mit [[Einchipmikrorechner_und_Signalprozessoren/Testfragen|Testfragen]] überprüfen. | ||
+ | |||
__TOC__ | __TOC__ | ||
Zeile 10: | Zeile 14: | ||
=== Gemeinsamkeiten === | === Gemeinsamkeiten === | ||
− | * '''Einchip-Konzept''': wesentliche Bauteile alle auf einem Chip (CPU, Speicher, | + | * '''Einchip-Konzept''': wesentliche Bauteile alle auf einem Chip (CPU, Speicher, I/O, Taktgeber) |
* '''minimierte (minimale) Außenbeschaltung''': Abblockkondensator, Quarz | * '''minimierte (minimale) Außenbeschaltung''': Abblockkondensator, Quarz | ||
− | * '''autonomer Betrieb''': Unbeaufsichtigter Betrieb, ohne (nur mit applikationsspezifischem) Bedienereingriff | + | * '''autonomer Betrieb''': Unbeaufsichtigter Betrieb, ohne (bzw. nur mit applikationsspezifischem) Bedienereingriff |
* '''aufgabenspezifisch angepasst''': "Nur soviel (Hardware) wie nötig" | * '''aufgabenspezifisch angepasst''': "Nur soviel (Hardware) wie nötig" | ||
* '''große Typenfamilien''': viele Typen mit jeweils mehreren Ausführungen, Unterschiede in Speicher/Pins | * '''große Typenfamilien''': viele Typen mit jeweils mehreren Ausführungen, Unterschiede in Speicher/Pins | ||
Zeile 35: | Zeile 39: | ||
| '''Besondere Befehle''' || Bit-Befehle,<br> Bit-Adressierung || MAC (Multiplikation und Addition in einem Befehl),<br> zirkuläre Adressierung,<br> Saturation (Festkomma-Arithmetik) | | '''Besondere Befehle''' || Bit-Befehle,<br> Bit-Adressierung || MAC (Multiplikation und Addition in einem Befehl),<br> zirkuläre Adressierung,<br> Saturation (Festkomma-Arithmetik) | ||
|- | |- | ||
− | | '''Typische Anwendungen''' || Steuergeräte in Industrie und Kraftfahrzeugtechnik, <br> Haushaltselektronik, <br> tragbare Geräte (MP3, Handy)|| digitale Filter/Regler, <br> Bildverarbeitung und Mustererkennung, <br> Messgeräte, Messtechnik, <br> Audioeffektgeräte, Modems|} | + | | '''Typische Anwendungen''' || Steuergeräte in Industrie und Kraftfahrzeugtechnik, <br> Haushaltselektronik, <br> tragbare Geräte (MP3, Handy)|| digitale Filter/Regler, <br> Bildverarbeitung und Mustererkennung, <br> Messgeräte, Messtechnik, <br> Audioeffektgeräte, Modems |
+ | |} | ||
+ | |||
+ | == Bauteile == | ||
=== Rechnerkern === | === Rechnerkern === | ||
* RISC oder CISC | * RISC oder CISC | ||
− | * Harvard oder von Neumann | + | * Harvard oder von-Neumann (Princeton) |
− | * viele | + | * viele Spezial(funktions)register (SFR) |
− | * allg. Register häufig verbunden mit | + | * allg. Register häufig verbunden mit internem RAM |
=== Speicher === | === Speicher === | ||
Zeile 68: | Zeile 75: | ||
* FLASH-EEPROM | * FLASH-EEPROM | ||
* FRAM | * FRAM | ||
− | * " | + | * "Bondout" |
* "ROM-less" | * "ROM-less" | ||
Zeile 75: | Zeile 82: | ||
<graphviz> | <graphviz> | ||
digraph G { | digraph G { | ||
− | "Ein- und Ausgabe" -> " | + | "Ein- und Ausgabe" -> "digital, Standard"; |
"Ein- und Ausgabe" -> "analog"; | "Ein- und Ausgabe" -> "analog"; | ||
"Ein- und Ausgabe" -> "speziell"; | "Ein- und Ausgabe" -> "speziell"; | ||
− | " | + | "digital, Standard" -> "parallel"; |
− | " | + | "digital, Standard" -> "seriell"; |
"seriell" -> "synchron"; | "seriell" -> "synchron"; | ||
Zeile 97: | Zeile 104: | ||
</graphviz> | </graphviz> | ||
− | === Sonstiges === | + | === Sonstiges ("Hilfs"-baugruppen)=== |
* Reset | * Reset | ||
* Takt | * Takt | ||
− | * | + | * Powermanagement |
* Interruptsystem | * Interruptsystem | ||
* DMA | * DMA | ||
Zeile 112: | Zeile 119: | ||
= Mikrocontroller am Beispiel der C166 Familie = | = Mikrocontroller am Beispiel der C166 Familie = | ||
+ | * von Siemens, später Infineon | ||
* 16bit Datenbreite | * 16bit Datenbreite | ||
− | * CISC | + | * CISC-Kern (eigentlich RISC, hat aber einige Erweiterungen) |
* Intelähnlicher Befehlssatz | * Intelähnlicher Befehlssatz | ||
− | * von | + | * von-Neumann-Architektur |
− | * bis 30 Mhz Taktfrequenz | + | * typischerweise bis 30 Mhz Taktfrequenz |
− | * | + | * Adressbreite 16bit (mit Segmentierung 24bit) |
* Mehrfachnutzung von Pins | * Mehrfachnutzung von Pins | ||
− | == | + | == Befehlssatzarchitektur == |
− | |||
=== Allgemeiner Registersatz === | === Allgemeiner Registersatz === | ||
− | * | + | * 16x16bit Register R0-R15 |
− | * | + | * Register R0-R7 lassen sich auch über H und L ansprechen |
=== Spezialfunktionsregister (SFR) === | === Spezialfunktionsregister (SFR) === | ||
Zeile 133: | Zeile 140: | ||
u.a. in: | u.a. in: | ||
* Prozessorkern | * Prozessorkern | ||
− | * | + | * Peripherieeinheiten |
* Interruptsystem | * Interruptsystem | ||
* Chipsteuerung | * Chipsteuerung | ||
Zeile 141: | Zeile 148: | ||
==== SFR im Prozessorkern ==== | ==== SFR im Prozessorkern ==== | ||
− | * PSW ( | + | * PSW (processor status word, "Flagregister"), 16bit breit |
− | :Beispiele für | + | :Beispiele für Flags: |
: Statusflags: | : Statusflags: | ||
:* C: Carry ''(Übertrag)'' | :* C: Carry ''(Übertrag)'' | ||
:* V: Overflow ''(Überlauf)'' | :* V: Overflow ''(Überlauf)'' | ||
:* Z: Zero | :* Z: Zero | ||
− | :* N: | + | :* N: Negative |
:* ... | :* ... | ||
: Steuerflags: | : Steuerflags: | ||
:* IEN: Interrupt Enable | :* IEN: Interrupt Enable | ||
− | :* | + | :* USR0: frei verfügbar |
* SP (Stackpointer) | * SP (Stackpointer) | ||
− | * STKUV (Stackunderflow) | + | * STKUV (Stackunderflow, untere Adressgrenze) |
− | * STKOV (Stackoverflow) | + | * STKOV (Stackoverflow, obere Adressgrenze) |
* SYSCON: Systemkonfiguration | * SYSCON: Systemkonfiguration | ||
* ... | * ... | ||
=== Speichermodell === | === Speichermodell === | ||
+ | |||
+ | * von-Neumann: '''ein''' Adressraum | ||
+ | :* interner ROM | ||
+ | :* interne RAMs | ||
+ | :* SFRs (reservierte Speicheradressen) | ||
+ | :* allgemeine Register (lassen sich im Speicherbereich verschieben -> Kontextwechsel sehr schnell möglich) | ||
+ | :* reservierte Bereiche | ||
+ | * Rest: verwendbar für externen Speicher | ||
==== kleines Speichermodell ==== | ==== kleines Speichermodell ==== | ||
+ | |||
+ | * '''nicht segmentiert''' | ||
+ | * logische 16 Bit-Adresse wird umgesetzt auf physikalische 16 Bit-Adresse | ||
+ | * ''Speicherraum:'' <math>2^{16}</math> Byte = 64 KiByte | ||
==== großes Speichermodell ==== | ==== großes Speichermodell ==== | ||
− | ===== | + | * ''' segmentiert''' |
+ | * logische 16 Bit-Adresse erhält zusätzliche Segmentbeschreibung (Länge variiert) | ||
+ | * wird ungeformt auf physikalische 24 Bit-Adresse | ||
+ | *''Speicherraum:'' <math>2^{24}</math> Byte = 16 MiByte | ||
+ | |||
+ | Vorteil: | ||
+ | * mehr Speicherplatz | ||
+ | * Segment = Grobpositionierung | ||
+ | :* Änderung davon seltener (wird nicht bei jedem Zugriff geändert) | ||
+ | |||
+ | ===== Segmentierter Datenzugriff ===== | ||
+ | |||
+ | [[Bild:Segemntierter Datenzugriff.jpg]] | ||
+ | |||
+ | ===== Segmentierter Programmzugriff ===== | ||
− | + | [[Bild:Segmentierter Programmzugriff.jpg]] | |
− | ===== | + | ===== Adressraumstruktur ===== |
+ | |||
+ | * 000000H - 00FFFFH -> 64KiByte des nichtsegmentierten Bereichs | ||
+ | * Datenseite jeweils 16 KiByte groß (10bit Data Page Pointer [SFR]) | ||
+ | * Codeseite jeweils 64 KiByte groß (8bit Code Segement Pointer [SFR]) | ||
===== Allgemeine Register: Mapping in den Speicherraum ===== | ===== Allgemeine Register: Mapping in den Speicherraum ===== | ||
− | + | * 32 Byte allgemeine Register | |
+ | * können im Speicherbereich verschoben werden | ||
+ | * CP (context pointer, 10bit) zeigt auf erstes Register (R0) | ||
+ | * ermöglicht sehr einfachen Kontextwechsl ohne Umkopieren durch Verschieben des Registerbereichs | ||
+ | * schnell, grade für Echtzeitanwendungen; z.B. bei Interruptbehandlung | ||
+ | |||
+ | == Befehlssatz == | ||
=== Transportbefehle === | === Transportbefehle === | ||
+ | |||
+ | * MOV ''Ziel'' , ''Quelle'' : Wort | ||
+ | * MOV B ''Ziel'' , ''Quelle'' : Byte | ||
+ | |||
+ | * MOV BZ ''Ziel'' , ''Quelle'' : Wort <- Byte (Null auffüllen) | ||
+ | * MOV BS ''Ziel'' , ''Quelle'' : Wort <- Byte (Vorzeichen auffüllen) | ||
+ | ermöglichen arithmetisch korrekte Expansion von 8 auf 16bit | ||
+ | |||
+ | * MOV ''Register'' , ''Register'' | ||
+ | * MOV ''Register'' , ''#Zahlenwert'' // Konstante | ||
+ | * MOV ''Register'' , ''Zahlenwert'' // direkt | ||
+ | * MOV ''Register'' , ''[Register]'' // indirekt | ||
+ | * MOV ''[Register]'' , ''Register'' | ||
+ | * MOV ''Register'' , ''[Register+#Index]'' | ||
+ | * MOV ''Register'' , ''[Register+]'' // postdekrement um 2 | ||
+ | * MOV ''[+Register]'' , ''Register'' // preinkrement um 2 | ||
+ | * MOV ''[Register]'' , ''[Register]'' // nicht universell! | ||
+ | |||
+ | * Zahlenwerte mit # kennzeichnen sonst Speicheradresse | ||
+ | * Variablenangabe statt Zahlenwert für Adresse möglich | ||
=== Stackbefehle === | === Stackbefehle === | ||
+ | |||
+ | * PUSH ''Quelle'' -> Ziel = Stack | ||
+ | :* Stackpointer geht 1 Speicherplatz nach unten (SP = SP - 2) und kopiert dann erst Inhalt aus Register in Stack | ||
+ | * POP ''Ziel'' -> Quelle = Stack | ||
+ | :* Wert aus Stack wird gelesen und in Register geschrieben, dann geht Stackpointer 1 Speicherplatz nach oben (SP = SP + 2) | ||
+ | |||
+ | * Befehle gelten nur für 16 Bit Register | ||
+ | * LIFO-Prinzip beim Daten retten beachten | ||
+ | * Stack-Befehle müssen ausbalanciert sein (sonst Über-/Unterlauf) | ||
+ | * Stackgrenzen können festgelegt werden | ||
+ | * wenn der Stack über- oder unterläuft wird an eine Handleradresse gesprungen (Interrupt) | ||
=== Arithmetik/Logik === | === Arithmetik/Logik === | ||
+ | |||
+ | {| | ||
+ | |16 Bit Befehle || || 8 Bit Befehle || || Bemerkung | ||
+ | |- | ||
+ | |ADD || || ADD B || || | ||
+ | |- | ||
+ | |ADD C || || ADD C B || || Wert des Carry-Flags mit addieren | ||
+ | |- | ||
+ | |SUB || || SUB B || || | ||
+ | |- | ||
+ | |SUB C || || SUB C B || || Wert des Carry-Flags mit subtrahieren | ||
+ | |- | ||
+ | |AND || || AND B || || bitweise | ||
+ | |- | ||
+ | |OR || || OR B || || bitweise | ||
+ | |- | ||
+ | |XOR || || XOR B || || bitweise | ||
+ | |- | ||
+ | |CMP || || CMP B || || beeinflusst nur Flags | ||
+ | |- | ||
+ | |NEG || || NEG B || || Vorzeichen-Wechsel (2er-Komplement) | ||
+ | |- | ||
+ | |CPL || || CPL B || || Bitweise Negation (1er-Komplement) (1->0 , 0->1) | ||
+ | |} | ||
=== Multiplikation/Division === | === Multiplikation/Division === | ||
+ | |||
+ | * MD - separates 32 Bit Register für Multiplikation/Division | ||
+ | * MDH , MHL = SFR | ||
+ | * Vorzeichenbehaftet - MUL | ||
+ | * Vorzeichenlos - MUL U | ||
+ | * Operationen nur mit Registern möglich | ||
+ | |||
+ | |||
+ | * DIV / DIV U -> MDL (16bit) : Op (16bit) = MDL (16bit) Rest: MDH (16bit) | ||
+ | * DIV L / DIV L U -> MD (32bit) : Op (16bit) = MDL (16bit) Rest: MDH (16bit) -> arithm. Überlauf möglich | ||
+ | |||
+ | |||
+ | * MD-Register wieder frei räumen vor neuer Multiplikation/Division | ||
=== Schieben/Rotieren === | === Schieben/Rotieren === | ||
+ | |||
+ | * nur für 16 bit Register | ||
+ | |||
+ | {| border = 0 | ||
+ | | Links || Rechts || || Bemerkungen | ||
+ | |- | ||
+ | | SHL ''Register'', ''Zahlenwert'' || SHR ''Register'', ''Zahlenwert'' || <graphviz> | ||
+ | digraph G { | ||
+ | rankdir = LR; | ||
+ | node [shape = record, width = 0.1, height = 0.1]; | ||
+ | |||
+ | Null [label = "0"]; | ||
+ | subgraph "cluster Register" { | ||
+ | rankdir = LR; | ||
+ | 15 -> "..." -> 0; | ||
+ | } | ||
+ | Carry [label = "CF"]; | ||
+ | |||
+ | Null -> 15; | ||
+ | 0 -> Carry; | ||
+ | } | ||
+ | </graphviz> | ||
+ | |- | ||
+ | | - || ASHR ''Register'', ''Zahlenwert'' || <graphviz> | ||
+ | digraph G { | ||
+ | rankdir = LR; | ||
+ | node [shape = record, width = 0.1, height = 0.1]; | ||
+ | |||
+ | subgraph "cluster Register" { | ||
+ | rankdir = LR; | ||
+ | 15 -> "..." -> 0; | ||
+ | } | ||
+ | Carry [label = "CF"]; | ||
+ | |||
+ | 15 -> 15; | ||
+ | 0 -> Carry; | ||
+ | } | ||
+ | </graphviz> || Vorzeichenbehaftete Division durch 2 | ||
+ | |- | ||
+ | | ROL ''Register'', ''Zahlenwert'' || ROR ''Register'', ''Zahlenwert'' ||<graphviz> | ||
+ | digraph G { | ||
+ | rankdir = LR; | ||
+ | node [shape = record, width = 0.1, height = 0.1]; | ||
+ | |||
+ | subgraph "cluster Register" { | ||
+ | rankdir = LR; | ||
+ | 15 -> "..." -> 0 [weight = 100]; | ||
+ | } | ||
+ | Carry [label = "CF"]; | ||
+ | |||
+ | 0 -> 15; | ||
+ | 0 -> Carry [weight = 0]; | ||
+ | } | ||
+ | </graphviz> | ||
+ | |} | ||
=== Steuerfluss-Befehle === | === Steuerfluss-Befehle === | ||
==== Sprungbefehle ==== | ==== Sprungbefehle ==== | ||
+ | |||
+ | Wir unterscheiden '''Intrasegment''' und '''Intersegment''' Sprünge | ||
+ | |||
+ | Nur der IP (Instruction Pointer) wird geändert beim: | ||
+ | * segmentierten Modell (Sprung im Segment) | ||
+ | * nicht segmentierten Modell | ||
+ | |||
+ | Sowohl der IP (Instruction Pointer) als auch der CSP (Code Segment Pointer) wird geändert beim: | ||
+ | * segmentierten Modell (Sprung zwischen Segmenten) | ||
===== Intrasegment ===== | ===== Intrasegment ===== | ||
+ | |||
+ | {| | ||
+ | | || Direkt || Indirekt | ||
+ | |- | ||
+ | | Absolut || JMPA || JMPI | ||
+ | |- | ||
+ | | Relativ || JMPR || - | ||
+ | |} | ||
+ | |||
+ | JMPA ''Condition Code'', ''Label'' | ||
+ | JMPR ''Condition Code'', ''Label'' | ||
+ | JMP ''Condition Code'', ''Label'' // Assembler entscheidet sich für absoluten oder relativen Sprung | ||
+ | JMPI cc_UC, [R4] // IP = [R4] | ||
+ | |||
+ | ===== Condition Code ===== | ||
+ | |||
+ | cc_UC: unconditional (unbedingt, immer!) | ||
+ | cc_NC: not carry | ||
+ | cc_C : carry | ||
+ | cc_NZ: not zero | ||
+ | cc_Z : zero | ||
+ | cc_EQ: eqal (entspricht cc_Z) | ||
+ | cc_NE: not eqal (entspricht cc_NZ) | ||
+ | cc_V : overflow | ||
+ | cc_NV: not overflow | ||
+ | cc_SLT: signed less than | ||
+ | cc_UGE: unsigned greater eqals | ||
+ | |||
+ | Vergleiche: <math>\underbrace{< > \le \le}_\mathrm{vzb/vzl} = \ne</math> werden aud dem Flags: C, Z, V und N gebildet | ||
===== Intersegment ===== | ===== Intersegment ===== | ||
+ | |||
+ | * nur absolut, direkt, unbedingt | ||
+ | |||
+ | JMP SEG ''Label'', SOF ''Label'' | ||
+ | \___ __/ \___ __/ | ||
+ | \/ \/ | ||
+ | Segment Offset | ||
+ | (CSP) (IP) | ||
+ | \________ ________/ | ||
+ | \/ | ||
+ | ergibt die 24bit-Speicheraddresse | ||
==== Unterprogrammbefehle ==== | ==== Unterprogrammbefehle ==== | ||
+ | |||
+ | ===== Intrasegment ===== | ||
+ | |||
+ | CALLA ''Condition Code'', ''Label'' // IP -> Stack | ||
+ | CALLR ''Condition Code'', ''Label'' // IP -> Stack | ||
+ | CALL ''Condition Code'', ''Label'' // IP -> Stack, wird vom Assembler auf CALLA bzw. CALLR umgesetzt | ||
+ | CALLI ''Condition Code'', ''Label'' // IP -> Stack | ||
+ | |||
+ | RET // Stack -> IP | ||
+ | |||
+ | ===== Intersegment ===== | ||
+ | |||
+ | CALLS ''Condition Code'', ''Label'' // IP und CSP -> Stack | ||
+ | |||
+ | RETS // Stack -> IP und CSP | ||
+ | |||
+ | Die Verwendung von RET bzw. RETS entscheidet darüber, ob eine Funktion aus einem anderem Segment erreichbar ist. | ||
=== Bit-Befehle === | === Bit-Befehle === | ||
+ | |||
+ | * Bitaddressierbare Bereiche: | ||
+ | ** 3x256 Byte im internen RAM | ||
+ | ** 1x256 Byte SFR | ||
+ | ** macht 1024x8 bit = 8 KiBit = Bitaddressierung | ||
+ | ** 13bit Zellenadresse + 3bit Bitadresse = 16bit | ||
+ | ** wenn Offset > 8, dann Adresse der nächsten Zelle + Offset MOD 8 als Offset | ||
+ | |||
+ | Beispiele für Bitadressen: | ||
+ | 0FF10H.1 // (0-7) oder (0-15) mgl. \ | ||
+ | PSW.1 // > sind alle äquivalent | ||
+ | C // / | ||
+ | |||
+ | BMOV ''Zielbitadresse'', ''Quellbitadresse'' | ||
+ | BMOVN ''Zielbitadresse'', ''Quellbitadresse'' | ||
+ | |||
+ | BAND ''Zielbitadresse'', ''Quellbitadresse'' | ||
+ | BOR ''Zielbitadresse'', ''Quellbitadresse'' | ||
+ | BXOR ''Zielbitadresse'', ''Quellbitadresse'' | ||
+ | |||
+ | BCMP ''Zielbitadresse'', ''Quellbitadresse'' | ||
+ | |||
+ | BCLR ''Bitadresse'' | ||
+ | BSET ''Bitadresse'' | ||
+ | |||
+ | * Bedingte Sprünge mit Bits nur intrasegment, direkt | ||
+ | |||
+ | JB ''Bitadresse'', ''Label'' // Bit gesetzt | ||
+ | JNB ''Bitadresse'', ''Label'' // Bit nicht gesetzt | ||
+ | |||
+ | "Test & Set" Befehle (atomar, für Parallelprogrammierung): | ||
+ | JBC ''Bitadresse'', ''Label'' | Bit gesetzt, zurücksetzen (CLEAR) | ||
+ | JNBS ''Bitadresse'', ''Label'' | Bit nicht gesetzt, setzen (SET) | ||
=== Sonstige Befehle === | === Sonstige Befehle === | ||
+ | |||
+ | <source lang=asm> | ||
+ | NOP ; No Operation | ||
+ | SRST ; Softwarereset | ||
+ | PWRDW ; Schlafzustand aktivieren | ||
+ | EINIT ; Ende der Initalisierung | ||
+ | ; Privelegierte Einstellungen können nicht mehr | ||
+ | ; verändert werden (wie z.B. Stackgrenzen) | ||
+ | </source> | ||
== SW-Entwicklung == | == SW-Entwicklung == | ||
+ | |||
+ | Cross-Tools: (z.B. Programmierung auf PC für nicht PC-Zielsystem) | ||
+ | |||
+ | Tool-Chain: (Werkzeugkette) | ||
+ | |||
+ | IDE: (Integrated Development Enviroment) | ||
+ | |||
+ | <graphviz> | ||
+ | digraph G { | ||
+ | rankdir = LR; | ||
+ | node [fontsize = 11, width = 0.1, heigth = 0.1]; | ||
+ | edge [fontsize = 11]; | ||
+ | |||
+ | IDE [shape = box, label = "Interaktives\nKonfigurations\nWerkzeug\n\n\"DAVE\"", color = green4, fontcolor = green4]; | ||
+ | |||
+ | ASM [shape = box, label = ".asm\nAssembler-\nQuelltext"]; | ||
+ | XASM [shape = ellipse, label = "Cross-\nAssembler"]; | ||
+ | AOBJ [shape = box, label = ".obj\nObjekt"]; | ||
+ | |||
+ | C [shape = box, label = ".c\nC-Quell-\ntext"]; | ||
+ | XCMP [shape = ellipse, label = "Cross-\nCompiler"]; | ||
+ | COBJ [shape = box, label = ".obj\nObjekt"]; | ||
+ | |||
+ | LIB [shape = box, label = ".lib\nBiblio-\ntheken"]; | ||
+ | |||
+ | XLNK [shape = ellipse, label = "Cross-\nLinker"]; | ||
+ | OUT [shape = box, label = ".out\nVerbunden-\nes Objekt"]; | ||
+ | XLOC [shape = ellipse, label = "Cross-\nLocator"]; | ||
+ | ABS [shape = box, label = ".abs\nAbsolutes\nObjekt"]; | ||
+ | |||
+ | { node [shape = none, fontcolor = gray]; | ||
+ | HINT1 [label = "noch keine endgültigen\nAddressen"]; | ||
+ | HINT2 [label = "Vorgefertigte Module"]; | ||
+ | HINT3 [label = "- endgültige Addressen\n- Reffenzen aufgelößt \n- Maschinencode "]; | ||
+ | } | ||
+ | |||
+ | labeljust = l; | ||
+ | USE [shape = box, label = "- Befehlssatz-Simulator\n- Remote Debugging \n- In-Circute-Emulation;\n JTAG (IEEE 1149.1) \n- Programmiergerät ", color = orange3]; | ||
+ | |||
+ | {rank = 0; IDE} | ||
+ | {rank = same; ASM; C; LIB; HINT2; OUT; HINT3} | ||
+ | {rank = same; AOBJ; HINT1; COBJ} | ||
+ | |||
+ | IDE -> ASM [style = invis, weight = 0]; // Workaround zur Anordnung der Elemente | ||
+ | ASM -> XASM -> AOBJ -> XLNK; | ||
+ | IDE -> C [color = green4]; | ||
+ | C -> XCMP -> COBJ -> XLNK; | ||
+ | LIB -> XLNK [weight = 0, label = "Linker wählt\nbenötigten Code\naus, nicht ganze Lib", fontcolor = gray]; | ||
+ | XLNK -> OUT [weight = 0]; | ||
+ | OUT -> XLOC -> ABS; | ||
+ | ABS -> USE [color = orange3]; | ||
+ | |||
+ | { | ||
+ | edge [color = gray, arrowhead = none]; | ||
+ | AOBJ -> HINT1 -> COBJ; | ||
+ | LIB -> HINT2; | ||
+ | OUT -> HINT3; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </graphviz> | ||
== Details zur internen Peripherie == | == Details zur internen Peripherie == | ||
+ | |||
+ | === Binärports (parallele digitale EA) === | ||
+ | |||
+ | Datenregister: P2 | ||
+ | |||
+ | Richtingsregister: DP2 (0 = input; 1 = output) | ||
+ | |||
+ | <source lang=asm> | ||
+ | MOV DP2, #1FH ; #001FH = 0000000000011111 | ||
+ | ; freie Eingänge auf 0 -> weniger Stromverbrauch | ||
+ | </source> | ||
+ | Output | ||
+ | <source lang=asm> | ||
+ | BCLR P2.3 ; PS = ************0*** | ||
+ | BSET P2.3 ; PS = ************1*** | ||
+ | </source> | ||
+ | Input | ||
+ | <source lang=asm> | ||
+ | JB P2.7, m3 ; PS = ********?******* Test auf 1 | ||
+ | JNB P2.7, m3 ; PS = ********?******* Test auf 0 | ||
+ | </source> | ||
+ | |||
+ | === Zähler/Zeitgeber ("Timer") T6 === | ||
+ | |||
+ | [Bild des T6 Timers] | ||
== Interrupt-System == | == Interrupt-System == | ||
+ | |||
+ | [...] | ||
+ | |||
+ | <graphviz> | ||
+ | digraph G { | ||
+ | node [fontsize = 11, width = 1.5]; | ||
+ | edge [fontsize = 11]; | ||
+ | |||
+ | { node [shape = record]; | ||
+ | 0 [label = "Normales Programm\nläuft"]; | ||
+ | 1 [label = "{aktuellen Befehl\nbeenden | IP, (CSP), PSW\n-\> Stack | Spung zur ISR\n(mittels Tabelle)}"]; | ||
+ | 2 [label = "{ISR | - Kontext retten\n-eigentl. Action\n- Kontext restaurieren\n- RETI}", color = green4, fontcolor = green4]; | ||
+ | 3 [label = "{ Stack -\> IP, (CSP),\nPSW| fortsetzten des Progr.}"]; | ||
+ | } | ||
+ | 0 -> 1 [label = "\"Blitz\""]; | ||
+ | 1 -> 2 -> 3 [color = orange3]; | ||
+ | } | ||
+ | </graphviz> | ||
+ | |||
+ | // TODO: Bild ist noch nicht ganz vollständig | ||
=== Arten von Interrupts === | === Arten von Interrupts === | ||
+ | |||
+ | * HW-Interrupts, maskierbar: | ||
+ | ** "intern" von Elementen auf dem Chip | ||
+ | ** "extern" jeder Pin als Interrupt | ||
+ | * NMI (nicht maskierbarer Interrupt) | ||
+ | *: nicht abschaltbar | ||
+ | *: für wichtige, dringende Sachen | ||
+ | * SW-Interrupts | ||
+ | *: Systemauf<font color = red>(ruf?)</font> bei BS | ||
+ | *: Beispiel: TRAP #25H | ||
+ | * Interne Ausnahmen: unbekanter OPKode, Div 0, etc. | ||
=== Interrupttabelle === | === Interrupttabelle === | ||
Zeile 246: | Zeile 637: | ||
== Typische Systeme mit C6000 == | == Typische Systeme mit C6000 == | ||
+ | [[Kategorie:Studium]] |
Aktuelle Version vom 10. März 2009, 15:30 Uhr
Für die Gemeinsamkeiten und Unterschiede von EµR und DSP gibt es eine Zusammenfassung.
Wer schon alles gelernt hat, kann sein Wissen mit Testfragen überprüfen.
Einleitung
Einordnung
- Einchipmikrorechner (EMR, µC)
- Digitaler Signalprozessor (DSP)
Gemeinsamkeiten
- Einchip-Konzept: wesentliche Bauteile alle auf einem Chip (CPU, Speicher, I/O, Taktgeber)
- minimierte (minimale) Außenbeschaltung: Abblockkondensator, Quarz
- autonomer Betrieb: Unbeaufsichtigter Betrieb, ohne (bzw. nur mit applikationsspezifischem) Bedienereingriff
- aufgabenspezifisch angepasst: "Nur soviel (Hardware) wie nötig"
- große Typenfamilien: viele Typen mit jeweils mehreren Ausführungen, Unterschiede in Speicher/Pins
- Crosswerkzeuge: Entwicklung auf PC, aber Code für Chips
- Software: muss sich nicht mehr verändern (ist in sich geschlossen)
Unterschiede
EMP | DSP | |
Leistung | niedrig bis mittel | mittel bis hoch |
Datenbreite | 4, 8, 16, 32 | 16, 32, 64 |
Speichergröße | ||
* intern | sehr wenig bis mittel | meist nur mittel |
* extern | wenig bis mittel | groß bis sehr groß |
Besondere Befehle | Bit-Befehle, Bit-Adressierung |
MAC (Multiplikation und Addition in einem Befehl), zirkuläre Adressierung, Saturation (Festkomma-Arithmetik) |
Typische Anwendungen | Steuergeräte in Industrie und Kraftfahrzeugtechnik, Haushaltselektronik, tragbare Geräte (MP3, Handy) |
digitale Filter/Regler, Bildverarbeitung und Mustererkennung, Messgeräte, Messtechnik, Audioeffektgeräte, Modems |
Bauteile
Rechnerkern
- RISC oder CISC
- Harvard oder von-Neumann (Princeton)
- viele Spezial(funktions)register (SFR)
- allg. Register häufig verbunden mit internem RAM
Speicher
<graphviz> digraph G { "Speicher" -> "intern"; "Speicher" -> "Speicherinterface";
"intern" -> "ROM"; "intern" -> "RAM";
"Speicherinterface" -> "Seriell"; "Speicherinterface" -> "Businterface"; "Speicherinterface" -> "\"glueless\"\n(Treiberlos)"; } </graphviz>
ROM
- Masken-ROM
- PROM/OTR
- EPROM
- EEPROM
- FLASH-EEPROM
- FRAM
- "Bondout"
- "ROM-less"
Ein- und Ausgabe
<graphviz> digraph G { "Ein- und Ausgabe" -> "digital, Standard"; "Ein- und Ausgabe" -> "analog"; "Ein- und Ausgabe" -> "speziell";
"digital, Standard" -> "parallel"; "digital, Standard" -> "seriell";
"seriell" -> "synchron"; "seriell" -> "asynchron";
node [shape=box]; "Kommunikation"; "Zähler/Zeitgeber"; "Geräte";
"speziell" -> "Kommunikation"; "speziell" -> "Zähler/Zeitgeber"; "speziell" -> "Geräte";
} </graphviz>
Sonstiges ("Hilfs"-baugruppen)
- Reset
- Takt
- Powermanagement
- Interruptsystem
- DMA
- Watchdog
Typenbeispiele
(nicht prüfungsrelevant)
Mikrocontroller am Beispiel der C166 Familie
- von Siemens, später Infineon
- 16bit Datenbreite
- CISC-Kern (eigentlich RISC, hat aber einige Erweiterungen)
- Intelähnlicher Befehlssatz
- von-Neumann-Architektur
- typischerweise bis 30 Mhz Taktfrequenz
- Adressbreite 16bit (mit Segmentierung 24bit)
- Mehrfachnutzung von Pins
Befehlssatzarchitektur
Allgemeiner Registersatz
- 16x16bit Register R0-R15
- Register R0-R7 lassen sich auch über H und L ansprechen
Spezialfunktionsregister (SFR)
- es existieren sehr viele Register
u.a. in:
- Prozessorkern
- Peripherieeinheiten
- Interruptsystem
- Chipsteuerung
- Adresseinheit
- ...
SFR im Prozessorkern
- PSW (processor status word, "Flagregister"), 16bit breit
- Beispiele für Flags:
- Statusflags:
- C: Carry (Übertrag)
- V: Overflow (Überlauf)
- Z: Zero
- N: Negative
- ...
- Steuerflags:
- IEN: Interrupt Enable
- USR0: frei verfügbar
- SP (Stackpointer)
- STKUV (Stackunderflow, untere Adressgrenze)
- STKOV (Stackoverflow, obere Adressgrenze)
- SYSCON: Systemkonfiguration
- ...
Speichermodell
- von-Neumann: ein Adressraum
- interner ROM
- interne RAMs
- SFRs (reservierte Speicheradressen)
- allgemeine Register (lassen sich im Speicherbereich verschieben -> Kontextwechsel sehr schnell möglich)
- reservierte Bereiche
- Rest: verwendbar für externen Speicher
kleines Speichermodell
- nicht segmentiert
- logische 16 Bit-Adresse wird umgesetzt auf physikalische 16 Bit-Adresse
- Speicherraum: Byte = 64 KiByte
großes Speichermodell
- segmentiert
- logische 16 Bit-Adresse erhält zusätzliche Segmentbeschreibung (Länge variiert)
- wird ungeformt auf physikalische 24 Bit-Adresse
- Speicherraum: Byte = 16 MiByte
Vorteil:
- mehr Speicherplatz
- Segment = Grobpositionierung
- Änderung davon seltener (wird nicht bei jedem Zugriff geändert)
Segmentierter Datenzugriff
Segmentierter Programmzugriff
Adressraumstruktur
- 000000H - 00FFFFH -> 64KiByte des nichtsegmentierten Bereichs
- Datenseite jeweils 16 KiByte groß (10bit Data Page Pointer [SFR])
- Codeseite jeweils 64 KiByte groß (8bit Code Segement Pointer [SFR])
Allgemeine Register: Mapping in den Speicherraum
- 32 Byte allgemeine Register
- können im Speicherbereich verschoben werden
- CP (context pointer, 10bit) zeigt auf erstes Register (R0)
- ermöglicht sehr einfachen Kontextwechsl ohne Umkopieren durch Verschieben des Registerbereichs
- schnell, grade für Echtzeitanwendungen; z.B. bei Interruptbehandlung
Befehlssatz
Transportbefehle
- MOV Ziel , Quelle : Wort
- MOV B Ziel , Quelle : Byte
- MOV BZ Ziel , Quelle : Wort <- Byte (Null auffüllen)
- MOV BS Ziel , Quelle : Wort <- Byte (Vorzeichen auffüllen)
ermöglichen arithmetisch korrekte Expansion von 8 auf 16bit
- MOV Register , Register
- MOV Register , #Zahlenwert // Konstante
- MOV Register , Zahlenwert // direkt
- MOV Register , [Register] // indirekt
- MOV [Register] , Register
- MOV Register , [Register+#Index]
- MOV Register , [Register+] // postdekrement um 2
- MOV [+Register] , Register // preinkrement um 2
- MOV [Register] , [Register] // nicht universell!
- Zahlenwerte mit # kennzeichnen sonst Speicheradresse
- Variablenangabe statt Zahlenwert für Adresse möglich
Stackbefehle
- PUSH Quelle -> Ziel = Stack
- Stackpointer geht 1 Speicherplatz nach unten (SP = SP - 2) und kopiert dann erst Inhalt aus Register in Stack
- POP Ziel -> Quelle = Stack
- Wert aus Stack wird gelesen und in Register geschrieben, dann geht Stackpointer 1 Speicherplatz nach oben (SP = SP + 2)
- Befehle gelten nur für 16 Bit Register
- LIFO-Prinzip beim Daten retten beachten
- Stack-Befehle müssen ausbalanciert sein (sonst Über-/Unterlauf)
- Stackgrenzen können festgelegt werden
- wenn der Stack über- oder unterläuft wird an eine Handleradresse gesprungen (Interrupt)
Arithmetik/Logik
16 Bit Befehle | 8 Bit Befehle | Bemerkung | ||
ADD | ADD B | |||
ADD C | ADD C B | Wert des Carry-Flags mit addieren | ||
SUB | SUB B | |||
SUB C | SUB C B | Wert des Carry-Flags mit subtrahieren | ||
AND | AND B | bitweise | ||
OR | OR B | bitweise | ||
XOR | XOR B | bitweise | ||
CMP | CMP B | beeinflusst nur Flags | ||
NEG | NEG B | Vorzeichen-Wechsel (2er-Komplement) | ||
CPL | CPL B | Bitweise Negation (1er-Komplement) (1->0 , 0->1) |
Multiplikation/Division
- MD - separates 32 Bit Register für Multiplikation/Division
- MDH , MHL = SFR
- Vorzeichenbehaftet - MUL
- Vorzeichenlos - MUL U
- Operationen nur mit Registern möglich
- DIV / DIV U -> MDL (16bit) : Op (16bit) = MDL (16bit) Rest: MDH (16bit)
- DIV L / DIV L U -> MD (32bit) : Op (16bit) = MDL (16bit) Rest: MDH (16bit) -> arithm. Überlauf möglich
- MD-Register wieder frei räumen vor neuer Multiplikation/Division
Schieben/Rotieren
- nur für 16 bit Register
Links | Rechts | Bemerkungen | |
SHL Register, Zahlenwert | SHR Register, Zahlenwert | <graphviz>
digraph G { rankdir = LR; node [shape = record, width = 0.1, height = 0.1]; Null [label = "0"]; subgraph "cluster Register" { rankdir = LR; 15 -> "..." -> 0; } Carry [label = "CF"]; Null -> 15; 0 -> Carry; } </graphviz> | |
- | ASHR Register, Zahlenwert | <graphviz>
digraph G { rankdir = LR; node [shape = record, width = 0.1, height = 0.1]; subgraph "cluster Register" { rankdir = LR; 15 -> "..." -> 0; } Carry [label = "CF"]; 15 -> 15; 0 -> Carry; } </graphviz> || Vorzeichenbehaftete Division durch 2 | |
ROL Register, Zahlenwert | ROR Register, Zahlenwert | <graphviz>
digraph G { rankdir = LR; node [shape = record, width = 0.1, height = 0.1]; subgraph "cluster Register" { rankdir = LR; 15 -> "..." -> 0 [weight = 100]; } Carry [label = "CF"]; 0 -> 15; 0 -> Carry [weight = 0]; } </graphviz> |
Steuerfluss-Befehle
Sprungbefehle
Wir unterscheiden Intrasegment und Intersegment Sprünge
Nur der IP (Instruction Pointer) wird geändert beim:
- segmentierten Modell (Sprung im Segment)
- nicht segmentierten Modell
Sowohl der IP (Instruction Pointer) als auch der CSP (Code Segment Pointer) wird geändert beim:
- segmentierten Modell (Sprung zwischen Segmenten)
Intrasegment
Direkt | Indirekt | |
Absolut | JMPA | JMPI |
Relativ | JMPR | - |
JMPA Condition Code, Label JMPR Condition Code, Label JMP Condition Code, Label // Assembler entscheidet sich für absoluten oder relativen Sprung JMPI cc_UC, [R4] // IP = [R4]
Condition Code
cc_UC: unconditional (unbedingt, immer!) cc_NC: not carry cc_C : carry cc_NZ: not zero cc_Z : zero cc_EQ: eqal (entspricht cc_Z) cc_NE: not eqal (entspricht cc_NZ) cc_V : overflow cc_NV: not overflow cc_SLT: signed less than cc_UGE: unsigned greater eqals
Vergleiche: werden aud dem Flags: C, Z, V und N gebildet
Intersegment
- nur absolut, direkt, unbedingt
JMP SEG Label, SOF Label \___ __/ \___ __/ \/ \/ Segment Offset (CSP) (IP) \________ ________/ \/ ergibt die 24bit-Speicheraddresse
Unterprogrammbefehle
Intrasegment
CALLA Condition Code, Label // IP -> Stack CALLR Condition Code, Label // IP -> Stack CALL Condition Code, Label // IP -> Stack, wird vom Assembler auf CALLA bzw. CALLR umgesetzt CALLI Condition Code, Label // IP -> Stack RET // Stack -> IP
Intersegment
CALLS Condition Code, Label // IP und CSP -> Stack RETS // Stack -> IP und CSP
Die Verwendung von RET bzw. RETS entscheidet darüber, ob eine Funktion aus einem anderem Segment erreichbar ist.
Bit-Befehle
- Bitaddressierbare Bereiche:
- 3x256 Byte im internen RAM
- 1x256 Byte SFR
- macht 1024x8 bit = 8 KiBit = Bitaddressierung
- 13bit Zellenadresse + 3bit Bitadresse = 16bit
- wenn Offset > 8, dann Adresse der nächsten Zelle + Offset MOD 8 als Offset
Beispiele für Bitadressen:
0FF10H.1 // (0-7) oder (0-15) mgl. \ PSW.1 // > sind alle äquivalent C // /
BMOV Zielbitadresse, Quellbitadresse BMOVN Zielbitadresse, Quellbitadresse BAND Zielbitadresse, Quellbitadresse BOR Zielbitadresse, Quellbitadresse BXOR Zielbitadresse, Quellbitadresse BCMP Zielbitadresse, Quellbitadresse BCLR Bitadresse BSET Bitadresse
- Bedingte Sprünge mit Bits nur intrasegment, direkt
JB Bitadresse, Label // Bit gesetzt JNB Bitadresse, Label // Bit nicht gesetzt
"Test & Set" Befehle (atomar, für Parallelprogrammierung):
JBC Bitadresse, Label | Bit gesetzt, zurücksetzen (CLEAR) JNBS Bitadresse, Label | Bit nicht gesetzt, setzen (SET)
Sonstige Befehle
<source lang=asm> NOP ; No Operation SRST ; Softwarereset PWRDW ; Schlafzustand aktivieren EINIT ; Ende der Initalisierung
; Privelegierte Einstellungen können nicht mehr ; verändert werden (wie z.B. Stackgrenzen)
</source>
SW-Entwicklung
Cross-Tools: (z.B. Programmierung auf PC für nicht PC-Zielsystem)
Tool-Chain: (Werkzeugkette)
IDE: (Integrated Development Enviroment)
<graphviz> digraph G {
rankdir = LR; node [fontsize = 11, width = 0.1, heigth = 0.1]; edge [fontsize = 11];
IDE [shape = box, label = "Interaktives\nKonfigurations\nWerkzeug\n\n\"DAVE\"", color = green4, fontcolor = green4];
ASM [shape = box, label = ".asm\nAssembler-\nQuelltext"]; XASM [shape = ellipse, label = "Cross-\nAssembler"]; AOBJ [shape = box, label = ".obj\nObjekt"];
C [shape = box, label = ".c\nC-Quell-\ntext"]; XCMP [shape = ellipse, label = "Cross-\nCompiler"]; COBJ [shape = box, label = ".obj\nObjekt"];
LIB [shape = box, label = ".lib\nBiblio-\ntheken"]; XLNK [shape = ellipse, label = "Cross-\nLinker"]; OUT [shape = box, label = ".out\nVerbunden-\nes Objekt"]; XLOC [shape = ellipse, label = "Cross-\nLocator"]; ABS [shape = box, label = ".abs\nAbsolutes\nObjekt"]; { node [shape = none, fontcolor = gray]; HINT1 [label = "noch keine endgültigen\nAddressen"]; HINT2 [label = "Vorgefertigte Module"]; HINT3 [label = "- endgültige Addressen\n- Reffenzen aufgelößt \n- Maschinencode "]; }
labeljust = l; USE [shape = box, label = "- Befehlssatz-Simulator\n- Remote Debugging \n- In-Circute-Emulation;\n JTAG (IEEE 1149.1) \n- Programmiergerät ", color = orange3];
{rank = 0; IDE} {rank = same; ASM; C; LIB; HINT2; OUT; HINT3} {rank = same; AOBJ; HINT1; COBJ}
IDE -> ASM [style = invis, weight = 0]; // Workaround zur Anordnung der Elemente ASM -> XASM -> AOBJ -> XLNK; IDE -> C [color = green4]; C -> XCMP -> COBJ -> XLNK; LIB -> XLNK [weight = 0, label = "Linker wählt\nbenötigten Code\naus, nicht ganze Lib", fontcolor = gray]; XLNK -> OUT [weight = 0]; OUT -> XLOC -> ABS; ABS -> USE [color = orange3];
{ edge [color = gray, arrowhead = none]; AOBJ -> HINT1 -> COBJ; LIB -> HINT2; OUT -> HINT3; }
} </graphviz>
Details zur internen Peripherie
Binärports (parallele digitale EA)
Datenregister: P2
Richtingsregister: DP2 (0 = input; 1 = output)
<source lang=asm> MOV DP2, #1FH ; #001FH = 0000000000011111
; freie Eingänge auf 0 -> weniger Stromverbrauch
</source> Output <source lang=asm> BCLR P2.3 ; PS = ************0*** BSET P2.3 ; PS = ************1*** </source> Input <source lang=asm> JB P2.7, m3 ; PS = ********?******* Test auf 1 JNB P2.7, m3 ; PS = ********?******* Test auf 0 </source>
Zähler/Zeitgeber ("Timer") T6
[Bild des T6 Timers]
Interrupt-System
[...]
<graphviz> digraph G {
node [fontsize = 11, width = 1.5]; edge [fontsize = 11];
{ node [shape = record]; 0 [label = "Normales Programm\nläuft"]; 1 [label = "{aktuellen Befehl\nbeenden | IP, (CSP), PSW\n-\> Stack | Spung zur ISR\n(mittels Tabelle)}"]; 2 [label = "{ISR | - Kontext retten\n-eigentl. Action\n- Kontext restaurieren\n- RETI}", color = green4, fontcolor = green4]; 3 [label = "{ Stack -\> IP, (CSP),\nPSW| fortsetzten des Progr.}"]; } 0 -> 1 [label = "\"Blitz\""]; 1 -> 2 -> 3 [color = orange3];
} </graphviz>
// TODO: Bild ist noch nicht ganz vollständig
Arten von Interrupts
- HW-Interrupts, maskierbar:
- "intern" von Elementen auf dem Chip
- "extern" jeder Pin als Interrupt
- NMI (nicht maskierbarer Interrupt)
- nicht abschaltbar
- für wichtige, dringende Sachen
- SW-Interrupts
- Systemauf(ruf?) bei BS
- Beispiel: TRAP #25H
- Interne Ausnahmen: unbekanter OPKode, Div 0, etc.