![]() |
|
||||
Writing Device Drivers for LynxOS |
Sample Device Driver
Header Files
ptrinfo.h
prtioclt.h
Driver Code
/* ptrdrvr.c - using threads */
#include <kernel.h>
#include <mem.h>
#include <sys/file.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <conf.h>
#include <st.h>
#include "ptrinfo.h"
#include "ptrioctl.h"
/* ports */
#define PP_DATA 0 /* data port offset */
#define PP_STATUS 1 /* status port offset */
#define PP_CONTROL 2 /* control port offset */
/* status bits */
#define PP_BUSY 0x80 /* printer busy */
#define PP_PE 0x20 /* out of paper */
#define PP_SLCT 0x10 /* printer is selected */
#define PP_ERROR 0x08 /* printer detected error */
/* control bits */
#define PP_IENABLE 0x10 /* interrupt enable */
#define PP_SLCTIN 0x08 /* select printer */
#define PP_INIT 0x04 /* start printer */
#define PP_AUTOLF 0x02 /* auto line feed */
#define PP_STROBE 0x01 /* strobe printer */
struct ptrstatics {
ptype datap; /* data port address */
ptype controlp; /* cntrl port address */
char control; /* control bits */
int irq; /* IRQ number */
int closing; /* closing device */
int close_sem; /* sempahore for close */
int expecting; /* expecting an int.? */
int nextnl; /* output a '\r' next? */
int chars; /* printed since open */
int lines; /* printed since open */
int qlen; /* characters in queue */
struct qentry *q; /* the queue itself */
int head; /* head of queue */
int tail; /* tail of queue */
int qdata; /* data in the queue */
int free_sem; /* free queue space */
int stid; /* thread id */
int int_sem; /* interrupt semaphore */
int qsem; /* queue protection */
struct priotrack pt; /* pri. tracking */
int curpri; /* current priority */
int prio_sem; /* pri. trking sem */
};
/*
static port_in(), port_out();
asm {
port_in: /* byte = port_in(port) *
mov EAX, 0
mov EDX, 4[ESP]
in AL, DX
ret
port_out: /* port_out(byte, port) *
mov EDX, 8[ESP]
mov EAX, 4[ESP]
out DX, AL
ret
}
*/
char *ptrinstall(info)
struct ptrinfo *info;
{
struct ptrstatics *s;
static void ptrint(), ptrthread(), ptruninstall();
int i;
/* probe for the printer */
port_out(1, info->port+PP_DATA);
if (port_in(info->port+PP_DATA) != 1)
return PERR;
s = (struct ptrstatics *)
sysbrk((long)sizeof *s);
if (!s) return PERR;
s->q = (struct qentry *)
sysbrk((long)info->qlen * sizeof(struct qentry));
if (!s->q) {
sysfree(s, (long)sizeof *s);
return PERR;
}
/* initialize statics */
s->datap = info->port + PP_DATA;
s->controlp = info->port + PP_CONTROL;
s->control = PP_SLCTIN | PP_INIT;
s->irq = info->irq;
s->expecting = 0;
s->lines = s->chars = 0;
s->closing = s->close_sem = 0;
s->nextnl = 0;
s->free_sem = s->qlen = info->qlen;
s->qdata = s->head = s->tail = 0;
s->int_sem = 0;
s->qsem = -1;
bzero(&s->pt, sizeof(struct priotrack));
s->curpri = 0;
s->prio_sem = -1;
/* initialize printer */
iointset(32+s->irq, ptrint, s);
port_out(PP_SLCTIN, s->controlp);
for (i = 0; i < 100; i++) ;
port_out(s->control, s->controlp);
s->stid = ststart(ptrthread, STACKSIZE,
s->curpri, "ptr thread", 1, s);
if (s->stid == SYSERR) {
ptruninstall(s);
return PERR;
}
return (char *) s;
}
![]() LynuxWorks, Inc. 855 Branham Lane East San Jose, CA 95138 http://www.lynuxworks.com 1.800.255.5969 |
![]() |
![]() |
![]() |
![]() |