Sunteți pe pagina 1din 8

Appendix

D
VxWorks 5.2 Serial Driver Lab

Wind River Systems

D-1

TOPICS:

The lab is a read through of a serial driver.

Example Serial Driver


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 /* tyCoDrv.c - Heurikon HK68/V20,V2F,V2FA USART tty handler */ /* Copyright 1984-1990 Wind River Systems, Inc. */ extern char copyright_wind_river[]; static char *copyright=copyright_wind_river; #include #include #include #include #include #include #include vxWorks.h iv.h ioLib.h iosLib.h memLib.h tyLib.h config.h

typedef struct/* TY_CO_DEV */ { TY_DEV tyDev; BOOL created;/* true if this device has really been created */ char *ucr;/* USART control register */ char *rsr;/* receiver status register */ char *tsr;/* transmit status register */ char *udr;/* USART data register */ } TY_CO_DEV; LOCAL TY_CO_DEV tyCoDv =/* device descriptors */ { {{{NULL}}}, FALSE, MFP_UCR (MFP_BASE_ADR), MFP_RSR (MFP_BASE_ADR), MFP_TSR (MFP_BASE_ADR), MFP_UDR (MFP_BASE_ADR) }; LOCAL int tyCoDrvNum;/* driver number assigned to this driver */ typedef struct/* BAUD */ { int rate;/* a baud rate */ char timeConstant;/* time constant to write to the timers C and D data registers (TCDR & TDDR) to get that baud rate */ } BAUD;

Wind River Systems

D-2

34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

LOCAL BAUD baudTable [] = { {150,0x128}, {300,0x64}, {600,0x32}, {1200,0x16}, {2400,0x08}, {4800,0x04}, {9600,0x02}, {19200,0x01} }; /* forward declarations */ LOCAL VOID tyCoStartup (); LOCAL int tyCoOpen (); LOCAL STATUS tyCoIoctl (); LOCAL VOID tyCoTxInt (); LOCAL VOID tyCoRxInt (); LOCAL VOID tyCoHrdInit (); /**************************************************************** * * tyCoDrv - ty driver initialization routine * * This routine initializes the serial driver, sets up interrupt vectors, * and performs hardware initialization of the serial ports. * * RETURNS: OK or ERROR if unable to install driver. */ STATUS tyCoDrv () { /* check if driver already installed */ if (tyCoDrvNum > 0) return (OK); /* MFP interrupts on level 4 and vectors to the appropriate routines */ (void) intConnect (INUM_TO_IVEC(MFP_INT_VECT_NUM + MFP_INT_TRANS), tyCoTxInt, NULL); (void) intConnect (INUM_TO_IVEC(MFP_INT_VECT_NUM + MFP_INT_RECV), tyCoRxInt, NULL); tyCoHrdInit (); tyCoDrvNum = iosDrvInstall (tyCoOpen, (FUNCPTR) NULL, tyCoOpen, (FUNCPTR) NULL, tyRead, tyWrite, tyCoIoctl);

Wind River Systems

D-3

74 75 76 77 78 79 80 81 82 83 84 85 86

return (tyCoDrvNum == ERROR ? ERROR : OK); } /***************************************************************** * * tyCoDevCreate - create a device for the onboard ports * * This routine creates a device on one of the serial ports. Each port * to be used should have exactly one device associated with it, by calling * this routine. * * RETURNS: OK or ERROR if invalid channel or driver not installed. */

87 STATUS tyCoDevCreate ( 88 char *name,/* Name to use for this device */ 89 int channel,/* Physical channel for this device (0 only!) */ 90 int rdBufSize,/* Read buffer size, in bytes */ 91 int wrtBufSize)/* Write buffer size, in bytes */ 92 93 { 94 if (tyCoDrvNum <= 0) 95 { 96 errnoSet (S_ioLib_NO_DRIVER); 97 return (ERROR); 98 } 99 100 /* if this device already exists or invalid channel, dont create it */ 101 102 if (tyCoDv.created || channel != 0) 103 return (ERROR); 104 105 /* initialize the ty descriptor */ 106 107 if (tyDevInit (&tyCoDv.tyDev, rdBufSize, wrtBufSize, tyCoStartup) != OK) 108 return (ERROR); 109 110 /* enable receiver and receiver error interrupts */ 111 112 *MFP_IMRA (MFP_BASE_ADR) |= MFP_A_RX_FULL; 113 *MFP_IMRA(MFP_BASE_ADR) |= MFP_A_RX_ERR; 114

Wind River Systems

D-4

115 116 117 118 119 120 121 122 123 124

/* mark the device as created, and add the device to the I/O system */ tyCoDv.created = TRUE; return (iosDevAdd (&tyCoDv.tyDev.devHdr, name, tyCoDrvNum)); } /************************************************************** * * tyCoHrdInit - initialize the USART */

