Search   
Home  Print View  

 

Software

Branch Content

LCCP Components

Devices Drivers

Device drivers take care of device-specific functionality isolating the rest of Software from these details by presenting a common interface to them. This interface is the Device Manager service (DEVMAN).

Architecture

A device driver consists of three separate routines:

  * Initialization Routine (INIT)
  * Device Service Routine (DSR)
  * Interrupt Service Routine (ISR)

The INIT routine initializes device hardware (for example, programmable chips) and data structures associated with the device driver.

The DSR routine is called to initiate operations on the controlled device. In most cases, the DSR sends commands to the device, returning immediately after that. The device's response could take some time and it is captured through interrupts.

The ISR routine services the interrupts coming from the device in question. Possibly the first thing to do is to query some device's control register to learn what caused the interrupt.

The ISR also performs part of the useful job. For instance, when reading from a Tape Drive, it receives the incoming bytes into a given buffer.

In source, device drivers are written in separate files with extension ".DEV".

Existing Device Drivers

VTCOM.DEV

VTCOM.DEV is the device driver for the VTCOM Tape Drive Simulation Software running at MS-DOS PC connected via Serial Port (RS-232) to LC-81. This program simulates a Tape Drive according to the "LC-81 Tape Drives Specification". (See the specification in section "Specs").

The LC-81 serial port is based on UART chip 16C550. The INIT routine initializes the chip to use FIFO and to interrupt for each byte received.

Since there is no EXT-BUS in this case, Drive's registers C and F can not be accessed directly. Access to those registers is orchestrated by the mean of 3-bytes "Escape Sequences". This method, however, presents a limitation for interrupts associated to the WRITE operation: it is not practical to write one byte at the time (as specified for Tape Drives) so the ISR routine writes a whole block continuously in a loop before returning.

We will cover VTCOM Operations and Escape Sequences in details later in section "VTCOM Tape Drive Simulation Software".

Service Manager (SERMAN)

Services

ERR

ERR_CLR

ERR_GET

ERR_SET

ERR_PANIC

INIT

DEVMAN

The Device Manager Service (DEVMAN) is the only way for applications to get access to peripherals, or, put in another way, it is the common interface between applications and device drivers. DEVMAN relies on the Device Table (DEVTAB).

Access to peripherals through DEVMAN also relies on a "request structure" (REQ) that applications need to construct as part of the requesting procedure.

The DEVMAN service has five functions:

  _INIT     Initialize device driver
  _PUTREQ   Attach REQ struct to DEVTAB
  _CLRREQ   Detach REQ struct from DEVTAB
  _EXEC     Execute device operation
  _SETDEV   Populate DEVTAB entry

The _INIT function calls the INIT device driver routine.

The _EXEC function calls the DSR device driver routine. Specifications for the operation being requested is in the REQ struct. The application must built the REQ struct and attach that to the device's entry in DEVTAB prior to call _EXEC.

The need for re-entrancy

A given device driver can be shared among alike devices. Moreover this is a common case. And shared device drivers arises the need for re-entrancy as we will show in this section.

Let put the case of a program transfering a file between drive A and drive B, both using the same device drivers.

Drive A serves data one byte at the time asserting an interrupt when a byte is ready for reading. The interrupt service routine (which is part of the device driver) must accomodate incomming bytes into a given buffer.

Similarly, drive B accept data one byte at the time asserting an interrupt when it is ready to receive one. The interrupt service routine must pull a byte for the buffer and update pointers as necessary.

We could make the buffer the size of a block, read a block entirely from A, then copy it to B, but this would be inneficient: the time between interrupts in this case is so long that the microprocessor could easily execute 400 intructions in that period. A much eficient solution is to interleave the two operations (read and writting) taking advantage of the waits between interrupts.

This implies that the device driver will be alternating roles. Now is reading, then is writing; now is working with device A, then is working with device B, and so on. Synchromizing these activities could prove complex, specially if we want to extend this behavior to an arbirtrary number of operations: say for instance that we also want to copy the file to a third drive C.

A better solution is to isolate the "context" in which the device driver must operate in each case. That "context" is provided by the REQ struct. We create a struct for each device being operated and attach a pointer to it in the DEVTAB entry for that device. REQ contains, not only the request parameters but also the variables that the device drivers will utilize internaly.

This way we re-enter the device driver code with a different "context" each time, so it never gets confussed. Yet the code is simpler because it doesn't have to take care of synchronization.


The Request Struct (REQ)

DEVMAN_INIT

DEVMAN_PUTREQ

DEVMAN_CLRREQ

DEVMAN_EXEC

DEVMAN_SETDEV

MEMMAN

LIBMAN

Utilities

HEXTOBIN

GETENTRY

Start

LC-81 Homebrew Minicomputer -- this software is based on Help Books running at melissa