字符设备驱动程序的完整模板
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
4.打开函数
int xxOpen(DEV_HDR *pxxDevHdr, int option, int flags) { xx_DEV * pxxDev=(xx_DEV *) pxxDevHdr; if(pxxDevHdr==NULL) { errnoSet(S_xx_NODEV); return(ERROR); } /*判断设备是否打开*/ if(pxxDev->Opened) { errnoSet(S_xx_DEVOPENED); return(ERROR); } pxxDev->Opened=TRUE; … } /*在这里作必要的初始化*/ return((int)pxxDevHdr);
6.写函数
int xxWrite(int xxDevId, char * pBuf, int nBytes) { xx_DEV * pxxDev=(xx_DEV *) pxxDevId; int WriteLength=0; BOOL FoundError; /*设备描述符是否为空*/ if(pxxDev==(xx_DEV *)NULL) { errnoSet(S_xx_NODEV); return(ERROR); } /*设备写就绪*/ if(pxxDev->ReadyToWrite) { readLength=0; pxxDev->ReadyToWrite=FALSE; … … } pxxDev->ReadyToWrite=TRUE; if(FoundError) return(ERROR); return(WriteLength);/*返回发送字符长度*/ } /*向设备发送处理*/ /*判断相关状态*/
3.设备创建函数
STATUS xxDevCreate(char *devName) { xx_DEV *pxxDev; /*检查驱动程序是否安装*/ if(xxDrvNum<1) { errno=S_ioLib_NO_DRIVER; return(ERROR); } /*分配内存并初始化*/ if((pxxDev=(xx_DEV *)malloc(sizeof(xx_DEV)))==NULL) return(ERROR);
二、串行设备驱动程序模板
1.串行通道数据结构
typedef struct { SIO_DRV_FUNCS * pDrvFuncs; STATUS STATUS void * void * UINT16 UINT16 UCHAR void … } (*getTxChar)(); (*putRcvChar)(); getTxArg; putRcvArg; int_vec; channelMode; (*inByte)(int); (*outByte)(int,char); /**/ /**/ /*中断向量*/ /*模式中断或轮询*/ /*从硬件读取一个字节函数指针*/ /*向硬件读取一个字节函数指针*/ /*驱动程序所需的函数*/ /*传送函数指针*/ /*接受函数指针*/ /*xx_CHAN*/
bzero(pxxDev, sizeof(xx_DEV)); selWakeupListInit(&pxxDev->selWakeupList); … … /*初始化必要的描述结构 pxxDev*/ /*执行设备硬件初始化,例如 I/O 地址、设备本地内存地址等*/
/*将设备添加到设备列表*/ if(iosDevAdd(&pxxDev->devHdr,devName, xxDrvNum)==ERROR { free((char *)pxxDev); return(ERROR); } return(OK); }
free(pxxDev);
9.卸载设备函数
STATUS xxDelete(char * devName) { DEV_HDR *pDevTail; char * pNameTail; /*查找设备*/ pDevHdr=iosDevFind(devName, &pNameTail); if(pDevHdr==NULL || *pNameTail !=’\0’) return(ERROR); … /*释放设备所占用的资源,例如:信号量、唤醒等待该设备的任务等*/ /*卸载设备*/ iosDevDelete(pDevHdr);
/*必要的寄存器描述及结构*/
2.串行设备驱动程序结构初始化函数
void xxDevInit(xx_CHAN *pChan/*指向设备的指针*/) { SIO_DRV_FUNCS xxSioDrvFuncs; /*驱动程序结构指针*/ if(xxSioDrvFuncs.ioctl == NULL) { xxSioDrvDFuncs.ioctl = (int (*)())xxIoctl; xxSioDrvDFuncs.txStartup = (int (*)())xxStartup; xxSioDrvDFuncs.calbackInstall = xxCallbackInstall; xxSioDrvDFuncs.pollInput = (int (*)())xxPollInput; xxSioDrvDFuncs.pollOutput = (int (*)(SIO_CHAN *, char))xxPollOutput; } pChan->pDevFuncs = &xxSioDrvFuncs;
8.设备关闭函数
int xxClose(int xxDevId) { xx_DEV * pxxDev=(xx_DEV *)xxDevId; if(pxxDev==(xx_DEV *)NULL) { errnoSet(S_xx_NOMEM); return(ERROR); } … … } /*设备相关操作*/ /*释放相关资源*/ /*释放资源*/
VxWorks 字符设备驱动程序的完整模板
一、字符设备驱动程序的模板
以下是一个完整的摸板
1.设备描述符结构
LOCAL int xxDrvNum=0; //驱动程序索引号 typedef struct { DEV_HRDdevHdr; BOOL BOOL UINT32 UINT32 ….. SEL_WAKEUP_LIST selWakeupList; //select()功能 BOOL BOOL }xx_DEV; ReadyToRead; //设备读就绪 ReadyToWrite; //设备写就绪 isCreate; isOpen; ioAddr; //设备头数据结构 //设备创建标志 //设备打开标志 //设备 I/O 基地址
… }ห้องสมุดไป่ตู้
/*必要的硬件初始化*/
3.回调安装函数
static int xxCallbackInstall(SIO_CHAN * pSioChan, int callbackType, STATUS (*callback)(), void * callbackArg) { xx_CHAN * pChan = (xx_CHAN *)pSioChan; switch(callbacktype) { case SIO_CALLBACK_GET_TX_CHAR: pChan->getTxChar pChan->getTxArg return(OK); case SIO_CALLBACK_PUT_RCV_CHAR: pChan->getRcvChar pChan->getRcvArg return(OK); default: return(ERROR); } } = callback; = callbackArg; = callback; = callbackArg;
4.启动一次发送周期函数
LOCAL int xxTxStartup(SIO_CHAN * pChan) { xx_CHAN * pxxChan = (xx_CHAN *)pChan; char ier = xx_IER_RXRDY; char status; if(pxxChan->cahnnelMode == SIO_MODE_INT) { /*根据硬件寄存器的值判断状态*/ status = ((*pxxChan->inByte)(pxxChan->sta)); /*如果状态正确,打开中断*/ if(status == xx_OK) (*pxxChan->outByte)(pxxChan->ier); /*ier:打开中断寄存器*/ } return(OK); }
7. I/O 控制函数
int xxIoctl(int xxDevId, int cmd, int arg) { int status; xx_DEV *pxxDev=(xx_DEV *)xxDevId; switch(cmd) { case FIOSELECT: selNodeAdd(&pxxDev->selWakeupList, (SEL_WAKEUP_NODE *)arg);
RegMEMBase; //设备存储器基地址
2.设备驱动程序装载函数
STATUS xxDrv() { //首先判断驱动程序是否已经安装 if(xxDrvNum>0) return(OK); … /*在这里添加驱动程序的初始化部分*/ /*将驱动程序添加到驱动程序描述表中*/ if((xxDrvNum=iosDrvInstall(xxOpen, NULL, xxOpen, xxClose, xxRead, xxWrite, xxIoctl)==ERROR) { return(ERROR); } return(OK); }
return(OK); }
10.设备中断管理函数
STATUS ULONG xxIntHandler(int xxDevId) { xx_DEV * pxxDev=(xx_DEV *) xxDevId; … /*读取中断状态*/
/*如果可以接受*/ pxxDev->ReadyToRead=TRUE; /*如果可以发送*/ pxxDev->ReadyToWrite=FALSE; … } /*清除相应中断*/
5.读函数
int xxRead(int xxDevId, char * pBuf, int nBytes) { xx_DEV * pxxDev=(xx_DEV *) pxxDevId; int ReadLength=ERROR; BOOL FoundError; if(pxxDev==(xx_DEV *)NULL) { errnoSet(S_xx_NODEV); return(ERROR); } /*判断设备是否就绪*/ if(pxxDev->ReadyToRead) { readLength=0;
if(selWakeupType((SEL_WAKEUP_NODE *)arg)==SELREAD)&&(&pxxDev->ReadyToRead)) selWakeup((SEL_WAKEUP_NODE *)arg); if(selWakeupType((SEL_WAKEUP_NODE *)arg)==SELWRIT)&&(&pxxDev->ReadyToWrite)) selWakeup((SEL_WAKEUP_NODE *)arg); break; case FIOUNSELECT: selNodeDelete(&pxxDev->selWakeupList, (SEL_WAKEUP_NODE *) arg); break; case xx_STATUS_GET: status=xxStatusGet(&arg); break; case xx_CONTROL_SET: status=xxCMDSet(arg); break; … /*其它命令实现*/ errno=S_ioLib_UNKNOWN_REQUEST; status=ERROR; } return(status); } default:
while(ReadLength<nBytes) { readLength++; } … … /*判断状态寄存器、接受到的字符数目*/ /*根据数据返回状态*/ return(ERROR); return(ReadLength); } return(ReadLength); }
if(FoundError) /*非正常接受*/