第8章 支持阻塞操作的globalfifo设备驱动

死锁,就是多个进程循环等待他方占有的资源而无限期地僵持下去。如果没有外力的作用,那么死锁涉及的各个进程都将永远处于封锁状态。

1、驱动头文件

#ifndef __GLOBAL_MEM_H
#define __GLOBAL_MEM_H

#include <linux/cdev.h>
#include <linux/mutex.h>
#include <linux/wait.h>

#define DRIVER_AUTHOR "xz@vi-chip.com.cn"
#define DRIVER_DESC   "A sample driver" 

#define GLOBALFIFO_SIZE 0x1000
#define MEM_CLEAR 0x1
#define DEV_NAME "global_fifo"
#define GLOBALFIFO_MAJOR 230 /* 主设备号 */

/**
*
* 定义全局内存字符设备的结构体:
* 借用面向对象程序设计中“封装”的思想,体现良好的编程习惯。
*
*/
struct globalfifo_dev {
struct cdev cdev;
unsigned int current_len; // FIFO中有效数据的长度
unsigned char mem[GLOBALFIFO_SIZE];
struct mutex mutex; // 互斥锁
wait_queue_head_t r_wait;// 读等待队列头部
wait_queue_head_t w_wait;// 写等待队列头部
};


#endif /* __GLOBAL_MEM_H */

2、驱动源代码文件

#include <linux/init.h>  
#include <linux/module.h> 
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/sched.h>


/* include local head files */
#include "global_fifo.h"

static int globalfifo_major = GLOBALFIFO_MAJOR;
module_param(globalfifo_major, int, S_IRUGO); /* mode:S_IRUGO */

struct globalfifo_dev *globalfifo_devp = NULL;

/**
*
* 读写函数
* 让设备结构体globalfifo_dev的mem[]数组与用户空间交互数据,
* 并随着访问的字节数变更更新文件读写偏移位置。
*/
// globalfifo设备驱动的读函数,从设备中读取数据
static ssize_t globalfifo_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
{
int ret;
struct globalfifo_dev *dev = filp->private_data; // 获取私有数据指针

DECLARE_WAITQUEUE(wait, current);// 定义并初始化一个名为wait的等待队列元素
mutex_lock(&dev->mutex); // 获取互斥锁
add_wait_queue(&dev->r_wait, &wait); // 把等待队列元素wait添加到读等待队列头部r_wait指向的双向链表中
while (dev->current_len == 0) { // FIFO为空
if (filp->f_flags & O_NONBLOCK) { // 非阻塞
ret = -EAGAIN;
goto out;
}
__set_current_state(TASK_INTERRUPTIBLE);// 改变进程状态TASK_INTERRUPTIBLE,浅度睡眠标记,并没有真正睡眠.
mutex_unlock(&dev->mutex); // 释放互斥锁
schedule();// 让读进程进入睡眠,调度其他进程执行
if (signal_pending(current)) { // 判断是否被信号唤醒
ret = -ERESTARTSYS;
goto out2;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值