Interrupt in C
Die folgenden Informationen sind nur für den LCC.
Der Assemblerinclude wird im lcc18 mit den vier Schaltern -target=spartan/hw, -target=spartan/hwmon, -target=spartan/moni und -target=spartan/mon ausgewählt. Mit diesen Schaltern werden vier verschiedene Assemblerquellen ausgewählt, die auf die unterschiedlichen Einsatzfälle von Programmen ausgerichtet sind. Der einfachste und auch als Standard eingerichtete Fall ist das Erzeugen von Programmen ohne Interrupt Behandlung mit Benutzung der Systemaufrufe des Monitors.
Der Schalter -target=spartan/mon
Mit ihm ist keine Interruptarbeit möglich. Der Monitor fängt aber alle Interrups ab und zeigt sie an, wenn durch einen Programmfehler doch ein Interrupt entstehen sollte. Die Übersetzten Programme werden als *.spho Datei erzeugt und müssen mit dem Kommando LO im Monitor geladen und mit G und ENTER gestartet werden. Der Compiler bindet dabei die Datei startup_monitor.inc ein, welche unter spartanmc/lib/startup_monitor.inc oder hier verfügbar ist.
Um den Programmstart mit dem Monitorkommando G und ENTER zu ermöglichen, liegt auf Adresse 0x4 ein unbedingter Sprung auf das Label _main des Hauptprogramms. Mit dieser Adresse beginnt dann auch jedes Programm. Beendet werden die Programme mit einem RETURN, der in das aufrufende Programm (den Monitor) zurückspringt. Der RETURN Wert wird dabei in Register r7 übergeben. Der Monitor meldet sich bei einem Fehler (r7 != 0) mit einem Fragezeichen bevor er in die Kommando Eingabe geht.
Speicheraufteilung bei 9 Speicherblöcken
Programm-adressen | Datenadressen | Belegt mit ... | Bemerkung |
00000 bis 00003 | 00000 bis 00006 | JUMP18 zum Setzen von SFR_IV und SFR_TR | Teil des Monitors |
00004 bis 00007 | 00008 bis 0000E | JUMP18 zu MAIN des C-Progamms | Startup Assembler Programm mit dem Kommando LO laden |
00008 bis . . . | 00010 bis . . . | Daten des C-Programms | wird mit dem Kommando LO mit geladen |
. . . | . . . | C-Programm | wird mit dem Kommando LO mit geladen |
. . . | . . . | compiler.inc | Assembler Include wird mit dem Kommando LO mit geladen |
. . . | . . . | *.inc | Assembler Include wird mit dem Kommando LO mit geladen |
. . . | . . . | *.inc | Assembler Include wird mit dem Kommando LO mit geladen |
. . . | . . . | monitor.inc | Assembler Include wird mit dem Kommando LO mit geladen |
. . . bis 04241 | . . . bis 08482 | Anwender Stack | Teil des Monitors *) |
04242 bis 04262 | 08484 bis 084C4 | Monitor Stack | |
04263 bis 0436E | 084C6 bis 086DC | Datenbereich des Monitors | |
0436F bis 046A1 | 086DE bis 08D42 | Programmbereich des Monitors | |
046B7 bis 046BF | 08D6E bis 08D7E | Setzen von SFR_IV und SFR_TR und Start des Monitors | Teil des Monitors |
046C0 bis 046FF | 08D80 bis 08DFE | Interrupt Behandlung des Monitors | Protokollierung bei versehentlicher Auslösung |
04700 bis 0471A | 08E00 bis 08E34 | Systemaufrufe (TRAP Einsprünge) | Teil des Monitors |
0471B bis 047FF | 08E36 bis 08FFE | nicht genutzte Systemaufrufe |
*) Der Anwender Stack wird im Monitor mit 32 Worten vom Monitoranfang reserviert. Der Anfang ergibt sich zu monanf = (SB_SPARTANMC_0_RAMBLOCKS)*2048 -1024-256-73-150. Der Anwender Stack ist damit STACK = monanf + 32. Bei 9 Speicherblöcken ist das stack = 9*2048 - 1503 + 32 = 16961 = 0x4241
Der Schalter -target=spartan/moni
Mit diesen Schalter ist eine eigene Interrupt Arbeit möglich, ohne auf die Systemaufrufe des Monitors verzichten zu müssen. Die übersetzten Programme werden als *.spho Datei erzeugt und müssen mit dem Kommando LO im Monitor geladen und mit G und ENTER gestartet werden. Der Compiler bindet dabei die Datei startup_mon_int.inc ein, welche unter spartanmc/lib/startup_mon_int.inc oder hier verfügbar ist. Zur Behandlung der Interrups werden in der Datei interrupt.inc Unterprogramm Aufrufe verwendet. Dadurch können sie in C als Prozedur realisiert werden und es ist keine Einschränkung in der Verwendung von Registern nötig. Die zu verwendenden Interrupts werden in der Datei system.inc in der Konstanten i_bits freigegeben. Sie wird für jede Konfiguration vom jConfig automatisch erstellt und vom make in den Quell Verzeichnissen zur Verfügung gestellt.
Der Interrupteinsprung des MC erfolgt auf der Adresse im SFR_IV. Um den Programmstart mit dem Monitorkommando G und ENTER zu ermöglichen, liegt auf Adresse 0x4 ein unbedingter 18 Bit Sprung auf die Initialisierung des SFR_IV und von dort zum Label _main des Hauptprogramms. Mit der Adresse 0x4 beginnt dann auch jedes Programm. Die Freigabe der Interrups in der CPU wird dabei schon im Monitor realisiert. Soll dies im Programm selbst noch gesteuert werden, dann stellt interrupt.h zwei Funktionen aus Interrupt.inc dafür bereit. Diese sind unter spartanmc/lib/interrupt.inc oder hier und spartanmc/lib/include/interrupt.h oder hier zu finden. Beendet werden die Programme mit einem RETURN, der in das aufrufende Programm (den Monitor) zurückspringt. Der RETURN Wert wird dabei in Register r7 übergeben. Der Monitor meldet sich bei einem Fehler (r7 != 0) mit einem Fragezeichen bevor er in die Kommando Eingabe geht.
Speicheraufteilung bei 9 Speicherblöcken
Programm-adressen | Datenadressen | Belegt mit ... | Bemerkung |
00000 bis 00003 | 00000 bis 00006 | JUMP18 zum Setzen von SFR_IV und SFR_TR | Teil des Monitors |
00004 bis 00007 | 00008 bis 0000E | JUMP18 zum Setzen von SFR_IV des C-Progamms | Startup Assembler Programm mit dem Kommando LO laden |
00008 bis . . . | 00010 bis . . . | Daten des C-Programms | wird mit dem Kommando LO mit geladen |
. . . | . . . | C-Programm | wird mit dem Kommando LO mit geladen |
. . . | . . . | compiler.inc | Assembler Include wird mit dem Kommando LO mit geladen |
. . . | . . . | *.inc | Assembler Include wird mit dem Kommando LO mit geladen |
. . . | . . . | *.inc | Assembler Include wird mit dem Kommando LO mit geladen |
. . . | . . . | monitor.inc | Assembler Include wird mit dem Kommando LO mit geladen |
. . . | . . . | interrupt.inc | Assembler Include für Enable und Disable wird mit dem Kommando LO mit geladen |
. . . | . . . | setzen des Interruptvektors | Bestandteil von interrupt.inc wird mit dem Kommando LO mit geladen |
. . . | . . . | JUMP18 zu MAIN des C-Progamms | Bestandteil von interrupt.inc wird mit dem Kommando LO mit geladen |
. . . | . . . | Interruptverarbeitung | Bestandteil von interrupt.inc wird mit dem Kommando LO mit geladen |
. . . bis 04241 | . . . bis 08482 | Anwender Stack | Teil des Monitors *) |
04242 bis 04262 | 08484 bis 084C4 | Monitor Stack | |
04263 bis 0436E | 084C6 bis 086DC | Datenbereich des Monitors | |
0436F bis 046A1 | 086DE bis 08D42 | Programmbereich des Monitors | |
046B7 bis 046BF | 08D6E bis 08D7E | Setzen von SFR_IV und SFR_TR und Start des Monitors | Teil des Monitors |
046C0 bis 046FF | 08D80 bis 08DFE | Interrupt Behandlung des Monitors (wird vom C-Programm nicht genutzt) | Protokollierung bei versehentlicher Auslösung |
04700 bis 0471A | 08E00 bis 08E34 | Systemaufrufe (TRAP Einsprünge) | Teil des Monitors |
0471B bis 047FF | 08E36 bis 08FFE | nicht genutzte Systemaufrufe |
*) Der Anwender Stack wird im Monitor mit 32 Worten vom Monitoranfang reserviert. Der Anfang ergibt sich zu monanf = (SB_SPARTANMC_0_RAMBLOCKS)*2048 -1024-256-73-150. Der Anwender Stack ist damit STACK = monanf + 32. Bei 9 Speicherblöcken ist das stack = 9*2048 - 1503 + 32 = 16961 = 0x4241
Beispiel einer C-Quelle Ass-Quelle Ass-Liste
Verwendeter Monitor Ass-Quelle Ass-Liste
Der Schalter -target=spartan/hwmon
Mit diesem Schalter ist die Erstellung eines völlig eigenständigen Programms möglich. Man kann auf Funktionen des Monitors und dem vom Monitor eingerichteten STACK zurückgreifen. Die in diesem fall eingesetzte Datei startup_hwmon.inc ist eine abgewandelte Variante des Monitors in der Version vom 07.07.2011 mit der automatischen Verschiebung des Monitors an das Speicherende, die aber das übersetzte Programm sofort startet. Die Interrupt Arbeit erfolgt hier genau wie beim Schalter -target=spartan/moni. Man kann daher sein Programm mit Interrupts im Monitor mit dem Schalter -target=spartan/moni testen und in der endgültigen Version des Programms hier unverändert übernehmen. Die Datei startup_hwmon.inc ist auch unter spartanmc/lib/startup_hwmon.inc oder hier einzusehen. Die MAIN Funktion kann auch mit einem RETURN beendet werden, wobei sich dann der Monitor meldet. Damit sind auch dann noch alle Monitorfunktionen für Service Aufgaben nutzbar. Die MAIN Funktion kann aber auch eine Endlosschleife sein. Dann muss das Programm zum Schluss aber noch einmal verändert werden. Bei der Verwendung dieses Schalters wird das C-Programm als Firmware bei der Erstellung einer Konfiguration geladen und damit sofort beim Einschalten oder nach dem Programmieren des FPGA gestartet.
Speicheraufteilung bei 9 Speicherblöcken
Programm-adressen | Datenadressen | Belegt mit ... | Bemerkung |
00000 bis 00003 | 00000 bis 00006 | JUMP18 zum Setzen von SFR_IV und SFR_TR | Startup Assembler Programm |
00004 bis 00007 | 00008 bis 0000E | JUMP18 zum Setzen von SFR_IV des C-Progamms | Startup Assembler Programm |
00008 bis . . . | 00010 bis . . . | Daten des C-Programms | wird beim Einschalten mit geladen. |
. . . | . . . | C-Programm | wird beim Einschalten mit geladen. |
. . . | . . . | compiler.inc | Assembler Include |
. . . | . . . | *.inc | Assembler Include |
. . . | . . . | *.inc | Assembler Include |
. . . | . . . | monitor.inc | Assembler Include |
. . . | . . . | interrupt.inc | Assembler Include für Enable und Disable |
. . . | . . . | setzen des Interruptvektors | Bestandteil von interrupt.inc |
. . . | . . . | JUMP18 zu MAIN des C-Progamms | Bestandteil von interrupt.inc |
. . . | . . . | Interruptverarbeitung | Bestandteil von interrupt.inc |
. . . bis 04241 | . . . bis 08482 | Anwender Stack | Startup Assembler Programm *) |
04242 bis 04262 | 08484 bis 084C4 | Monitor Stack | Startup Assembler Programm |
04263 bis 0436E | 084C6 bis 086DC | Datenbereich des Monitors | Startup Assembler Programm |
0436F bis 046A1 | 086DE bis 08D42 | Programmbereich des Monitors | Startup Assembler Programm |
046B7 bis 046BF | 08D6E bis 08D7E | Setzen von SFR_IV und SFR_TR und Start des Monitors | Startup Assembler Programm |
046C0 bis 046FF | 08D80 bis 08DFE | Interrupt Behandlung des Monitors (wird vom C-Programm nicht genutzt) | Startup Assembler Programm |
04700 bis 0471A | 08E00 bis 08E34 | Systemaufrufe (TRAP Einsprünge) | Startup Assembler Programm |
0471B bis 047FF | 08E36 bis 08FFE | nicht genutzte Systemaufrufe |
*) Der Anwender Stack wird im Monitor mit 32 Worten vom Monitoranfang reserviert. Der Anfang ergibt sich zu monanf = (SB_SPARTANMC_0_RAMBLOCKS)*2048 -1024-256-73-150. Der Anwender Stack ist damit STACK = monanf + 32. Bei 9 Speicherblöcken ist das stack = 9*2048 - 1503 + 32 = 16961 = 0x4241
Beispiel einer C-Quelle mit 17 Speicherblöcken Ass-Quelle Ass-Liste
Der Schalter -target=spartan/hw
Mit diesem Schalter ist die Erstellung eines völlig eigenständigen Programms möglich. Es muss aber auch alles selbst eingestellt und eingerichtet werden. Man kann nicht auf Funktionen des Monitors und dem vom Monitor eingerichteten STACK zurückgreifen. Die in diesem fall eingesetzte Datei startup_hardware.inc richtet daher bereits einen STACK ein und bietet auch die Möglichkeit eigene Prozeduren für die TRAP Befehle zu schreiben. Dafür muss für jeden zu nutzenden TRAP ein Bit in der Konstanten en_trap in der Datei conf_con.inc gesetzt werden. Sie befindet sich auch unter spartanmc/lib/conf_con.inc oder ist hier verfügbar. Die Interrupt Arbeit erfolgt hier genau wie beim Schalter -target=spartan/moni. Man kann daher seine Interruptprogramme zusammen mit dem Monitor testen und in der endgültigen Version des Programms hier unverändert übernehmen. Die Datei startup_hardware.inc ist auch unter spartanmc/lib/startup_hardware.inc oder hier einzusehen. Bei der Verwendung dieses Schalters wird der RETURN der MAIN Funktion automatisch als Endlosschleife übersetzt, da es bei selbständigen Programmen kein aufrufendes Programm gibt! Bei der Verwendung dieses Schalters wird das C-Programm als Firmware bei der Erstellung einer Konfiguration geladen und damit sofort beim Einschalten oder nach dem Programmieren des FPGA gestartet.
Speicheraufteilung bei 9 Speicherblöcken
Programmadresse | Datenadresse | Belegt mit ... | Bemerkung |
00000 bis 00003 | 00000 bis 00006 | JUMP18 zum Setzen von SFR_IV und SFR_TR | Startup Assembler Programm |
00004 bis 00009 | 00008 bis 00012 | JUMP18 zu SET IV und Load R0 | Startup Assembler Programm |
0000A bis . . . | 00014 bis . . . | Daten des C-Programms | |
. . . | . . . | Programm Stack | |
. . . | . . . | C-Programme | |
. . . | . . . | compiler.inc | Assembler Include |
. . . | . . . | *.inc | Assembler Include |
. . . | . . . | *.inc | Assembler Include |
. . . | . . . | interrupt.inc | Assembler Include für Enable und Disable |
. . . | . . . | setzen des Interruptvektor | Bestandteil von interrupt.inc |
. . . | . . . | JUMP18 zu MAIN des C-Progamm | Bestandteil von interrupt.inc |
. . . | . . . | Interruptverarbeitung | Bestandteil von interrupt.inc |
022C7 bis 022CF | 0458E bis 0459E | Setzen von SFR_IV und SFR_TR und Start Adresse 4 | Startup Assembler Programm |
022D0 bis 022FF | 045A0 bis 045FE | Interrupt Behandlung des Monitors ==ungenutzt== | Startup Assembler Programm |
02300 bis 023FF | 04600 bis 046FE | Vorbereitete Systemaufrufe (TRAP Einsprünge) | Startup Assembler Programm |
Die alte Speicheraufteilung kann hier eingesehen werden.
Hier wird die Speicheraufteilung bei der Übersetzung des Quicksort Programms dargestellt.
Nutzung der drei mit dem Schalter ==-target== erstellbaren Konfigurationen des LCC18 und die dabei entstehenden Speicheraufteilungen.
1. Variante: lcc18 -target=spartan/mon quicksort.c
C-Quelle Ass-Quelle Ass-Liste spho-Datei
2. Variante: lcc18 -target=spartan/moni quicksort_moni.c
C-Quelle Ass-Quelle Ass-Liste spho-Datei
3. Variante: lcc18 -target=spartan/hw quicksort_hw.c
C-Quelle Ass-Quelle Ass-Liste sph-Datei
2. Variante mit Nutzung der Monitor I/O: lcc18 -Wf-include-stdasm=monitor.inc quicksort_iomon.c
C-Quelle Ass-Quelle Ass-Liste spho-Datei Protokoll
2. Variante mit Timer RTI Interrupt
zu jeder Sekunde und Ausgabe eines Wertes auf SFR_LED übersetzt mit:
lcc18 -Wf-include-stdasm=interrupt.inc -Wf-include-stdasm=led7.inc -Wf-default-shift -target=spartan/moni timer.cC-Quelle Ass-Quelle Ass-Liste spho-Datei Protokoll timer.h rti.h
Konfiguration im binären Format für den Spartan 3E Starter Kit auf der das Programme lauffähig ist.
Die Konfiguration hat 9 Speicherblöcke.
- SPARTANMC.BIT Datei für das 3e Board und SPARTANMC.MSK Datei für Verify im iMpact (nur Jumper M1 geschlossen).
- M25P16.MCS Datei und M25P16.CFI Datei für den SPI-PROM des 3e Board (nur Jumper M0 offen).
- xcf04s_0.MCS Datei und xcf04s_0.CFI Datei für den Platform Flash-PROM des 3e Board (alle Jumper M0, M1 und M2 geschlossen). Diese 6 Dateien in ein Verzeichnis speichern und von dort mit dem iMpact in einen der PROMs oder die FPGA speichern.
- Konstanten der Konfiguration als Include system.h und system.inc für alle Programme auf dieser Konfiguration.
- Der Testmonitor für diese Konfiguration als Quelle, Liste und im HEX-Format.
4. Variante mit Schalter -target=spartan/hwmon
C-Quelle Ass-Quelle Ass-Liste sph-DateiKonfiguration im binären Format für den Spartan 3E Starter Kit mit dem Programm auto.c.
Die Konfiguration hat 9 Speicherblöcke.
- SPARTANMC.BIT Datei für das 3e Board und SPARTANMC.MSK Datei für Verify im iMpact (nur Jumper M1 geschlossen).
- M25P16.MCS Datei und M25P16.CFI Datei für den SPI-PROM des 3e Board (nur Jumper M0 offen).
- xcf04s_0.mcs Datei und xcf04s_0.cfi Datei für den Platform Flash-PROM des 3e Board (alle Jumper M0, M1 und M2 geschlossen). Diese 6 Dateien in ein Verzeichnis speichern und von dort mit dem iMpact in einen der PROMs oder die FPGA speichern.
- Konstanten der Konfiguration als Include system.h und system.inc für alle Programme auf dieser Konfiguration.
- Der Testmonitor für diese Konfiguration ist in ==auto.a18== enthalten. Quelle, Liste und im HEX-Format.