1, 标准I/o 函数为 open, create, read, write, ioctl, close , remove.
2,核心结构为 a, 设备列表 iosDevShow or devs可以查看系统中安装的设备
b, 驱动程序描述表 iosDrvShow可以查看系统中的驱动程序的个数和各个io函数的地址
c, 文件描述符表, i/o系统将文件描述符与驱动程序,设备对应起来的手段
3,fd = open(”/xxDev”, O_READ, 0)的过程 是 先通过/xxDev文件名找到设备(在设备列表中),根据设备描述结构找到驱动程序索引号,找到驱动程序, 返回文件描述符
4, read(fd, &buf, nBytes)的过程是通过文件描述符表直接找到驱动程序索引号。使用驱动程序。
5, src
6,.h
//data struct
#ifndef __XYXTYDRV_H__
#define __XYXTYDRV_H__
#ifdef __cplusplus
extern "C"{
#endif
typedef struct
{
DEV_HED devHdr;
BOOL isCreate;
BOOL isOpen;
UINT32 RegMEMBase;
UINT32 ioAddr;
SEL_WAKEUP_LIST selWakeupList;
BOOL ReadyToRead;
BOOL ReadyToWrite;
} ttyXyx_DEV;
#ifdef __cplusplus
}
#endif
#endif
7, .c
#include "xyxtyDrv.h"
LOCAL int ttyXyxDrvNum=0;
//install
STATUS ttyXyxDrv()
{
if(ttyXyxDrvNum>0) return(OK);
//drv init code here
//put the drv into drv table
if(ttyXyxDrvNum = iosDrvInstall(ttyXyxOpen, ttyXyxDelete, ttyXyxOpen, ttyXyxClose,/
ttyXyxRead, ttyXyxWrite, ttyXyxIoctl) == ERROR)
{
return (ERROR);
}
return (OK);
}
//drv create
STATUS ttyXyxDevCreate(char * devName)
{
ttyXyx_DEV *pttyxyxDev;
if(ttyXyxDrvNum < 1)
{
errno = S_ioLib_NO_DRIVER;
return (ERROR);
}
if((pttyxyxDev = (ttyXyx_DEV *)malloc( sizeof(ttyXyx_DEV))) == NULL)
{
return (ERROR);
}
bzero(pttyxyxDev, sizeof(ttyXyx_DEV));
selWakeupListInit(&pttyxyxDev->selWakeupList);
//init pttyxyxDev
if( iosDevAdd(&pttyxyxDev->devHdr, devName, ttyXyxDrvNum) == ERROR)
{
free((char *)pttyxyxDev);
return (ERROR);
}
return (OK);
}
// open function
int ttyXyxOpen(DEV_HDR *pttyDevHdr, int option, int flags)
{
ttyXyx_DEV *pttyDev = (ttyXyxDEV *)pttyDevHdr;
if(pttyDev == NULL)
{
errnoSet(S_xyx_NODEV);
return (ERROR);
}
if(pttyDev->isOpen)
{
errnoSet(S_xyx_DEVOPENED);
return (ERROR);
}
pttyDev->isOpen = TRUE;
//....init
return (int)pttyDevHdr);
}
//read function
int ttyXyxRead(int ttyDevId, char *pBuf, int nBytes)
{
ttyXyx_DEV *pttyXyxDev = (ttyXyx_DEV *)ttyDevId;
int ReadLength = ERROR;
BOOL FoundError;
if(pttyXyxDev = (ttyXyx_DEV *)NULL)
{
errnoSet(S_xyx_NODEV);
return ERROR;
}
if(pttyXyxDev->ReadyToRead)
{
ReadLength = 0;
while(ReadLength < nBytes)
{
ReadLength++;
}
// judge the register and received nbytes
if(FoundError)
return (ERROR);
return (ReadLength);
}
return (ReadLength);
}
//write function
int ttyXyxWrite(int ttyDevId, char *pBuf, int nBytes)
{
ttyXyx_DEV *pttyXyxDev = (ttyXyx_DEV *)ttyDevId;
int WriteLength = 0;
BOOL FoundError;
if(pttyXyxDev == (ttyXyx_DEV *)NULL)
{
errnoSet(S_xyx_NODEV);
return (ERROR);
}
if(pttyXyxDev->ReadyToWrite)
{
pttyXyxDev->ReadToWrite = FALSE;
//write data to data
//judge the state
}
pttyXyxDev->ReadyToWrite = TRUE;
if(FoundError)
return (ERROR);
return (WriteLength);
}
//ioctl function
int ttyXyxIoctl(int ttyDevId, int cmd, int arg)
{
int status;
ttyXyx_DEV *pttyXyxDev = (ttyXyx_DEV *)ttyDevId;
switch(cmd)
{
case FIOSELECT:
selNodeAdd(&pttyXyxDev->selWakeupList, (SEL_WAKUP_NODE *)arg);
if((selWakeupType((SEL_WAKUP_NODE *)arg) == SELREAD) && (&pttyXyxDev->ReadyToRead)
selWakeup((SEL_WAKUP_NODE *)arg);
if((selWakeupType((SEL_WAKUP_NODE *)arg) == SELWRITE) && (&pttyXyxDev->ReadyToWrite)
selWakeup((SEL_WAKUP_NODE *)arg);
break;
case FIOUNSELECt:
selNodeDelete(&pttyXyxDev->selWakeupList, (SEL_WAKUP_NODE *)arg);
break;
case xx_STATUS_GET:
status = xxStatusGet(&arg);
case xx_CONTROL_SET:
status = xxCMDSet(arg);
break;
//other cmd
default:
errno=S_ioLib_UNKNOWN_REQUEST;
status=ERROR;
}
return (status);
}
//close function
int ttyXyxClose(int ttyDevId)
{
ttyXyx_DEV *pttyXyxDev = (ttyXyx_DEV *)ttyDevId;
if(pttyXyxDev = (ttyXyx_DEV *)NULL)
{
errnoSet(S_xyx_NoMEM);
return (ERROR);
}
// deal with equipment
//release resourse
free(pttyXyxDev);
}
//unsintall function
STATUS ttyXyxDelete(char *devName)
{
DEV_HDR *pDevHdr;
char *pNameTail;
//search dev
pDevHdr=iosDevFind(devName, pNameTail);
if(pDevHdr == NULL || *pNameTail !='/0')
return (ERROR);
//release resourse sample sam wakeup signal
//uninstall
iosDevDelete(pDevHdr);
return (OK);
}
LOCAL ULONG ttyXyxIntHandler(int ttyDevId)
{
ttyXyx_DEV *pttyXyxDev = (ttyXyx_DEV *)ttyDevId;
if(pttyXyxDev = (ttyXyx_DEV *)NULL)
{
errnoSet(S_xyx_NoMEM);
return (ERROR);
}
// read the interrupt status
//if can receive
pttyXyxDev->ReadyToRead = TRUE;
pttyXyxDev->ReadyToWrite = FALSE;
// clear the interrupt
}