Turbo-Locator :: Readme und Dokumentation
16bit x86 Code Locator for Turbo/Borland C++, Turbo Pascal, TASM
- Geeignet für Prozessoren wie ix86, V25, V40, V50, SC400, Am186, AmX86, ...
- Verwendet Standard-Output von Turbo/Borland C++, Turbo Pascal, Borland Pascal und TASM
- Location von C++, Assembler and Pascal Code ohne zusätzliches Betriebssystem
- Erzeugt Flat Images für ROM, EPROM, Flash und RAM-Download
- OS-artige Services inklusive dem Multi-Threading System TurboTASK werden als normale Bibliothek dazugelinkt
- Beispielanwendungen: x86 kompatible Embedded Systems, Industrie-PCs und BIOS/Flat/Raw/ROM PC Applicationen ohne Betriebssystem
Der TurboLocator ist ein einfach zu verwendender Entwickler-Kit inklusive System-Bibliotheken, um den Output von Borland PC 16bit Compilern auf x86 basierende Embedded Rechner zu übertragen. Die Verwendung ist i.d.R innerhalb von wenigen Stunden zu erlernen. Zahlreiche Beispiele liegen bei.
Inhalt
Newsletter
Registrierung
Aktueller Download
Setup & Einführung
Handbuch
Newsletter
Bestellen sie den freien Embedded x86 & TurboLocator Newsletter um über Updates und Tips&Tricks informiert zu werden. Die Adresse wird nicht für andere Zwecke verwendet.
Registrierung von TurboLocator
Nach Registrierung erhalten sie das personalisierte Registrierungs-Ticket, den TurboLocator Vollversions-Installer ohne Code-Größenlimit.
> RegistrationDie TurboLocator Vollversion ist auch in den Komplett-Entwicklungspaketen mit Hardware (MT25 & MT400; IMT GmbH) enthalten: hier
Download
Aktuelle Release V5.0: TurboLocator-Setup-Trial.exe
(1.2
MB). Das TurboLocator Demo mit 8k Code-Größenlimit ist Freeware.
Feedback an feedback@xellsoft.com.
Setup
Das Setup des Turbo-Locator Installers ist weitgehend selbsterklärend. Nach dem Start des Programms kann der erste Lokator-Lauf an dem Beispiel-EXE hellolcd.exe durchgeführt werden. Funktioniert dies, so ist das Setup erfolgreich durchgeführt.
Code Beispiele und die System-Bibliothek sind im Sys.LIB-ZIP-File über entsprechenden Windows-Start-Menü-Eintrag nach der Installation erreichbar.
Handbuch
Der TurboLocator ist eine Entwicklungssoftware, um den Output von wohlerprobten Borland 16bit PC Compilern (TurboPascal, Turbo C++, TASM, ..) auf x86 basierende Embedded Rechner und Raw PC Umgebungen zu übertragen, in den kein Betriebssystem (DOS) vorhanden ist.
Viel Wert wurde auf ein Softwarekonzept gelegt, das eine zügige, unkomplizierte und dennoch anspruchsvolle Anwendungsentwicklung ohne lange Einarbeitungszeit erlaubt. Es besteht die Möglichkeit, auf der einen Seite sowohl modernste Programmiertechniken (OOP), als auch auf der anderen Seite Assemblerprogrammierung für höchste Geschwindigkeitsanforderungen einzusetzen. Ein einfaches aber effektives Echtzeit-Multitaskingsystem (TurboTASK) erlaubt die Entwirrung komplexer paralleler Abläufe in x86-Embedded-Umgebungen. Zahlreiche System-Bibliotheken stehen zur Verfügung.
Als Beispiel-Rechner ist im folgenden oftmals der MT25 Messtechnikrechner (basierend auf NEC V25) angenommen. Die Systembibliothek für den MT25 ist ebenfalls im Lieferumfang der Software enthalten (Installations-Menü "System Library") und viele Teile davon können in beliebigen x86-Umgebungen verwendet werden.
Prinzipielles Vorgehen einer Programm-Lokation mit dem Turbo-Locator:
-
Erstellen der Software mit einem der genannten Borland Compiler. Erzeugung eine EXE-Files. Dabei ggf. Einbindung des speziellen Embedded Start-Codes c0x.obj aus der mitgelieferten System-Bibliothek, oder ein für das jeweilige System angepassten Start-Code (bei den Borland C-Compilern ist der Start-Code für ggf. notwendige Anpassungen mitgeliefert.
-
Der eigentliche TurboLocator-Lauf: Anwenden von EXELOC.EXE auf das EXE-File (+ggf. MAP-File). Dies kann sowohl über Commandline (Syntax s.u.) oder über das bequeme WinMT-GUI durchgeführt werden.
-
Bei ROM-Code: Brennen des entstandenen BIN- oder HEX-Files.
Bei RAM-Code: Download des DLF-Files an den MTxx - Rechner oder den jeweiligen Zielrechner mit DLX / WinMT
Bei FLASH-Code: Download des FSH-Files mit DLX / WinMT in den Ziel-Rechner
Der Locator EXELOC.EXE
Der
Locator EXELOC wandelt ein fertig compiliertes und gelinktes Programm,
das mit den Compilern TurboC/BorlandC, TurboPascal, TurboAssembler
erstellt wurde, in eine EPROM- oder eine download-fähige Datei um. Um
diese Aufgabe auszuführen, benötigt EXELOC neben der EXE-Datei des
Programmes zusätzlich die MAP-Datei, die beim Link-Vorgang erzeugt
wird. Die Erzeugung der MAP-Datei wird je nach Compiler folgendermaßen
veranlaßt:
TC/BC- und TurboPascal-IDE:
Der Schalter Options/Linker/Mapfile muß zumindest auf Segments stehen.
TurboPascal Kommandozeile (TPC.EXE):
Der Parameter /GD muß angegeben werden
Kommandozeile
C/C++ oder reine Assembler-Programme:
Beim Linkvorgang mit dem TurboLinker TLINK darf der Parameter /x zur Unterdrückung der MapDatei nicht angegeben werden. Der Parameter /m für ausführliche Map-Datei ist natürlich zulässig.
EXELOC erkennt automatisch den Compilertyp und behandelt die EXE-Datei entsprechend.
Benutzung von EXELOC anhand von Beispielen
Anhand von Beispielen wird nun der Umgang mit EXELOC erklärt. Vorausgesetzt wird dabei ein bereits fertiggestelltes Programm TEST.EXE (+TEST.MAP). Ein solches Programm ist z.B. im Verzeichnis SysLib\MT25\PAS\EXAMPLES\ vorbereitet.
Das einfachste Beispiel eines EXELOC-Aufrufes ist:
EXELOC TEST
(TEST.EXE sei z.B. ein Turbo-Pascal-Programm)
Dazu muß EXELOC.EXE im MSDOS-Pfad liegen und die Dateien TEST.EXE und TEST.MAP im aktuellen Verzeichnis. EXELOC wandelt die Datei TEST.EXE in die download-fähige Datei TEST.DLF um. Diese Datei kann dann über die serielle Schnittstelle in den x86/MT25-Computer geladen, und direkt aus dem RAM ausgeführt werden. Durch den EXELOC-Lauf werden auch die RAM/EPROM-Spezifikationen festgelegt. Sind - wie in diesem Beispiel - keine Optionen angegeben, so geht EXELOC von folgenden Defaulteinstellungen aus:
Ziel-Datei-Typ: Downloadfähige
Datei (Endung .DLF)
EPROM-Größe:
32K
(hier nicht benutzt,
da Download)
RAM-Größe:
32K
Startsegment für
Programm
und Daten im RAM: 0040H
Weiter nimmt EXELOC als Default-Einstellung an, daß das RAM im unteren Speicherbereich von 00000H bis maximal 7FFFFH liegt und das EPROM im oberen Speicherbereich FFFFFH bis minimal 80000H, wobei der Reset-Vektor bei FFFFH:0000H liegt. Diese Werte passen automatisch für den MT25-Rechner. Für andere Zielumgebungen muss man ggf. anpassen.
Ist
der EXELOC-Vorgang erfolgreich verlaufen, so erscheint folgende Ausgabe:
C:\MT25\PAS\EXAMPLES>EXELOC
TEST
EXELOC V2.0 TC++/BC++/TPascal Relocator for x86/NECVxx
relocating file TEST.EXE -> TEST.DLF (Binary)
RAM Size 32K
Source is
TPascal...
Code and Data
segments start at 0040H (para)
Code length
(bytes):
3040
Code + const data
length (bytes): 3120 (required eprom size)
Data + min.stack
lenght (bytes): 4784 (min. RAM size in eprom
applic.)
Stack length
(bytes):
4096
Remaining heap
length (bytes): 23920
EXE-file
relocation OK
Wichtig sind vor allem die Informationen zu "required eprom size" und "min. RAM size in eprom applic.", um zu bestimmen, welche Speichergrößen mindest erforderlich ist, um das fertige Programm vom EPROM aus ablaufen zu lassen. "Remaining heap length" gibt an, wieviel Speicher bei der vorgegebenen RAM-Größe auf dem Heap dynamisch allokiert werden können.
Die erste Einstellung, die bei der Zunahme des Programmcodes durchgeführt werden muß, ist die Anpassung der RAM-Größe. Dies erfolgt mittels des Parameters /RAMSIZE (Groß-/Kleinschreibung und Abfolge der Parameter und Argumente spielt keine Rolle):
EXELOC demoA
/ramsize:128
Jetzt geht EXELOC von einer RAM-Größe von 128KB aus. Die maximal wählbare RAM-Größe ist 512K. Reicht die angegebene RAM-Größe für Programm und Daten nicht aus, so erzeugt EXELOC eine entsprechende Fehlermeldung.
Achtung: Ist die angegebene RAM-Größe größer als die tatsächliche, ist ein Programm-Absturz sicher. Umgekehrt gibt es keine Probleme, außer, daß das "verschwiegene" RAM nicht als Heap genutzt werden kann.
Ist das Programm nun ausgereift, so kann es in ein EPROM abgelegt werden. Dazu muß es auf andere Weise reloziert werden, damit der Code, die Konstanten und die initialisierten Daten (bei C/C++) im EPROM, die nicht initialisierten und (bei C/C++) die Kopien der initialisierten Daten dagegen im RAM plaziert werden. Die Relokationsart wird mit dem Parameter /ROM auf EPROM gewechselt. z.B.:
EXELOC TEST
/ROM /romsize:64 /ramsize:8
In diesem Beispiel wurden gleichzeitig die RAM-Größe auf 8K reduziert (reicht bei vielen EPROM-Anwendungen aus), und die EPROM-Größe mittels des Parameters /ROMSIZE auf 64K erhöht (maximal sind auch hier 512K möglich).
Es entsteht diesmal die Datei TEST.BIN. Dies ist eine Binärdatei, die von vielen PC-basierenden EPROM-Programiergeräten wie z.B. SEP-81, ALL-03A, EPROP verwertet werden kann. Diese Datei hat bereits die angegeben EPROM-Länge, und kann 1:1 in ein EPROM übertragen werden. Der ResetVektor (JMP FFFF:FFF0, der nach Reset zum Code-Start springt) wird automatisch entsprechend der angegebenen EPROM-Größe generiert.
Wird statt einer 1:1-Binärdatei eine Intel-HEX-Datei gewünscht, die praktisch alle EPROM-Programmiergeräte lesen können (auch Programmiergeräte, die über serielle Schnittstelle angeschlossen werden), so muß zusätzlich die Option /HEX angegeben werden. Intel-HEX-Dateien sind länger als die Binärdateien, und benötigen mehr Speicher auf der Festplatte.
Im folgenden sind alle bereits beschriebenen und weiter noch möglichen Optionen aufgelistet. Diese werden auch beim Aufruf von EXELOC ohne Argument "Online" dargestellt.
Syntax von EXELOC
Die Syntax von EXELOC ist folgende:
EXELOC exename [destination]
[options]
options:
/ROM: ROM-fähiger Code ( BIN- oder
Intel-HEX-Datei ) wird erzeugt.
/ROMSIZE: ROM-Größe wird auf bestimmten Wert (in kByte) gesetzt
/RAMSIZE: RAM-Größe wird auf
bestimmten Wert (in kByte) gesetzt
/ROMX : ResetVektor wird nicht erzeugt; BIN-File-Länge =Länge des Codes; dadurch können mehrere verschiedene Programme in ein EPROM geladen werden, oder ein Programm auf mehrere EPROMs verteilt werden.
/HEX: Intel-HEX-Datei wird erzeugt
/DLD: Download-File wird generiert
(Default-Einstellung)
/C: Der Code-Start wird an vorgegebner Stelle erzwungen; sinnvoll bei von MT25 abweichender Speicherkonfiguration (nur Experten sollten diese Option verwenden)
/D: Der Data-Start wird an angegeb. Pos. erzwungen (nur Experten sollten diese Option verwenden)
/V: verbose report: detaillierte Information über Relocations-Prozess für den Experten.
Anmerkungen:
-
Die Endung .EXE muß bei exename nicht angegeben werden
-
Wird destination nicht angegeben, wird hierfür der Hauptname des EXE-Files plus Endung .DLF, bzw. .BIN oder .HEX angenommen
-
Alle Fehlermeldungen von EXELOC erfolgen im Klartext
Detail-Dokumentation
zur Embedded x86 Programmentwicklung mit TurboLocator
4.1. x86 Embedded- Programmentwicklung
Ein Programm, das auf einem V25-Singlechip-Rechner läuft, hat im Unterschied zu einem PC-Programm kein DOS oder BIOS unter sich. Das V25-Programm kann auch nicht auf die vom DOS her bekannte Weise aufgerufen und in den Speicher geladen werden.
Um dennoch ein Programm für den Embedded Rechner wie den MT25 mit einem professionellen PC-Compiler entwickeln zu können, bedarf es also einer Anpassung, um ein solches Programm EPROM- oder download‑fähig zu machen. Diese Aufgabe übernimmt das MT25-Entwicklungspaket.
Wie man ein EXE-Programm so umwandelt, daß es in den EPROM- oder RAM-Speicher des MT25 geladen werden kann, wird im Kapitel 3 bei der Bedienung des Programmes EXELOC gezeigt.
Aber auch bei der Erstellung dieses EXE-Programms muß der Programmierer auf das fehlende DOS bzw. BIOS Rücksicht nehmen. Die Besonderheiten der V25-Programmierung gegenüber der DOS-Programmierung werden im folgenden für die einzelnen Compiler beschrieben. Darüber hinaus aber läuft die Programmentwicklung genauso ab, wie bei der Erstellung eines DOS-Programms gewohnt. Alle Tools, vorhandene Librarys, usw. können - soweit auf dem Controller sinnvoll - benutzt werden.
4.2. Programmentwicklung
in TurboPascal
Die Erstellung eines V25-Programmes mit Turbo Pascal ist durch die einfache Struktur von Turbo Pascal in vieler Hinsicht einfacher als in C/C++.
Von den mit Turbo Pascal mitgelieferten Units kann nur die System-Unit benutzt werden, die automatisch in jedes Turbo Pascal Programm eingebunden wird. Die Funktion der Units CRT, DOS, usw. benutzen DOS/BIOS-Funktionen, die auf dem V25 nicht verfügbar sind und ohnehin sinnlos wären (Dateiverwaltung, PC-Tastatur, Videokartenfunktionen). Diese Units dürfen auch nicht eingebunden werden, da bereits bei Inititialisierung der Units I/O- bzw. DOS /BIOS- Zugriffe erfolgen.
Die objektorientierten Erweiterungen von Turbo Pascal können ohne Einschränkungen benutzt werden.
Die meisten Optionseinstellungen können, wie auch unter DOS, je nach Sachlage angepaßt werden. Die im folgenden aufgeführten Optionseinstellungen sind jedoch bei der V25-Programmierung besonders zu beachten, und sollten so gesetzt werden wie angegeben. Hier werden die Schalterangaben für Turbo Pascal 6.0 beschrieben. Für andere Versionen von Turbo Pascal können die Schaltereinstellungen leicht abweichen oder die Schalter in anderen Menüs plaziert sein.
IDE-Compiler-Einstellungen:
Schalter |
Einstellung |
Anmerkung |
Compile/Destination |
Disk |
EXE-File muß für
Weiterverarbeitung vorliegen |
Options/Compiler/Numeric
processing |
Emulation=on, 80x87=off |
Emulator einschalten, da
keine FPU im V25 |
Options/Compiler/286-Instructions |
on |
V25 versteht alle
286-Maschinenbefehle (Real-Mode) |
Options/Compiler/Runtime
errors/I/O-Checking |
off |
|
Options/Compiler/Runtime
errors/Range check |
off |
nur bei eigenem
installierten Error-Handler sinnvoll |
Options/Compiler/Runtime
errors/Stack check |
off |
nur bei eigenem
installierten Error-Handler sinnvoll |
Options/Compiler/Debugging |
alles off |
Debug-Information
im MT25-RAM/ROM sinnlos; wird aber notfalls auch von EXELOC
weggeschnitten; |
Options/Memory sizes/Stack
size |
evtl. auf 4K verringern |
die 16K-Einstellung für DOS
ist meist Verschwendung |
Options/Linker/mapfile |
mindestens "segments" |
auch "public" und
"detailed" können gewählt werden |
Options/Debugger/Debugging/Standalone |
off |
Debug-Information
im MT25-RAM/ROM sinnlos; wird aber notfalls auch von EXELOC
weggeschnitten; |
Options/Directories/Unit
directories |
um \MT25\PAS\TPU ergänzen |
MT25-Units müssen gefunden
werden |
Options/Directories/Object
directories |
um \MT25\PAS\TPU ergänzen |
OBJ-Dateien für MT25-Units
müssen gefunden werden |
Anmerkungen:
um in einer Umgebung mit anderen TurboPascal-Projekten die Ordung zu wahren, ist es empfehlenswert, in Projektverzeichnissen eigene TURBO.TP und TURBO.DSK-Dateien anzulegen (bei Option/Save options das aktuelle Verzeichnis angeben), sodaß andere Turbo Pascal-Projekte nicht von den V25-Einstellungen betroffen werden.
bei Turbo/Borland-Pascal 7.0 (oder höher) muß als Zielplatform Real Mode verwendet werden. Der Protected Mode ist auf dem V25 nicht verfügbar.
Jedes Programm für den V25 benötigt gewisse V25-Grundfunktion und -Definitionen. Diese sind in der Unit SYSV25 enthalten, die über das "uses"-Kommando eingebunden wird. Die Unit SYSV25 befindet sich, wie alle anderen MT25-Units, im Verzeichnis \MT25\PAS\TPU und wird automatisch von der IDE gefunden, sofern die oben beschriebenen Directory-Einträge ergänzt wurden. Diese Unit liegt als PAS-File im Source-Code (mit Ausnahme des Assembler-Object-Modules) vor.
Die Unit SYSV25 enthält folgende Elemente:
Memory-Definitionen der V25-special-function-register
(SFR);
Die Bedeutung der einzelnen Register wird im NEC-V25 Handbuch genau
erklärt.
Mit Ausnahme der I/O Port-Register P0, P1, P2, PT, deren Benutzung in
mehreren Beispielen in diesem Handbuch erklärt wird, werden die SFR
jedoch von der MT25-Systemlibrary verwaltet, sodaß der Programmier sich
nur bei der Benutzung spezieller Features mit den SFR befassen muß.
die Prozeduren RL_setIntVec und RL_getIntVec zum Setzen von Interrupt-Vektoren ( die Prozeduren setIntVec und getIntVec aus der TP-Unit DOS sind nicht verwendbar (s.o.) )
Definitionen der speziellen V25-Interrupt-Nummern (siehe hierzu Kapitel über Interrupt-Programmierung)
einige Spezial-Befehle des V25 sowie oft benötigte Abkürzungs-Befehle wie FINT, BSET, BCLR, CLI, STI
grundlegende Prozeduren für die Prozessoreinstellung und Systemzeitverwaltung wie RL_initTCPorts, RL_fullSpeed, RL_SysClock, RL_wait
Prozeduren, welche die spätere nahtlose Einbindung des TurboTASK-Multitasking-Systems ermöglichen, wie RL_setMTSWVect, MT_yield
einen Standard-ExitProc-Handler, welcher bei irregulärem Programmabbruch die LED1 (unterhalb der CPU) blinken läßt; dieser wird automatisch bei Initialisierung der Unit gesetzt
Mit der SYSV25-Unit kann bereits ein erstes MT25-Programm geschrieben werden.
Der Hauptausgabeport P0 wird mit dem Muster $AA (hex) belegt und im Sekundentakt invertiert (kann bei Anschluß von LED´s sichtbar gemacht werden), gleichzeitig blinkt die Betriebs-LED mit:
program t25guid1;
uses SYSV25;
{ Basis-Unit für V25-Programme }
begin
RL_initTCPorts;
{ I/O-Ports für MT25-Rechner vorinitialisieren }
RL_fullSpeed;
{ 0 Waitstates und volle Prozessorgeschwindigkeit }
PM0 := 0;
{ Port0 (8-freie I/O-Ausgänge) auf Ausgang schalten }
P0 := $AA;
{ Bit-Muster AN-AUS-AN-AUS-AN-AUS-AN-AUS an Port 0 }
while TRUE do
{ Endlosschleife }
begin
RL_wait(1000);
{ 1000 msek. warten }
P0 := NOT P0;
{ Port P0 (Ausgabeport) invertieren }
BNOT(1,P2);
{ LED-Beleuchtung invertieren }
end;
end.
Nach der Durchführung nachfolgend aufgeführter Schritte ist das Programm ablauffähig:
Programm mit Compile/Compile (F9) übersetzen; es entsteht eine EXE- und eine MAP-Datei
EXELOC-Lauf (s.o.)
Downlaod mit Programm DLX (s.o)
Anmerkungen:
Ein Programm für den MT25 darf niemals abgebrochen werden, da eine Rückkehr zu einem Betriebssystem wie DOS nicht möglich ist (etvl. Programm mit Endlosschleife abschließen)
Die beiden ersten Befehle (RL_initTCPorts und RL_fullSpeed) sollten immer ein Programm für den MT25 einleiten
4.2.4. Die MT25-Systemlibrary für TurboPascal
Die MT25-Systemlibrary für Turbo Pascal liegt in mehreren Units vor, welche ganz normal über den USES-Befehl in ein Anwenderprogramm eingebunden werden. Erst durch die Benutzung dieser Library geht die Programmierung des MT25 mit allen seinen Hardwarekomponenten zügig und bequem von statten. Im folgendem werden die einzelnen Units mit allen Proceduren und Funktionen beschrieben.
Anmerkungen:
bei der Beschreibung der nachfolgenden Library-Funktionen werden unter dem Kennzeichen MT auch Informationen zur Multithreading-Fähigkeit gegeben: zur Bedeutung siehe Kapitel TurboTASK Multitasking-System. Wird MT nicht benutzt, können diese Hinweise einfach überlesen werden.
oft wird im folgenden der Begriff Funktion in Anlehnung an C als Oberbegriff von Function und Procedure in Turbo Pascal verwendet .
4.2.4.1. Unit SYSV25
Die Unit SYSV25 muß in jedes Programm für den V25 eingebunden werden, und stellt grund-legende Dienste für den V25/MT25 zur Verfügungung.
Funktionen
und Prozeduren:
procedure RL_initTCPorts;
setzt I/O-Ports für MT25 auf die korrekte
Richtung (Ein- oder Ausgang) und initialisiert die Ports
procedure RL_FullSpeed;
Prozessor ohne Wait-States laufen lassen. Sollte praktisch immer als
erstes gerufen werden (außer bei "Uralt-EPROMs" mit mehr als 250ns
Zugriffszeit)
function
RL_SysClock:longint;
liefert Zeit in Millisekunden seit Programmstart; fängt nach
$FFFFFFFF wieder bei 0 an;
procedure RL_wait(wtime:longint);
wartet wtime Millisekunden; bei Verwendung von TurboTASK
wird die Rechenzeit für andere Tasks benutzt
procedure RL_SetIntVec(intnr:
byte; vector:pointer)
setzt Interrupt-Vector für Interrupt mit Nummer intnr auf
Interruptprocedur mit Adress vector ( DOS-Unit-Procedure SetIntVec darf
nicht benutzt werden)
procedure RL_GetIntVec(intnr:
byte; var vector:pointer)
gibt Interrupt-Vector für Interrupt mit Nummer <intnr>
in der Pointervariable <vector> zurück ( DOS-Unit-Procedure
GetIntVec darf nicht benutzt werden)
procedure BSET(nr:
bits; var location: byte);
procedure BCLR(nr:
bits; var location: byte);
procedure BNOT(nr:
bits; var location: byte);
Bitmanipulationsbefehle zum Setzen, Löschen, Invertieren des
Bits <nr> in der Variable location; Vorteil gegenüber AND / OR /
XOR: Manipulation erfolgt mit einem Maschinenbefehl, sodaß die Bits in
derselben Variable auch von Interrupt-Routinen benutzt werden können.
procedure FINT;
FINT-Befehl des V25: Quittiert Interruptkontroller nach
Beendigung eines Interrupt;
muß am Ende jeder selbstdefinierten Interruptprozedur gerufen werden,
welche einen V25-internern Interrupt (z.B. INTP0) handled (siehe
T25GUID4.PAS)
procedure STI;
procedure CLI;
Äquivalente zu den Assembler-Befehlen cli und sti;
procedure MT_yield;
(MT)
gibt unter TurboTASK den Rest der aktuellen
Zeitscheibe des aufrufenden Tasks für das System frei; diese Funktion
sollte ständig gerufen werden, wenn die Task zur Zeit nichts zu tun hat
(z.B. auf Eingaben oder bestimmte Zustände wartet), um die Rechenzeit
anderen Tasks zukommen zu lassen; läuft TurboTASK
nicht, so ist MT_yield wirkungslos (lediglich return-Befehl); es ist
aber sinnvoll diese Funktione auch ohne TurboTASK
schon zu verwenden, um bei einem späteren Umstieg auf TurboTASK-Multitasking
bereits eine Task in den Händen zu haben, der sparsam mit der
Prozessorzeit umgeht.
Diese Prozedur gehört eigentlich zum Befehlssatz der TurboTASK-Routinen,
wird aber aus dem eben geschilderten Grund bereits ohne TurboTASK
angeboten.
procedure RL_setMTSWVect(handler:pointer);
(MT)
setzt Handler für MT_yield;
ist nur für interne Verwendung gedacht (TurboTASK ruft
diese Prozedur)
procedure RL_init;
initialisiert das Assemblermodul zu SYSV25;
nur für interne Verwendung gedacht (wird bei Unit-Init. gerufen)
procedure handleAbort;
Standard-Exit-Prozedur (wird bei Unit-Init. gesetzt)
läßt bei irregulärem Programmabbruch die LCD-Beleuchtung blinken;
procedure RL_clearWatchDog;
Siehe Kapitel 2.3. Watchdog
Anmerkung:
es ist sinnvoll, die Datei SYSV25.PAS - v.a. die Abort-Procedur - im Quellcode zu betrachten;
4.2.4.2. Unit LCD
Die Unit LCD stellt alle Funktionen zur Verfügung um das Standard LCD-Display von IMT am LCD-Port des MT25 mit einem HD44780-LCD-Controller anzusteuern. Auch andere LCD-Displays mit diesem Controller können von der Unit LCD angesteuert werden.
Die Benutzung einiger wichtiger Funktionen der LCD-Unit zeigt das Demoprogramm T25GUID2.PAS
MT: alle Funktionen sind multithreadingfähig.
d.h. die Funktionen stören sich bei gleichzeitiger Ausführung nicht
gegenseitig beim Zugriff auf Hardware (Serialisierung der
Hardware-Zugriffe). Vorsicht ist aber angebracht, wenn z.B. mehrere
Threads den HardwareCursor benutzen. (z.B. LCD_gotoXY mit
darauffolgenden LCD_write-Aufrufe). Chaos auf dem LCD ist dann
vorprogrammiert.
Diese Probleme umschiffen einige Funktionen mit erweiterter
MT-Fähigkeit (z.B. LCD_writeXY ), die dafür sorgen, daß verschiedene
Bereiche des LCD-Displays von verschiedenen Threads
benutzt werden können. Besonders die Prozedur LCD_writeXY sollte der
Prozedur LCD_write immer vorgezogen werden.
Funktionen und Prozeduren:
procedure LCD_init;
braucht normalerweise nicht explizit aufgerufen werden, da diese automatisch bei unit-Initialisierung aufgerufen wird;
procedure LCD_clrScr;
löscht Bildschirm und setzt Cursor an Position 0/0;
procedure LCD_gotoXY(x,y:integer);
versetzt den Hardware-Cursor an die Position x/y;
die linke obere Position hat die Koordinaten 0/0 (im Gegensatz zu
gotoxy in der crt-Unit);
procedure LCD_write(s:string);
schreibt String an aktueller Cursorposition auf den
Bildschirm;
procedure LCD_writeXY(x,y:integer;
s:string)
MT: erweitert
MT-fähig
schreibt String s an Position x,y auf den Bildschirm;
die linke obere Position hat die Koordinaten 0/0 (im Gegensatz zu
gotoxy in der crt-Unit);
LCD_putCharXY(x,y:integer; c:char)
MT: erweitert MT-fähig
schreibt einzelnes Zeichen c an Position x/y auf
Bildschirm;
LCD_clrLine(y:integer);
MT: erweitert
MT-fähig
löscht die Zeile y am Bildschirm komplett; die oberste
Zeile ist die Zeile 0;
procedure LCD_enableBlink;
schaltet Blinken des Cursors ein;
procedure LCD_disableBlink;
schaltet Blinken des Cursors aus;
procedure LCD_showCursor;
macht Cursor sichtbar;
procedure LCD_hideCursor;
macht Cursor unsichtbar;
function
LCD_getCurX:integer;
liefert X-Position des Cursors; Umkehrung zu LCD_gotoXY
function
LCD_getCurY:integer;
liefert Y-Position des Cursors; Umkehrung zu LCD_gotoXY;
procedure LCD_setUserChar(charno: byte,
bitmap:pointer);
erstellt selbstdefiniertes Zeichen;
<charno> ist die Nummer des selbstdefinierten Zeichens und hat
den Wertebereich 0..15;
dabei sind jedoch die Zeichen 0..7 identisch mit den Zeichen 8..15;
Es stehen also insgesamt 8 verschiedene selbstdefinierbare Zeichen zur
Verfügung.
Die Sonderzeichen können als normale Charakter bei Aufrufen wie
LCD_writeXY in Strings oder Charakters übergeben werden. Sie belgen den
ASCII-Bereich 0..15;
<bitmap> ist ein Zeiger auf eine 8 Byte lange Struktur, welche
die Bitmap-Information für
das Zeichen beinhaltet. Ein Zeichen hat das Format 5x7(8) Punkte. Die
8. Zeile kann benutzt werden, allerdings wird sie bei Benutzung des
Hardware-Cursors von diesem überlappt.
Die Bitmapstruktur hat folgenden Aufbau (Binärzahlen):
Aufrufbeispiel:
...
const
fnt_haus:array[0..7] of byte=($04,$0A,$11,$15,$11,$11,$15,$1F);
...
LCD_setUserChar( 3,
@fnt_haus );
LCD_writeXY(0,0,'User-Char:
'+chr(3) );
Das Demoprogramm T25GUID6 zeigt die Anwendung der selbstdefinierten
Zeichen ausführlich.
procedure LCD_wait;
intern: warten bis LCD
für nächste Operation bereit ist
4.2.4.3. Units SER0 und SER1
Die beiden Units SER0 und SER1 stellen viele Routinen zur Verfügung, die für die serielle Kommunikation benötigt werden. Sowohl empfangs- wie senderseitig wird Puffer-Betrieb zur Verfügung gestellt, sodaß die entsprechenden Funktionen sofort an das aufrufende Programm zurückkehren, während der Empfangs- und Sendebetrieb im Hintergrund von Interrupt-Handlern erledigt wird. Die Puffergröße beträgt jeweils 128Byte.
SER1: RS232 (auch Downloadschnittstelle)
SER0: RS232 oder RS485
procedure SERx_putChar(c:char);
sendet ein Zeichen über Puffer-Betrieb;
function
SERx_getChar:integer;
gibt nächstes Zeichen aus Empfangspuffer zurück, bzw. -1,
wenn Empfangspuffer leer ist;
procedure SERx_putStr(s:string);
sendet String über Puffer-Betrieb;
procedure SERx_putBlk(p:pointer;
n:word);
sendet Datenblock über Puffer-Betrieb;
n : Länge des Datenblocks in Byte;
p : Pointer auf 1. Byte des Datenblocks;
mit Hilfe dieser Funktion können Datenblöcke größer als 255 Byte
übertragen werden;
procedure SERx_setBaudRateX(br:
integer; brxflags:byte)
(set baudrate extended)
setzt BaudRate und Bit-Einstellungen der seriellen
Schnittstelle. Die Default-Einstellungen sind:
9600Baud, no parity,
(even) , 8Bit, 1 Stoppbit
br
: spezifiziert Baudrate; die Konstanten BR_1200 bis
BR_115200 sind vordefiniert;
brxflags
: Bitfeld, über welches die verschiedenen
Bit-Einstellungen gesetzt werden;
folgende Bit-Masken-Konstanten sind
(vor-)definiert:
BRXF_2StoppBit
: 2 Stoppbits
BRXF_7Bit
: 7 Bit - Zeichenlänge
BRXF_ParOdd
: ungerade Parität (falls Parity-Betrieb)
BRXF_Parity
: Parity-Betrieb einschalten
sollen mehrere Flags gesetzt werden, müssen
die Flags ODER-verknüpft
werden
Anmerkung: Flag, das nicht gesetzt ist ® der jeweilige Wert aus den
Defaulteinstellungen wird genommen.
Beispiel:
SER0_setBaudRateX(BR_19200,
BRXF_7Bit OR BRXF_Parity)
in diesem Beispiel wird 19200Baud/7Bit/even
Parity/1Stoppbit gewählt
procedure SERx_setBaudRate(br
: integer);
setzt BaudRate der seriellen Schnittstelle, die
Bit-Einstellungen bleiben unberührt;
br : spezifiziert Baudrate; siehe SERx_setBaudRateX;
procedure SERx_sendChar(c:
char);
sendet Zeichen ungepuffert;
procedure SERx_sendBlk(n:
integer; p: pointer);
sendet Block ungepuffert;
Argumente siehe SERx_putBlk;
function
SERx_TransmitterBusy:boolean;
liefert TRUE, falls der gepufferte Sendebetrieb noch läuft,
FALSE, falls sich keine Zeichen im Sendepuffer befinden;
procedure SERx_init;
intern: wird automatisch bei Unit-Initialisierung aufgerufen
Die Unit SER0 enthält zusätzlich folgende Prozedur zur RS485-Steuerung:
procedure RS485_setDir(direction:
integer);
setzt die Übertragungsrichtung des RS485-Wandlerbausteins;
direction = 0 für Empfang;
direction = 1 für Senden;
direction = 2 für Senden + Mithören (für Netzwerkbetrieb)
Die Default-Einstellung nach Unit-Initialisierung ist Empfang
(direction=0).
Hinweis: Die Serielle Schnittstelle SER0 kann mit dem RS485-Wandler
verbunden werden (s. Anhang: 7.5. Jumperbelegung)
4.2.4.4. Unit SEP
Die Unit SEP wird benötigt, um das serielle 128-Byte große E2PROM auf dem MT25 anzusteuern. Das E2PROM ist in 64 Worten von jeweils 16 Bit organisiert. Folgende Routinen werden zur Verfügung gestellt:
procedure SEP_EWEN;
(erase/write-enable)
erst nach Aufruf dieser Procedure kann schreibend oder löschend auf das
E2PROM zugegriffen werden;
procedure SEP_EWDS;
(erase/write-disable)
nach Aufruf dieser Procedure ist das E2PROM
wieder hardwaremäßig gegen Schreib/Lösch‑Zugriffe gesperrt;
function SEP_read(adress:word):word;
das 16-Bit-Wort an der Adresse <adress> wird ausgelesen
und zurückgeliefert;
<adress> hat den Wertebereich 0..63 ($00..$3F), es existieren
also 64 Word-Speicherstellen
procedure SEP_write(adress:word,
value:word);
der 16-Bit-Wert value wird an Adresse <adress> ins E2PROM geschrieben;
ein vorheriges Löschen der Speicherstelle ist nicht nötig, da das E2PROM wortweises auto‑erase‑write unterstützt. Ein
Schreibzugriff dauert ca. 2msek (Microchip) bis
4ms (EXCEL u.a). Diese Zeit macht sich nur bei wiederholtem Schreiben
bemerkbar.
Bei einem einzelnen Schreibzugriff kehrt SEP_write sofort zurück, da
die letzte Schreiboperation immer im Hintergrund (automatisch im E2PROM ) abläuft. Bei direkt aufeinanderfolgenden
Schreibzugriffen legt SEP_write dann evtl. erforderliche Wartezeiten
ein.
procedure SEP_erase(adress:word);
die Speicherstelle <adress> wird gelöscht (mit $FFFF
belegt);
ein Löschzyklus dauert ca. 1msek. (Microchip) - 2msek. (andere);
das dynamische Zugriffsverhalten ist wie bei SEP_write;
procedure SEP_eraseAll;
löscht komplett alle 64 Speicherstellen des E2PROM;
Dauer des Löschvorgangs: ca. 15msek. Die Funktion kehrt sofort zurück.
Wartezeit fällt evtl. beim nächsten E2PROM-Zugriff
an (siehe SEP_write), falls er innerhalb der 15msek. ausgeführt wird.
4.2.4.5. Unit ANA
Die Unit ANA ermöglicht den einfachen Zugriff auf den AD-Wandler des MT25 (sofern bestückt).
Diese Unit besteht lediglich aus einer Funktion:
function ANA_readAD(nr:word):word;
liest einen 12-Bit-Wert vom AD-Wandler mit Nummer <nr>;
<nr> hat den Werte-Bereich 0..7 für die 8 AD-Wandler-MUX-Eingänge;
Hinweis: Die Wandlungszeit des AD-Wandlers ist so extrem kurz (12µs),
daß der Benutzer dieser Funktion keine Rücksicht darauf nehmen muß.
4.2.4.5. Unit RTC
Das Modul RTC stellt alle Funktionen zur Verfügung, die zum Zugriff auf die Echtzeituhr erforderlich sind.
Proceduren:
procedure RTC_GetTime(var Hour, Minute,
Second, Sec100: Word);
schreibt die aktuelle Zeit der Echtzeituhr in die angegebenen
Var-Parameter
procedure RTC_SetTime(Hour, Minute, Second,
Sec100: Word);
setzt die Zeit der Echtzeituhr auf die Zeit in den angegebenen
Parametern
procedure RTC_GetDate(var Year, Month, Day:
Word);
schreibt das aktuelle Datum der Echtzeituhr in die
angegebenen Var-Parameter
procedure RTC_SetDate(Year, Month, Day: Word);
setzt das Datum der Echtzeituhr auf das Datum in den
angegebenen Parametern
4.2.5. Auffinden von Turbo Pascal-Runtime-Fehlern
Turbo Pascal liefert in folgenden Fällen einen Runtime-Fehler:
Division durch Null
Stacküberlauf
Heapüberlauf
Range-Error (bei eingeschaltetem Range-Check)
In diesen Fällen wird eine Routine angesprungen, auf welche der System-Pointer ExitProc zeigt. Standardmäßig wird hier von der SYSV25-Unit eine Prozedur installiert, welche die LED1 blinken läßt.
Indem ExitProc mit einem anderen Wert beschrieben wird, kann der Anwender eine eigene Procedur installieren, welche z.B. über die Systemvariablen ExitCode und ErrorAddr eine genaue Fehlermeldung auf dem LCD-Display präsentiert, mit der der Fehlerauslöser lokalisiert werden kann. Die Position im Sourcecode könnte z.B. mit Search/Find error bzw. Compile/Find error in der IDE gefunden werden, sofern "Intergrated Debugging" eingeschaltet ist.
4.2.6. Ausblick auf Multitasking-Programmierung
Für den Einsatz des Multitaskingsystems TurboTASK soll hier kurz auf ein kleines Demonstrationsprogramm hingewiesen werden. Der Pfad des Demo-Programmes ist \MT25\PAS\EXAMPLES\MT_DEMO.PAS. In diesem Programm laufen - ohne besondere Interrupt-Programmierung - eine mathematische Berechnung, eine Tastaturkommunikation sowie die Anzeige einer Systemzeit gleichzeitig ab.
4.3. Programmentwicklung mit C/C++
Die Einrichtung einer C/C++ Programmierumgebung für die V25-Programmentwicklung erfordert einen Schritt mehr als bei Turbo Pascal: Die Einbindung eines speziellen Startcodes.
Dafür bietet das C/C++-System größere Flexibilität bei der Benutzung der Library. Aus allen mit dem Compiler mitgelieferten Librarys können Funktionen verwendet werden, die kein DOS/BIOS benutzen, wie z.B. die in folgenden Header-Dateinen deklarierten Funktionen:
math.h, alloc.h, mem.h,viele stdlib.h-Funktionen, string.h, usw...
(im folgenden wird davon ausgegangen, daß Turbo- oder Borland-C im Verzeichnis \TC liegt )
Die meisten Optionseinstellungen können, wie auch unter DOS, je nach Sachlage angepaßt werden. Leztlich ist immer der Programmierer dafür verantwortlich, ob eine Einstellung zu einem Programm paßt. Die im folgenden aufgeführten Optionseinstellungen sind jedoch bei der V25-Programmierung besonders zu beachten, und sollten so gesetzt werden wie angegeben. Hier werden die Schalterangaben für TurboC++ 1.0 beschrieben. Für andere Versionen von Turbo/Borland-C/C++ können die Schalterbezeichnungen leicht abweichen, oder die Schalter in anderen Menüs plaziert sein (/code generation/more/ ist z.B. je nach Compilerversion als /advanced code generation/ implementiert).
IDE-Compiler-Einstellungen:
Schalter |
Einstellung |
Anmerkung |
Options/Compiler/code
generation/more/ Model |
verwendetes
Speichermodell wählen (außer HUGE/TINY) |
Es muß dann die zum
Speichermodell passende MT25-Library beim Linken verwendet werden: V25S.LIB, V25M.LIB,
V25C.LIB oder V25L.LIB Das Modell SMALL ist für
MT25-Projekte meist die beste Wahl, da sehr schnell, und bis zu 64K
Daten und 64K Programmcode |
Options/Compiler/code
generation/more/ Floating
Point |
Emulation |
Emulator einschalten, da
keine FPU im V25 |
Options/Compiler/code
generation/more/ Instruction
Set |
80186 |
V25 versteht alle
286-Maschinenbefehle (Real-Mode) |
Options/Compiler/code
generation/ test
stack overflow |
off |
nur bei eigenem
installierten Error-Handler sinnvoll |
Options/Compiler/code
generation/more/ Debug
info in OBJs |
off |
Debug-Information
im MT25-RAM/ROM sinnlos; wird aber notfalls auch von EXELOC
weggeschnitten; |
Options/Linker/mapfile |
mindestens "segments" |
auch "public" und
"detailed" können gewählt werden |
Options/Debugger/Debugging/Source
Debuffing |
off oder Standalone |
Debug-Information
im MT25-RAM/ROM sinnlos; wird aber notfalls auch von EXELOC
weggeschnitten; |
Options/Directories/Include
directories |
um \MT25\C\INCLUDE ergänzen |
MT25-Include-Dateien müssen
gefunden werden Beispiel: "C:\TC\INCLUDE;C:\MT25\C\INCLUDE" |
Options/Directories/Library
directories |
\MT25\C\LIB; voranstellen |
MT25-Librarys
müssen gefunden werden. Dieser Eintrag muß vor allen anderen eingefügt
werden, damit die MT25-Startdateien anstelle der original Borland
Startdateien gelinkt werden Beispiel: "C:\MT25\C\LIB;C:\TC\LIB" |
Anmerkungen:
um in einer Umgebung mit anderen TurboC-Projekten die
Ordung zu wahren, ist es empfehlenswert, in Projektverzeichnissen
eigene TCDEF.DPR und TCDEF.DSK-Dateien anzulegen (siehe
Borland-Handbücher), sodaß andere TurboC-Projekte nicht von den
V25-Einstellungen betroffen werden.
Diese Dateien dazu aus dem \TC\BIN-Verzeichnis ins Projektverzeichnis
kopieren, TC (bzw. BC) aufrufen, Einstellungen treffen, mit
Options/Save abspeichern. Allerdings werden wohl bei der Erstellung
größerer V25-Programme fast immer Projekt-Dateien verwendet. Die
Einstellung werden dann ohnehin lokal in der Projektdatei gespeichert.
4.3.3. Aufbau von V25-C-Programmen
Ein C-Programm für den V25 kann in 4 vom DOS her bekannten Speichermodellen erstellt werden. Dabei sind die maximale Größe von Programmcode und der Daten, sowie die Größe von Pointern unterschiedlich. 2 Borland-spezifische Speichermodelle können für V25-Programme nicht verwendet werden:
Das Modell TINY kann nicht auf EPROM gebrannt werden, da Daten und Code im selben Segment angelegt werden und dies zu Hardware-Problemen führt (zum Download könnte dieses Modell theoretisch verwendet werden).
Das DOS-Model Huge mit automatischen FAR-Zeigern wurde nicht berücksichtigt, da in diesem Model das DS‑Segment‑Register von fast jeder Procedur neu gesetzt werden müßte, was erhebliche Geschwindigkeitseinbußen und ungerechtfertigten Aufwand mit sich bringen würde. Stattdessen muß auf das Modell Large ausgewichen werden. Nichts desto trotz können in den anderen Speichermodellen natürlich huge-Zeiger verwendet werden.
Modell Small:
wird man meistens benutzen wenn Programme nicht zu groß
sind;
Code: default NEAR-Funktionen,
max. 64K
Daten: default NEAR-Zeiger,
max. 64K incl. Stack
Modell Medium:
Code: FAR-Funktionen,
max. 1M
Daten: NEAR-Zeiger,
max. 64K incl. Stack
diese Modelle nur sinnvoll
ab 128k RAM ! |
Modell Compact:
Code: NEAR-Fkts.,
max. 64K
Daten: FAR-Zeiger,
max. 1M
Modelle Large:
Code: FAR-Fkts.,
max. 1M
Daten: FAR-Zeiger,
max. 64K
Bauplan eines
C/C++-V25-Programmes:
Bestandteile eines C-Programmes:
c0-Startcode (c0s.OBJ
- c0l.OBJ {small bis large});
Der Startcode wird vom Linker als erste Datei gelinkt. Diese Datei ist
für DOS- und WINDOWS-Programme von Borland mitgeliefert. Bei einem
V25-Programm muß diese durch V25‑Startcode der MT25‑Systemlibrary
ersetzt werden.
eigene Programm-Module ( z.B. DEMOA.OBJ compiliert aus DEMOA.C )
zusätzliche Librarys ( z.B. V25S.LIB die
small-model-Library mit allen Funktionen der MT25‑Systemlibrary);
diese Librarys müssen über Projectdatei oder TLINK gelinkt werden
Standard-C-Library (cs.lib
bis ch.lib );
von Borland geliefert und auch im V25-Programm bis auf DOS-lastige
Funktionen verwendbar
Wichtig:
In
einem V25-Programm muß beim Linken der
Borland‑Startcode \TC\LIB\C0x.obj durch den V25-Startcode
\MT25\C\C0x.obj (identisch zu \MT25\C\V0x.obj) ersetzen
(x steht für s,c,m oder l )
Einbindung des
V25-Startcodes:
Da normalerweise automatisch der Borland C0-Code gelinkt wird, müssen besondere Vorkehrungen getroffen werden, um die V25-Startdatei zu linken:
1. Fall: IDE integrierte
Entwicklungsumgebung
Vorgehensweise:
die V25-Startdateien (V0x.obj und identisch C0x.obj) ins V25-Library-Verzeichnis kopieren. Dies ist auf den Installationsdisketten schon vorbereitet und wurde bei der Installation automatisch durchgeführt
in Options/Direktorys/Library
Direktories einen Eintrag voranstellen, so daß die V25‑Startdatei
zuerst gefunden wird
(z.B.: "C:\MT25\C\LIB;.;C:\TC\LIB" statt
"C:\TC\LIB", falls die V25-Startdateien im Verzeichnis C:\MT25\C\LIB liegen, wie bei der Installation empfohlen)
beim ersten Test die Funktion void RL_FullSpeed(void) (oder eine andere RL_-Funktion) benutzen:
[ File
\MT25\C\EXAMPLES\LINKTEST.C ]
#include
<SYSV25.H>
main() {
RL_FullSpeed();
while( 1 );
}
Das
Programm kann durch Drücken der Taste F9 compiliert werden.
Die Funktion RL_FullSpeed wird nur von der V25-Startdatei zu Verfügung gestellt. Erhält man einen Linker Error, so bedeutet dies, daß doch noch die Borland C0x.obj-Datei benutzt wird. Der Library-Pfad ist wahrscheinlich falsch angegeben.
Anmerkung: Da eine RL_...-Funktion praktisch in jedem Programm benutzt wird, fällt eine falsche C0-Datei immer durch einen Linker-Error auf
die Einstellungen mit Options/Save abspeichern
2. Fall:
Arbeiten mit Kommandozeile und Makedatei
Vorgehensweise:
statt der Borland-C0x.obj einfach die V25-V0x.obj beim TLINK-Befehl verwenden;
Beispiel:
TLINK \MT25\C\LIB\V0s ownprg,ownprg,,\TC\LIB\cs
MT25\C\LIB\v25s.lib
(statt TLINK \TC\LIB\C0s
ownprg,ownprg,,\TC\LIB\cs \MT25\C\LIB\v25s.lib bei einem DOS-Programm)
Hinweis:
Im Verzeichnis \MT25\C\LIB existieren identische Startdateien als C0x.obj und V0x.obj. Wird explizit mit TLINK gearbeitet, sollte v0x.obj verwendet werden, um Verwechslungen mit den Borland-Startdateien zu vermeiden; die c0x.obj existieren, um der IDE (welche immer die Namen C0x.obj verwendet) die V25-Startdateien unterzuschieben (siehe Fall 1).
Einbindung
der MT25-System-Library in eigene Projekte
Neben der Startdatei wird für ein MT25-Programm in der Regel immer die MT25-Library benutzt. Im Unterschied zu Turbo Pascal Paket sind hier alle Module der MT25-System-Library in einer einzigen Library-Datei archiviert. Eine Ausnahme bilden die RL_..-Funktionen (Root-Library), welche schon in der Startdatei enthalten sind.
Für jedes der 4 Speichermodelle existiert jeweils eine solche Library-Datei mit Namen v25x.lib (und eine Startdatei mit Name c0x.obj und identisch v0x.obj). Alle diese Dateien liegen im Verzeichnis \MT25\c\lib.
Im Falle z.B. des Modells Small ist dies die Library \MT25\c\lib\v25s.lib. Diese Library muß zunächst beim Link‑Vorgang explizit angegeben werden, da standardmäßig nur die Standard-C-Librarys gelinkt würden. Der Kommandozeilen/Makefile-Programmierer gibt hier in der selben Weise, in der die Standard-C-Libraries gelinkt werden, einfach zusätzlich die v25x.lib an.
Bei Verwendung der IDE kann das Hinzulinken über eine Projekt-Datei erfolgen. Nur Programme mit lediglich einem Modul (außer den Standard-C-Libraries) können ohne Projektdatei gelinkt werden, wie z.B. LINKTEST.C (s.o.). Eine Möglichkeit, wie dennoch nicht auf das bequeme 1‑Modul‑Verfahren ohne Projektdatei verzichtet werden muß, wird weiter unten aufgezeigt.
Die meisten TurboC-erfahrenen Programmierer wissen, wie das Anlegen einer Projektdatei funktioniert. Nachfolgend werden die einzelnen Schritte in Kurzform angegeben:
-
in das Verzeichnis wechseln, in dem die Programmodule liegen
-
TC (bzw. BC) starten.
-
/Project/Open project aufrufen
-
den gewünschten Projektnamen angeben (z.B. T25GUID3.PRJ)
-
---> es erscheint ein Projekt-Fenster
-
Taste [INSERT] drücken
-
1. Eintrag angeben (z.B. T25GUID3.C)
-
2. Eintrag angeben (z.B. V25S.LIB )
der Library-Pfad muß nicht und soll nicht explizit angegeben werden, wenn das Modul bereits über den Library-Pfad (/Options/Direktories) gefunden wird -
evtl. weitere Module angeben
-
Projektdatei mit /Options/Save sichern, da dies nicht immer automatisch beim Verlassen des Compilers erfolgt
-
mit F9 Projekt "maken"; sollten keine Compiler- oder Link-Fehler auftreten, entsteht die gewünschte EXE-Datei (trägt den Namen des Projekt-Files)
Einbindung der MT25-System-Library in die Standard-C-Library
Eine andere Möglichkeit, um in der IDE (kleinere) V25-Projekte zu compilieren, ohne jedesmal die V25x.lib explizit in einer Projekt-Datei anzugeben, besteht darin, die Standard-C-Library um die MT25-Library zu erweitern. MT25-Programme mit nur einem C-Modul können dann wie gewohnt einfach durch Drücken der Taste F9 erstellt werden. Die Library-Erweiterung sollte folgendermaßen ablaufen:
die Standard-C-Library des gewünschten Speichermodells aus dem Borland-Verzeichnis ins Verzeichnis \MT25\C\LIB kopieren, z.B.: (Modell Small)
xcopy c:\tc\lib\cs.lib c:\MT25\c\lib
ins Verzeichnis \MT25\C\LIB wechseln, z.B.:
c:
cd \MT25\c\lib
die zum Speichermodell passende
MT25-Systemlibrary mit dem Borland Library-Utility TLIB zur (Kopie der)
Standard-C-Library hinzuaddieren, z.B.:
tlib cs +v25s.lib
Da in der IDE im Library Pfad der Verzeichniseintrag \MT25\C\LIB vor dem Borland-Library-Verzeichnis aufgeführt ist (vorrausgesetzt die Installationshinweise wurden beachtet), wird die nun erweiterte Standard-C-Library immer zuerst gefunden und verwendet. Die MT25-Library muß ab sofort nicht mehr explizit beim Linken angegeben werden.
Achtung:
Bei
einem Versionsupdate von Turbo/Borland-C oder natürlich der
MT25-System-Library muß der hier beschriebene Vorgang wiederholt
werden, damit Library und Compiler zusammenpassen, bzw. die MT25-System-Library aktuell ist.
Es ist nicht garantiert, das Library und Compiler verschiedener
Versionen kombiniert werden können !
Verwendung von Heapfunktion in den Speichermodellen Compact und Large
(bzw. der expliziten Far-Heap-Funktionen in Small und Medium)
Die Standard-C-Routinen der Borland-Library zur Verwaltung des sogenannten Far-Heap (dynamischer Speicher außerhalb des Datensegments) sind nicht EPROM-fähig, da sie Variablen im Code-Segment führen!
Der Far-Heap wird in den Speichermodellen Compact und Large standardmäßig von den Routinen malloc, free, ..., sowie den C++-Operatoren new und delete benutzt. Auch in den Speichermodellen Small und Medium kann der Far-Heap über die Spezialfunktionen farmalloc, farfree, ... benutzt werden !
Für den Fall, daß ein V25-Programm den Far-Heap benutzen muß, ist im MT25‑Entwicklungssystem ein Far-Heap-Ersatzmodul mit identischer Funktion aber mit EPROM-Fähigkeit enthalten. (Pfad: \MT25\C\LIB\MTFHEAPx.OBJ, wobei x=s,m,c oder l entspr. Speichermodell)
Anmerkung: Dieses Ersatzmodul arbeitet ohne Einschränkung auch unter DOS, und ist zugleich multithreadingfähig (ursprünglich Bestandteil von TurboTASK)
Folgendes Modul der Borland-C-Library muß ersetzt werden:
FARHEAP
Folgendes Modul ist das neue EPROM-feste Ersatzmodul
MTFHEAPx.OBJ (x
= s,m,c,l)
Am Beispiel des Modells Small wird demonstriert, wie das Auswechseln des Moduls funktioniert:
ins Verzeichnis \MT25\C\LIB wechseln
mit COPY \TC\LIB\CS.LIB die Original-Borland-Library kopieren
wie die Startdatei c0s.obj wird ab jetzt die im \MT25\c\lib-Verzeichnis
liegende cs.lib vom IDE-Linker benutzt, die im Library-Pfad zuerst kommt
Achtung: Wurde dieser Schritt schon beim
"Einbinden der MT25-Lib. in die Standard-
C-Lib." durchgeführt, so ist dieser Schritt nicht ein 2.
mal auszuführen !
sicherstellen, daß das Borland-Dienstprogramm TLIB.EXE zur Verfügung steht (normalerweise auch im \TC\BIN-Verzeichnis)
mit TLIB CS -FARHEAP das EPROM-untaugliche Modul aus der Library entfernen
mit TLIB CS +MTFHEAPs das neue EPROM-taugliche Module in die Library einfügen (Memory-Model SMALL)
in Zukunft sicherstellen, das auch
wirklich die neue CS.LIB benutzt wird
Die neue CS.LIB kann bedenkenlos auch auf die Originaldatei
zurückkopiert werden, da das Ersatzmodul ohne Einschränkung auch unter
DOS lauffähig ist.
MT25-Header-Datei
Die Header-Datei \MT25\C\INCLUDE\SYSV25.H für MT25-Projekte besteht aus folgenden Komponenten:
Definitionen aller
Spezial-Function-Register (SFR) des V25 wie z.B. P0, BRG1, ...
die SFR sind als Memory-Locations definiert, d. h. , sie können direkt
wie normale Variablen beschrieben und gelesen werden (z.B. P0 += 0x35; )
Definitionen der Nummern aller
V25-spezifischen und einiger weiterer Interrupt-Nummern
z.B.: INTP0, INTDOS
Prototypen aller Funktionen der MT25-System-Library und der Rootlibrary-Funktionen, die vom Startcode zur Verfügung gestellt werden (z.B. void LCD_writeXY(int x,int y,const char *s) )
Utility-Makros, wie BSET (Bit setzen), CLI (Interrupt sperren), usw.
Prototypen der TurboTASK-Routinen, welche allerdings ohne die TurboTASK-Library nicht verwendet werden können (Ausnahme MT_yield (s.u.) )
Die Headerdatei sysv25.h ist somit die einzige MT25-spezifische Datei, die in ein MT25-Programm "included" werden muß.
Anmerkungen:
In C wird durch die Definition eines Prototypen noch nicht das Linken des dazugehörigen Library-Modules und damit die Belegung des vom Modul benötigten Speichers veranlaßt. Das Linken wird erst veranlaßt, wenn der Prototyp tatsächlich benutzt wird. So kann hier gegenüber dem Turbo Pascal Paket der Vorteil genutzt werden, daß nur eine einzige Header-Datei eingebunden werden muß.
Die Funktionen in der MT25-System-Library sind nach Modulen geordnet (wie die Units des Turbo Pascal Paketes). Die Module LCD, KBD, SER0, SER1 (MT) besitzen eine init-Funktion (z.B. LCD_init() ).
Bevor Funktionen
aus einem Modul benutzt werden können muß zuerst die Init-Funktion des
Moduls gerufen werden!
Auf einen automatischen Modul-Init (mittels INIT-Segment-Methode) wurde bewußt verzichtet, so daß eine "manuelle Kontrolle" der ablaufenden Vorgänge möglich ist. (Vorteil bei Fehlersuche, Runtime-kontrollierte Nichtbenutzung von Geräten, ...).
Auf die Init-Funktionen wird im Library-Kapitel jeweils hingewiesen.
In diesem Kapitel soll ein erstes Programm kompiliert, gelinkt, located und per Download-Programm an den Zielrechner übertragen werden. Dieses erste Programm kommt ohne die v25x.lib aus und benötigt lediglich den Startcode (s.o.).
In nachfolgendem Programm wird der Hauptausgabeport P0 mit dem Muster $AA (hex) belegt und im Sekundentakt invertiert (kann bei Anschluß von LED´s sichtbar gemacht werden), gleichzeitig blinkt die LED1.
Erstes Programm (Projektdatei nicht erforderlich):
/*
module \MT25\c\examples\T25guid1.c */
#include
<SYSV25.H>
/* Header-Datei für T25-Programme */
main()
{
RL_initTCPorts();
/* I/O-Ports für MT25-Rechner initialisieren.*/
RL_FullSpeed();
/* 0 Waitstates und volle Prozessorgeschwindigkeit */
PM0 = 0;
/* Port0 (8-freie I/O-Ausgänge) auf Ausgang schalten */
P0 = 0xAA;
/* Bit-Muster AN-AUS-AN-AUS-AN-AUS-AN-AUS an Port 0 */
while (TRUE)
/* Endlosschleife */
{
RL_wait(1000);
/* 1000ms = 1 Sekunde warten */
P0 = ~P0;
/* Port P0 invertieren */
BNOT(2,P2);
/* LED1 invertieren */
}
}
Vorgehensweise beim Programmtest auf dem MT25
Rechner:
Programm in der IDE mit Compile/Compile (F9) übersetzen
und linken; es entsteht die EXE-Datei T25GUID1.EXE
EXELOC-Lauf (s.o.)
Downlaod mit Programm DLX (s.o)
Anmerkungen:
Ein Programm für den MT25 darf niemals abgebrochen werden, da eine Rückkehr zu einem Betriebssystem wie DOS nicht möglich ist
Die beiden ersten Befehle (RL_initTCPorts und RL_fullSpeed) sollten immer ein MT25-Programm einleiten
4.3.5. Die MT25-Systemlibrary für Turbo/Borland C/C++
Die MT25-Systemlibrary für C liegt als Set von Modulen vor, welche (je Speichermodell) in einer Librarydatei mit Namen v25x.lib (x=s,c,m oder l) archiviert sind.
Erst durch die Benutzung dieser Library geht die Programmierung des MT25 mit allen seinen Hardwarekomponenten zügig und bequem vonstatten. Im folgendem werden die einzelnen Module mit allen Funktionen beschrieben.
Hinweis: bei der Beschreibung der nachfolgenden Library-Funktionen werden unter dem Kennzeichen MT auch Informationen zur Multithreading-Fähigkeit gegeben. (siehe Kapitel über TurboTASK Multitasking-System) Wird TurboTASK nicht benutzt, können diese Hinweise überlesen werden.
4.3.5.1. Modul RL
Das Modul RL (Root-Library) ist eigentlich kein richtiges Modul, sondern wird vom Startcode zur Verfügung gestellt. RL stellt grundlegende Dienste für den V25/MT25 zur Verfügung.
Funktionen:
void RL_initTCPorts(void);
setzt I/O-Ports für MT25 auf die korrekte Richtung (Ein- oder
Ausgang) und initialisiert die Ports
void RL_FullSpeed(void);
Prozessor ohne Wait-States laufen lassen. Sollte praktisch immer als
erstes gerufen werden (außer bei Uralt-Eproms)
long RL_SysClock(void);
liefert Zeit in Millisekunden seit Programmstart; beginnt
nach 0xFFFFFFFFL wieder bei 0;
void RL_wait(long
wtime);
wartet wtime Millisekunden; bei Verwendung von TurboTASK wird
Rechenzeit für andere Tasks benutzt
void MT_yield(void);
(MT)
gibt unter TurboTASK den Rest der aktuellen Zeitscheibe des
aufrufenden Tasks für das System frei. Diese Funktion sollte ständig
gerufen werden, wenn die Task zur Zeit nichts zu tun hat (z.B. auf
Eingaben oder bestimmte Zustände wartet), um die Rechenzeit anderen
Tasks zukommen zu lassen; läuft TurboTASK nicht, so ist MT_yield
wirkungslos (lediglich return-Befehl). Es ist aber sinnvoll, diese
Funktion auch ohne TurboTASK schon zu verwenden, um bei einem späteren
Umstieg auf TurboTASK-Multitasking bereits eine Task in den Händen zu
haben, der sparsam mit der Prozessorzeit umgeht.
Diese Prozedur gehört eigentlich zum Befehlssatz der
TurboTASK-Routinen, wird aber aus dem eben geschilderten Grund bereits
ohne TurboTASK angeboten.
void abort(void);
intern: Standard-Abort-Funktion
läßt bei irregulärem Programmabbruch die LED1 blinken. Auch Division
durch 0 (Interrupt 0) ist defaultmäßig auf abort gesetzt.
Eine eigene Exit-Procedur kann wie gewöhnlich über die atexit-Methode
gesetzt werden.
void RL_clearWatchDog(void);
Makros:
BSET(nr, memlocation)
BCLR(nr, memlocation)
BNOT(nr, memlocation)
Bitmanipulationsbefehle zum Setzen, Löschen, Invertieren des
Bits nr in der Variable memlocation;
(Vorteil gegenüber AND / OR / XOR: Manipulation erfolgt mit einem
Maschinenbefehl, sodaß die Bits in derselben Variable auch von
Interrupt-Routinen und anderen Tasks benutzt werden können.)
FINT
FINT-Befehl des V25: Quittiert Interruptkontroller nach
Beendigung eines Interrupt;
muß am Ende jeder selbstdefinierten Interruptfunktion gerufen werden,
welche einen V25-internern Interrupt (z.B. INTP0) handled (siehe
T25GUID4.C)
CLI
STI
Äquivalente zu den Assembler-Befehlen cli und sti;
(Interrupts stoppen/freigeben)
Anmerkungen:
es ist sehr lehrreich, sich die Datei sysv25.h direkt anzusehen
im Unterschied zum Turbo
Pascal Paket können die C-Routinen setvect und getvect zum Setzen und Lesen von Interrupt-Vektoren aus
der Standard‑C‑Bibliothek benutzt werden, so daß keine Spezialroutinen
benutzt werden müssen
4.3.5.2. Modul LCD
Das Modul LCD stellt praktisch alle Funktionen zur Verfügung um das Standard LCD-Display des MT25 mit dem LCD-Controller HD44780 anzusteuern. Auch andere LCD-Displays mit diesem Controller können mit dem Modul LCD angesteuert werden.
Die Benutzung einiger wichtiger Funktionen des LCD-Moduls zeigt das Demoprogramm T25GUID2.C .
MT:
alle
Funktionen sind multithreadingfähig. d.h. Funktionen stören sich bei
gleichzeitiger Ausführung nicht gegenseitig beim Zugriff auf Hardware
(Serialisierung der Hardware-Zugriffe). Vorsicht ist aber geboten, wenn
z.B. mehrere Threads den HardwareCursor benutzen. (z.B. LCD_gotoXY mit
darauffolgenden LCD_write-Aufrufe) Chaos auf dem LCD ist dann
vorprogrammiert.
Dieses Probleme umschiffen einige Funktionen mit erweiterter
MT-Fähigkeit (z.B. LCD_writeXY ), die dafür sorgen, daß verschiedene
Bereiche des LCD-Displays von verschiedenen Threads benutzt werden
können. Besonders die Prozedur LCD_writeXY sollte der Prozedur
LCD_write immer vorgezogen werden.
Funktionen:
void LCD_init(void);
initialisiert das LCD-Display und das LCD-Modul;
muß gerufen werden, bevor LCD-Funktionen verwendet werden können !
void LCD_clrScr(void);
löscht Bildschirm und setzt Cursor an Position 0/0;
void LCD_gotoXY(int
x,int y);
versetzt den Hardware-Cursor an die Position x/y;
die linke obere Position hat die Koordinaten 0/0 (im Gegensatz zu
gotoxy aus conio.h)
void LCD_write(const
char *s);
schreibt String an aktueller Cursorposition auf den Bildschirm
void LCD_writeXY(int
x,int y, const char *s);
MT: erweitert
MT-fähig
schreibt String s an Position x,y auf den Bildschirm;
die linke obere Position hat die Koordinaten 0/0 (im Gegensatz zu
gotoxy aus conio.h)
void LCD_putCharXY(int
x,int y, char c);
MT: erweitert
MT-fähig
schreibt einzelnes Zeichen c an Position x/y auf
Bildschirm
void LCD_clrLine(int
y);
MT: erweitert
MT-fähig
löscht die Zeile y am Bildschirm komplett;
die oberste Zeile ist die Zeile 0;
void LCD_enableBlink(void);
schaltet Blinken des Cursors ein
void LCD_disableBlink(void);
schaltet Blinken des Cursors aus
void LCD_showCur(void);
macht Cursor sichtbar;
void LCD_hideCur(void);
macht Cursor unsichtbar;
int
LCD_getCurX(void);
liefert X-Position des Cursors; Umkehrung zu LCD_gotoXY
int
LCD_getCurY(void);
liefert Y-Position des Cursors; Umkehrung zu LCD_gotoXY
void LCD_setUserChar(char
charno, char *bitmap8x8);
erstellt selbstdefiniertes Zeichen;
<charno> ist die Nummer des selbstdefinierten Zeichen und hat den
Wertebereich 0..15;
dabei sind jedoch die Zeichen 0..7 identisch mit den Zeichen 8..15;
Es stehen also insgesamt 8 verschiedene selbstdefinierbare Zeichen zur
Verfügung.
Die Sonderzeichen können als normale Charakter bei Aufrufen wie
LCD_writeXY in Strings oder Charakters übergeben werden. Sie belegen
den ASCII-Bereich 0..15;
in C ist es empfehlenswert statt dem Wertebereich 0..7 den Bereich
8..15 zu benutzen, um beim Zeichen 0(=8) nicht Schwierigkeiten mit der
0-Terminierung von Strings zu bekommen;
<bitmap> ist ein Zeiger auf eine 8 Byte lange
Struktur, welche die Bitmap-Information für
das Zeichen beinhaltet. Ein Zeichen hat das Format 5x7(8) Punkte. Die
8. Zeile kann benutzt werden, allerdings wird sie bei Benutzung des
Hardware-Cursors von diesem überlappt.
Die Bitmapstruktur hat folgenden Aufbau (Binärzahlen) :
mit
dieser Funktion können unter C auch im Datenblock enthaltene
0-Bytes problemlos übertragen
werden
void SERx_setBaudRateX(int
rate, unsigned brxflags)
(set baudrate extended)
setzt BaudRate und Bit-Einstellungen der seriellen
Schnittstelle
rate
: spezifiziert Baudrate; die Konstanten BR_1200 bis
BR_115200 sind vordefiniert;
brxflags
: Bitfeld, über welches die verschiedenen
Bit-Einstellungen gesetzt werden;
folgende Bit-Masken-Konstanten sind
(vor-)definiert:
BRXF_2StopBit
: 2 Stoppbits
BRXF_7Bit
: 7 Bit - Zeichenlänge
BRXF_ParOdd
: ungerade Parität (falls Parity-Betrieb)
BRXF_Parity
: Parity-Betrieb einschalten
sollen mehrere Flags gesetzt werden, müssen
die Flags ODER-verknüpft
werden.
Anmerkung: Flag, das nicht gesetzt ist ® der jeweilige Wert aus den
Defaulteinstellungen wird genommen.
Aufrufbeispiel:
SER0_setBaudRateX(BR_19200,
BRXF_7Bit OR BRXF_Parity)
in diesem Beispiel wird 19200Baud/7Bit/even Parity/1Stoppbit gewählt
Die Default-Einstellungen nach Unit-Initialisierung sind:
9600Baud, no parity,
(even) , 8Bit, 1 Stoppbit
void SERx_setBaudRate(int
rate);
setzt BaudRate der seriellen Schnittstelle, die
Bit-Einstellungen bleiben unberührt
<rate> : spezifiziert Baudrate; siehe SERx_setBaudRateX
void SERx_sendChar(char
c);
sendet ein Zeichen ungepuffert
void SERx_sendBlk(const
char *p, unsigned len);
sendet Block ungepuffert
Argumente siehe SERx_putBlk;
int
SERx_TransmitterBusy:boolean;
liefert Wert ungleich 0, falls der gepufferte Sendebetrieb
noch läuft, 0, falls sich keine Zeichen mehr im Sendepuffer befinden;
hiermit kann festgestellt werden, wann alle Zeichen vom Rechner
übertragen worden sind
Anmerkung: Für den PC ist dieselbe Library mit identischen Funktionen lieferbar.
Das Modul SER0 enthält zusätzlich folgende Funktion zur RS485-Steuerung:
void RS485_setDir(int
direction);
setzt die Übertragungsrichtung des RS485-Wandlerbausteins;
direction = 0 für Empfang;
direction = 1 für Senden;
(direction = 2 für Senden + Mithören
(für Netzwerkbetrieb; z.Zt. noch nicht implementiert) )
die Default-Einstellung ist Empfang (direction=0)
4.3.5.4. Modul SEP
Das Modul SEP wird benötigt, um das serielle 128-Byte große E2PROM auf dem MT25-Board anzusteuern. Das E2PROM ist zu 64 Worten von jeweils 16 Bit organisiert. Folgende Routinen werden zu Verfügung gestellt:
Funktionen:
void
SEP_EWEN(void);
(erase/write-enable)
erst nach Aufruf dieser Funktion kann schreibend oder löschend auf das E2PROM zugegriffen werden
void
SEP_EWDS(void);
(erase/write-disable)
nach Aufruf dieser Funktion ist das E2PROM wieder
hardwaremäßig gegen Schreibe/Lösch‑Zugriffe gesperrt
unsigned SEP_read(unsigned adress);
das 16-Bit-Wort an der Adress <adress> wird ausgelesen
und zurückgeliefert.
<adress> hat den Wertebereich 0..63 ($00..$3F), es existieren
also 64 Word-Speicherstellen
void
SEP_write(unsigned adress, unsigned value);
der 16-Bit-Wert value wird an Adresse <adress> ins E2PROM geschrieben.
Ein vorheriges Löschen der Speicherstelle ist nicht nötig, da das E2PROM wort-weises auto‑erase‑write unterstützt. Ein
Schreibzugriff dauert ca. 2msek. (Microchip) bis
4msek. (EXCEL u.a). Diese Zeit macht sich nur bei wiederholtem
Schreiben bemerkbar.
Bei einem einzelnen Schreibzugriff kehrt SEP_write sofort zurück, da
die letzte Schreiboperation immer im Hintergrund (automatisch im E2PROM ) abläuft. Bei direkt aufeinander folgenden
Schreibzugriffen legt SEP_write dann evtl. erforderliche Wartezeiten
ein.
void
SEP_erase(unsigned adress);
die Speicherstelle <adress> wird gelöscht (mit $FFFF
belegt);
ein Löschzyklus dauert ca. 1msek.(Microchip) - 2msek. (andere);
das dynamische Zugriffsverhalten ist wie bei SEP_write
void
SEP_eraseAll(void);
löscht komplett alle 64 Speicherstellen des E2PROM:
Dauer des Löschvorgangs: ca. 15msek.. Die Funktion kehrt sofort zurück.
Wartezeit fällt evtl. beim nächsten E2PROM-Zugriff
an (siehe SEP_write), falls er innerhalb der 15msek.
ausgeführt wird.
4.3.5.5. Modul ANA
Das Modul ANA ermöglicht den einfachen Zugriff auf die DA- und AD-Wandler des MT25. Dieses Modul liegt vollständig im Quellcode vor, sodaß der Ansteuerungs-Mechanismus leicht nachvollzogen werden kann. Für extrem zeitkritische Anwendungsfälle (NF-Sampling u.a.), wofür die Hardwarebausteine ausgelegt sind, kann der Programmierer aus dieser Unit somit die nötigen Informationen gewinnen, um z.B. ein High-Speed-Assemblermodul zu entwickeln.
Funktionen:
unsigned ANA_readAD(unsigned nr);
liest einen 12-Bit-Wert vom AD-Wandler nr;
<nr> hat den Werte-Bereich 0..7 für die 8 AD-Wandler-MUX-Eingänge;
Achtung: ANA_readAD
liefert den Wert der AD-Wandlung, die durch den
letzten
ANA_readAD-Zugriff gestartet wurde.
4.3.5.6. Modul RTC
Das Modul RTC stellt alle Funktionen zur Verfügung, die zum Zugriff auf die Echtzeituhr erforderlich sind.
Funktionen:
void
RTC_gettime(struct time *t);
schreibt die aktuelle Zeit der Echtzeituhr in eine
time-Struktur <*t>
void
RTC_settime(struct time *t);
setzt die Zeit der Echtzeituhr auf die Zeit in der time Struktur <*t>
int
RTC_getdate(struct date *d);
schreibt das aktuelle Datum der
Echtzeituhr in eine date-Struktur <*d>
void
RTC_setdate(struct date *d);
setzt das Datum der Echtzeituhr auf das Datu in der time
Struktur <*d>
Anmerkungen:
das Demoprogramm T25GUID8, welches auch geeignet ist, viele Komponenten des MT25-Rechners zu testen, demonstriert die Verwendung einer representativen Auswahl der oben beschriebenen Libraryfunktionen
das Demoprogramm T25GUID4 demonstriert die Erstellung einer V25-Interruptprozedur für Turbo Pascal. Hierbei wird der V25-TIMER0-Interrupt benutzt, um die LED- Beleuchtung blinken zu lassen. Man beachte besonders die Verwendung des Befehles FINT, welcher dem V25-Interrupt-Controller mitteilt, daß der Interrupt "gehandled" wurde.
4.3.6. Ausblick auf Multitaskingprogrammierung
Für Noch-Nicht-Benutzer des V25-Multitaskingsystems TurboTASK soll hier kurz auf ein kleines Demonstrationsprogramm MT_DEMO.C hingewiesen werden, welches die Einsatzmöglichkeiten von TurboTASK zeigen soll.
Der Pfad des Demo-Programmes ist \MT25\PAS\EXAMPLES\MT_DEMO.C.
In diesem Programm laufen ohne besondere Interrupt-Programmierung o.ä. eine mathematische Berechnung, eine Tastaturabfrage und die Anzeige einer Systemzeit gleichzeitig ab.
4.4. Programmentwicklung mit TurboAssembler
Wenn Assembler Programme auf einem V25-EPROM laufen sollen, müssen die Segmente so angeordnet und benannt werden, das EXELOC erkennt, wo CodeSegmente aufhören (ROM) und Datensegmente anfangen (RAM). Alle Code-Segmente im EXE-File müssen vor allen Datensegmenten liegen (z.B. durch DOSSEG erreichbar). Am besten werden C-kompatible Segmente benutzt (_TEXT,_DATA, _BSS ...). Am einfachsten arbeitet man mit den vereinfachten Segmentbefehlen des TurboAssemblers im "MODEL SMALL"´.
Einfache ASM-Schablone [File \MT25\ASM\MT25ASM.ASM ]:
DOSSEG
; richtige Segmentanordnung für EXELOC
INCLUDE V25.INC
;
mitgelieferte ASM-V25-Definitionen
.MODEL
SMALL
.STACK 128 ; 128 Byte Stack
.DATA
xy db 1,2,3 ;
Datendefinieren
;...
define your
own data
.CODE
startx PROC
mov ax,@data
mov ds,ax ;
Datensegment setzen
ASSUME DS:@data
mov ax,HWSEGADR
mov es,ax
ASSUME ES:HWSEG ; ES zeigt auf
V25-SFR-Segment
;...write
your
own code
mov [_PM0],0 ; PortMode0 auf
Ausgang
mov [_P0],77h ;
Muster auf Port0 ausgeben
jmp $+0
; Endlos-Warteschleife
ENDP
END startx ;
Programm-Startpunkt setzen
Vorgehensweise
beim Übersetzen eines Programms:
mit "tasm -i\MT25\asm t25asm" übersetzen
mit "tlink t25asm" linken
mit "EXELOC firstasm" downloadfähig machen (bzw. mit Option /ROM EPROM-fähig)
Für MT25 & MT400 ist weitere Dokumentation im gedruckten Manual enthalten.