125 LOCAL VOID tyCoHrdInit () 126 127 { 128 int oldlevel;/* current interrupt level mask */ 129 130 oldlevel = intLock (); 131 132 /* 8 data bits, 1 stop bit, no parity */ 133 134 *MFP_UCR (MFP_BASE_ADR) = MFP_UCR_16X | MFP_UCR_8BIT | 135 MFP_UCR_1STOP | MFP_UCR_NO_PARITY; 136 137 /* set timer C,D for delay mode, /4 prescale */ 138 139 *MFP_TCDCR (MFP_BASE_ADR) = MFP_TCDCR_C_DELAY_4 | MFP_TCDCR_D_DELAY_4; 140 141 *MFP_TCDR (MFP_BASE_ADR) = 0x02;/* set timer C for 9600 baud */ 142 *MFP_TDDR (MFP_BASE_ADR) = 0x02;/* set timer D for 9600 baud */ 143 144 /* enable the receivers and transmitters on both channels */ 145 146 *MFP_RSR (MFP_BASE_ADR) = MFP_RSR_RX_ENABLE;/* enable rcvr status */ 147 *MFP_TSR (MFP_BASE_ADR) = MFP_TSR_TX_ENABLE;/* enable xmit status */ 148 149 *MFP_IERA (MFP_BASE_ADR) |= MFP_A_RX_FULL;/* enable recv int. */ 150 *MFP_IERA (MFP_BASE_ADR) |= MFP_A_RX_ERR;/* enable recv error int. */ 151 *MFP_IERA (MFP_BASE_ADR) |= MFP_A_TX_EMPTY;/* enable transmit int. */ 152 153 /* all interrupts are still masked out via the interrupt mask registers: 154 * turn the receiver on and off by twiddling the interrupt mask reg (IMRA), 155 * the receiver interrupt will be enabled in tyCoDevCreate,

Wind River Systems

D-5

156 157 158 159 160 161 162 163 164 165 166

* the transmitter interrupt will be enabled in tyCoStartup */ intUnlock (oldlevel); } /************************************************************** * * tyCoOpen - open file to USART * * ARGSUSED1 */

167 LOCAL int tyCoOpen (pTyCoDv, name, mode) 168 TY_CO_DEV *pTyCoDv; 169 char *name; 170 int mode; 171 172 { 173 return ((int) pTyCoDv); 174 } 175 176 177 178 179 180 181 182 183 184 /************************************************************** * * tyCoIoctl - special device control * * This routine handles baud rate requests, and passes all others * to tyIoctl(2). * * RETURNS: OK or ERROR if invalid baud rate, or whatever * tyIoctl(2) returns. */

185 LOCAL STATUS tyCoIoctl ( 186 TY_CO_DEV *pTyCoDv,/* device to control */ 187 int request,/* request code */ 188 int arg)/* some argument */ 189 190 { 191 int ix; 192 FAST STATUS status; 193 194 switch (request)

Wind River Systems

D-6

195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230

{ case FIOBAUDRATE: /* set timers C,D for delay mode, /4 prescale */ *MFP_TCDCR (MFP_BASE_ADR) = MFP_TCDCR_C_DELAY_4 | MFP_TCDCR_D_DELAY_4; status = ERROR; for (ix = 0; ix < NELEMENTS (baudTable); ix++) { if (baudTable [ix].rate == arg) { *MFP_TCDR (MFP_BASE_ADR) = baudTable [ix].timeConstant; *MFP_TDDR (MFP_BASE_ADR) = baudTable [ix].timeConstant; status = OK; break; } } break; default: status = tyIoctl (&pTyCoDv->tyDev, request, arg); break; } return (status); } /************************************************************** * * tyCoTxInt - handle a transmitter interrupt * * This routine gets called to handle transmitter interrupts. * If there is another character to be transmitted, it sends it. If * not, or if a device has never been created for this channel, we just * disable the interrupt. */

231 LOCAL VOID tyCoTxInt () 232 233 { 234 char outChar; 235

Wind River Systems

D-7

236 237 238 239 240 241 242 243 244 245 246 247 248

if (tyCoDv.created && (tyITx (&tyCoDv.tyDev, &outChar) == OK)) *tyCoDv.udr = outChar; else { *MFP_IMRA (MFP_BASE_ADR) &= ~MFP_A_TX_EMPTY; /* turn off transmitter */ } } /************************************************************* * * tyCoRxInt - handle a receiver interrupt * * This routine gets called to handle receiver interrupts. */

249 LOCAL VOID tyCoRxInt () 250 251 { 252 (void)tyIRd (&tyCoDv.tyDev, *tyCoDv.udr); 253 } 254 255 256 257 258 259 /************************************************************* * * tyCoStartup - transmitter startup routine * * Call interrupt level character output routine for USART. */

260 LOCAL VOID tyCoStartup ( 261 FAST TY_CO_DEV *pTyCoDv)/* ty device to start up */ 262 263 { 264 char outchar; 265 266 if (tyITx (&pTyCoDv->tyDev, &outchar) == OK) 267 *pTyCoDv->udr = outchar;/* write the next char out */ 268 269 *MFP_IMRA (MFP_BASE_ADR) |= MFP_A_TX_EMPTY;/* turn transmitter on */ 270 }

Wind River Systems

D-8

S-ar putea să vă placă și