分类: 嵌入式
2013-06-19 21:49:54
函数库iosLib是库ioLib的底层实现,它负责将各个硬件设备及其驱动组织起来,从而使得用户只需要调用ioLib库就可以通过类似于文件IO的访问方式来访问各个硬件设备。在对iosLib库函数进行分析的过程中我们将主要分析系统是如何将这些设备以及驱动组织起来,以及如何为ioLib库提供接口的。
在函数库iosLib中定义了一个通用的接口结构DRV_ENTRY,它为ioLib库提供了一个通用过的接口,使得ioLib无需了解具体的设备类型就可以对硬件设备进行访问;另一方面它又通过继承的方法,将不同类型的设备保存在链表中进行统一管理(参见图2.8)。下面对设备的管理函数进行详细分析。
1. static STATUS nullWrite
(
int dummy,
char * pBuf,
int nBytes
)
空函数。
2. STATUS iosInit
(
int max_drivers,
int max_files,
char *nullDevName
)
iosLib函数库初始化,该函数的主要作用是动态创建了一个FD_ENTRY结构数组和一个DRV_ENTRY结构数组,并进行了初始化。
3. int iosDrvInstall
(
FUNCPTR pCreate,
FUNCPTR pDelete,
FUNCPTR pOpen,
FUNCPTR pClose,
FUNCPTR pRead,
FUNCPTR pWrite,
FUNCPTR pIoctl
)
从DRV_ENTRY结构数组中找到一个空闲的DRV_ENTRY结构变量,将参数指定函数指针填充到该。注意由于最开始的一个元素即drvTable[0]中填充的是一个空设备,因此查找空闲的元素是从下表1开始查找的。如图2.10。该函数返回下标i。
图2.10 函数iosDrvInstall的操作
正是这个步骤才使得一类设备的特殊访问方法与通用的接口连接起来。
4. STATUS iosDrvRemove
(
int drvnum,
BOOL forceClose
)
函数iosDrvInstall的逆过程,将DRV_ENTRY结构数组中的下表为drvnum的元素清空。如果forceClose参数为TRUE则需要强制关闭该设备已经打开的文件。如果forceClose为FALSE但是该设备有打开的文件,则返回错误。
注意:一个设备可能对应多个打开的文件。
5. STATUS iosDevAdd
(
DEV_HDR *pDevHdr,
char *name,
int drvnum
)
增加一个设备,该设备名称(路径)名为name,该设备的7个访问函数在对应的DRV_ENTRY结构数组中的下表为drvnum。如图2.11所示。
注意,在添加设备之前需要调用函数iosDevMatch检查已经添加的设备中是否包含相同的路径名(文件名)如果有则说明该设备已经加入了。返回错误。此外就是该函数只修改了iosDvList链,并不触及DRV_ENTRY结构数组的操作。
如果已经加入的设备中有“ab”这个名字,那么还可以增加名字为“abc”、“a”这样的设备,但是名字为“ab”的再不能添加了。
图2.11 在设备管理库中加入新设备
6. void iosDevDelete
(
DEV_HDR *pDevHdr /* pointer to device's structure */
)
从iosDvList链中删除一个设备。注意添加的时候DEV_HDR结构中的name是动态分配的,因此这里需要释放相应的空间。这里可以参考iosDevAdd函数,在iosDevAdd函数中参数pDevHdr也不是动态分配的。
7. DEV_HDR *iosDevFind
(
char *name, /* name of the device */
char **pNameTail /* where to put ptr to tail of name */
)
根据名字查找一个设备的DEV_HDR结构。查找遵照一下原则:
l 调用函数iosDevMatch在devTable数组中查找与name最为匹配的,也就是说查找的设备名字与name的前面n(n为设备名称的字符个数)个字符完全相同;
l 如果查到了匹配的,则返回值*pNameTail返回的则是name字符串中不包含设备名称的字符串;
l 如果没有找到匹配的设备,则返回默认的设备(如果有的话),此时*pNameTail返回的则是原name字符串。
8. LOCAL DEV_HDR *iosDevMatch
(
char *name
)
该函数的作用是查找已经添加的设备名中与参数name匹配度最大设备名。所谓匹配度最大就是说设备名正好是name字符串的前n(n为设备名称字符串长度)个字符完全相同中的所有设备中n最大的那一个设备。例如已经添加的设备中有“ab”、“abc”“bcde”,那么与name=“abcde”匹配最大的为“abc”。
9. DEV_HDR *iosNextDevGet
(
DEV_HDR *pDev
)
从node链中查找下一个node的DEV_HDR结构变量,参照前面的链表结构图。
10. int iosCreate
(
DEV_HDR *pDevHdr,
char *fileName,
int mode
)
该函数根据DEV_HDR结构指针pDevHdr中的drvNum数值作为下标,找到drvTable数组中的DEV_ENTRY结构变量中的de_create函数指针,调用de_create函数。
11. int iosDelete
(
DEV_HDR *pDevHdr,
char *fileName
)
类似于函数iosCreate()。
12. int iosOpen
(
DEV_HDR *pDevHdr,
char *fileName,
int flags,
int mode
)
类似于函数iosCreate()。
13. STATUS iosClose
(
int fd
)
类似于函数iosCreate()。
14. int iosRead
(
int fd,
char *buffer,
int maxbytes
)
类似于函数iosCreate()。
15. int iosWrite
(
int fd,
char *buffer,
int nbytes
)
类似于函数iosCreate()。
16. int iosIoctl
(
int fd,
int function,
int arg
)
基本的控制函数,主要完成几个功能。
function == FIOGETNAME,将文件描述符的名字复制到arg中;
其他情况则执行drvTable [pFdEntry->pDevHdr->drvNum].de_ioctl,这个类似于函数iosCreate()。
17. LOCAL void iosLock (void)
这个函数和iosUnlock共同管理一个二进制信号量,主要负责对fdTable、iosDevList的访问保护。主要进行互斥操作。