Linux字符设备驱动
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验二:Linux字符设备驱动
一.字符设备驱动实现的方法包括Write, Read, Poll, Icotl, Mmap, Llseek等。
二.字符设备驱动的主要内容:并发控制,阻塞与非阻塞,异步通知。
三.字符设备驱动的主要文件:globalfifo.c Makefile globalfifo_test,globalfifo.c。
四.驱动程序如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define GLOBALFIFO_SIZE 24 /*全局fifo最大4K字节*/
#define FIFO_CLEAR 0x1 /*清0全局内存的长度*/
#define GLOBALFIFO_MAJOR 249 /*预设的globalfifo的主设备号*/ static int globalfifo_major = GLOBALFIFO_MAJOR;
/*globalfifo设备结构体*/
struct globalfifo_dev {
struct cdev cdev; /*cdev结构体*/
unsigned int current_len; /*fifo有效数据长度*/
unsigned char mem[GLOBALFIFO_SIZE]; /*全局内存*/ struct semaphore sem; /*并发控制用的信号量*/
wait_queue_head_t r_wait; /*阻塞读用的等待队列头*/
wait_queue_head_t w_wait; /*阻塞写用的等待队列头*/
};
struct globalfifo_dev *globalfifo_devp; /*设备结构体指针*/
/*文件打开函数*/
int globalfifo_open(struct inode *inode, struct file *filp)
{
/*将设备结构体指针赋值给文件私有数据指针*/
filp->private_data = globalfifo_devp;
return 0;
}
/*文件释放函数*/
int globalfifo_release(struct inode *inode, struct file *filp) {
return 0;
}
/* ioctl设备控制函数 */
static int globalfifo_ioctl(struct inode *inodep, struct file *filp, unsigned
int cmd, unsigned long arg)
{
struct globalfifo_dev *dev =
filp->private_data;/*获得设备结构体指针*/
switch (cmd) {
case FIFO_CLEAR:
down(&dev->sem); /* 获得信号量 */
dev->current_len = 0;
memset(dev->mem,0,GLOBALFIFO_SIZE);
up(&dev->sem); /* 释放信号量 */
printk(KERN_INFO "globalfifo is set to zero\n");
break;
default:
return - EINVAL; }
return 0;
}
static unsigned int globalfifo_poll(struct file *filp, poll_table *wait) {
unsigned int mask = 0;
struct globalfifo_dev *dev = filp->private_data;
/*获得设备结构体指针*/
down(&dev->sem);
poll_wait(filp, &dev->r_wait,
wait);/*把读等待队列添加到poll_table*/
poll_wait(filp, &dev->w_wait,
wait);/*把写等待队列添加到poll_table*/
/*fifo非空表示可读*/
if (dev->current_len != 0) {
mask |= POLLIN | POLLRDNORM; /*标示数据可获得*/ }
/*fifo非满表示可写*/
if (dev->current_len != GLOBALFIFO_SIZE) {
mask |= POLLOUT | POLLWRNORM; /*标示数据可写入*/ } up(&dev->sem);
return mask;
}
/*globalfifo读函数*/