Search   
Home  Print View  

 

Software

Branch Content

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

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