Universität Bielefeld - Technische Fakultät - Neuroinformatik



next up previous contents
Next: Einbindung in den Up: Die Software-Einbindung des Previous: Die Software-Einbindung des

C-Schnittstelle

Ein Treiber ermöglicht den Zugriff auf den VME-Bus über den in Druide eingebauten S-Bus-Konverter. Der Adressraum der M-Modul-Trägerkarte muß mit mmap angemeldet werden. Aus dem folgenden Code-Segment geht die Speicherbelegung der Trägerkarte hervor:

/* Device name of the VMEbus rack and offset of the A201N */
/* carrier board. */
#define VMEDEVNAME "/dev/ptvme24d16"
#define A201N_OFFS (off_t) 0xff0000

struct MModule {             /* Mapping of a single M-Module */
  ushort data[0x80] ;        /* on the A201N carrier board.  */
  ushort icontrol;
  ushort ivector;
  ushort pad[0x7e];
};

struct MMCarrier {           /* Mapping of all four M-Modules */
  struct MModule mod[4];     /* on the A201N carrier board.   */
};


iVMEDeviceHandle = open(VMEDEVNAME, O_RDWR)

psCarrierAddress = (struct MMCarrier *)
         mmap(0, (size_t) 0x800, PROT_WRITE|PROT_READ,
              MAP_SHARED, iVMEDeviceHandle, A201N_OFFS)
Die letzten beiden Aufrufe liefern als Rückgabewert -1, falls ein Fehler aufgetreten ist. Die Strukturdefinitionen beschreiben die Speicherbelegung der Trägerkarte. A201N_OFFS ist die Startadresse der Trägerkarte innerhalb des VME-Bus-Adressraums; sie kann mit DIP-Schaltern auf der Karte eingestellt werden.

Bei Beenden der Applikation muß der VME-Bus-Zugriff noch abgemeldet werden. Dazu reicht close(iVMEDeviceHandle) aus. Die Funktionen BradStartup() und BradShutup() übernehmen diese Initialisierungs- und Finalisierungsaufgaben. BradStartup() löscht außerdem sicherheitshalber das Interrupt-Register für das Puffermodul (eine Zusammenstellung der implementierten Funktionen befindet sich in Anhang C).

Durch Zuweisungen mit psCarrierAddress->mod[Module ].data[Address ] als Quelle oder Ziel geschieht der Zugriff auf den Pufferspeicher, wobei Module die Schachtnummer des gewünschten Moduls ist (0 bis 3) und Address die Speicheradresse innerhalb des Moduls (0 bis 127). Da die Module einen 16-Bit-Datenbus haben, sind die Elemente der Struktur MModul vom Typ ushort.

Schreibzugriffe auf BRAD setzen nur das Page-Register, daher kann eine intelligente Routine zum Auslesen einer Speicherstelle des Moduls wie folgt aussehen:

/* The BRAD M-Module lives on slot #2 on the A201N carrier */
/* board. */
#define BRAD_SLOT 2

ushort BradRead(int iRAMaddr)
{
  /* The initialization of lastpage with an invalid page */
  /* number makes sure BRAD's upper address latch is written */
  /* during the first read operation. */
  static u_int iCurrentPage = 64;
  u_int iPage, iAddr;

  iPage = (iRAMaddr >> 7 ) & 0x3f;
  iAddr =  iRAMaddr        & 0x7f;

  /* Only update BRAD's upper address latch if the page */
  /* changes. */
  if (iPage != iCurrentPage) {
    sBradHandle.psAddress->mod[BRAD_SLOT].data[iPage] = 0;
    iCurrentPage = iPage;
  }
  return (sBradHandle.psAddress->mod[BRAD_SLOT].data[iAddr]
           & 0xff);
}
Die Routine übernimmt das Decodieren der Gesamtadresse ( 0x0000..0x1fff) in die Seite (Bits [7:12]) und die Adresse innerhalb der Seite (Bits [0:6]).

Eine statische Variable, iCurrentPage, spiegelt das Page-Register des Moduls wider; beim ersten Aufruf der Prozedur wird dieses Register korrekt initialisiert. Bei jedem folgenden Aufruf wird nur dann eine Schreiboperation ausgeführt, wenn sich das Page-Register ändern soll.

Da nur die untere Hälfte des Datenbusses belegt ist, wird der Rückgabewert mit 0xff maskiert.



Markus Jankowski Jan Jockusch Lars Jansen Michael Jandrey Marjan Tomas , 1996-Dec-06