Linux字符设备驱动

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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 /* device_create()*/

#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读函数*/

相关文档
最新文档