主要内容:
- Linux设备驱动分类
- Linux系统下应用程序调用驱动程序过程
- 字符设备驱动程序基础
- 驱动程序初始化
- 和并行端口交互
- RTC子系统;
1.Linux设备驱动分类
Linux系统将设备分为3类,如下:
- 字符设备,就是按照字节流进行读写操作的设备,读写数据是分先后顺序的,常见的字符设备有按键、鼠标、键盘、串口、I2C、SPI和LCD等,
- 块设备,是指可以从设备的任意位置读取一定长度数据的设备,如U盘、SD卡、硬盘等;
- 网络设备,能够支持上网的,如有线网卡,无线网卡的;
2. Linux系统下应用程序调用驱动程序过程
图1 linux应用程序对驱动程序的调用过程
应用程序运行在用户空间,而linux驱动程序属于内核的一部分,运行在内核空间,当使用open函数打开/dev/led驱动时,需要使用“系统调用”的方法来完成,调用过程如下图open()函数调用流程所示:
图2 open()函数调用流程
3. 字符设备驱动程序基础
字符设备驱动程序包括如下:
初始化例程init(),负责初始化设备并将驱动程序和内核的其他部分通过注册函数实现连接;
入口函数集,如open()、read()、ioctl()、llseek()和write(),这些函数直接对应相应的I/O系统调用;
中断例程、底半部例程、定时器处理例程、内核辅助线程等;
4. 驱动程序初始化
4.1 Init()函数是注册机制的基础,负责完成如下工作:
申请分配主设备号;
为特定设备相关的数据结构分配内存;
将入口函数(open()、read()等)与字符驱动程序的cdev抽象相关联;
将主设备号与驱动程序的cdev相关联;
在/dev和/sys下创建节点;
初始化硬件;
4.2 打开和释放
当应用程序打开设备节点时,内核调用相应驱动程序的open()函数;关闭一个已经打开的设备时,内核调用release()函数。
代码片段1,打开和释放
/* * Open CMOS bank */ int cmos_open(struct inode *inode, struct file *file) { struct cmos_dev *cmos_devp; /* Get the per-device structure that contains this cdev */ cmos_devp = container_of(inode->i_cdev, struct cmos_dev, cdev); /* Easy access to cmos_devp from rest of the entry points */ file-.private_data = cmos_devp; /* Initialize some fields */ cmos_devp->size = CMOS_BANK_SIZE; cmos_devp->current_pointer = 0; return 0; } /* * Release CMOS bank */ int cmos_release(struct inode *inode, struct file *file) { struct cmos_dev *cmos_devp = file->private_data; /* Reset file pointer */ cmos_devp->current_pointer = 0; return 0; }
5. 和并行端口交互
并行端口是在PC兼容系统上常见的25针接口,并行端口的能力取决于芯片组。
6. RTC子系统
内核中对RTC的支持分成两层:硬件无关的顶层字符驱动程序,用于实现内核的RTC API;硬件相关的底层驱动程序,用于和底层的总线通信。