在我们编写CC1100驱动程序和倒车雷达驱动程序的时候,我们都用到了当前读取数据标志位,即我们在驱动程序中会定义一个容器用来存放数据,每一次我们读完一个数据时,我们都会将我们的读数据变量加1,这样下一次再来读取数据的时候就不会读到以前的数据了,都会是全新的数据。当然这个方法是我们自己在编写驱动程序时候自己定义的。是否在Linux内核中本来就有这样的机制呢?答案是肯定的。这个机制就是seek机制,那么seek机制又是如何实现记录读取数据位置的机智的呢?同poll机制一样,在file->fop里面也定义有seek的函数指针,那就是llseek,这个函数指针当然是指向我们自己编写的驱动程序的函数了。其实seek实现的机制比较简单,主要就是围绕当前文件指针file->f_ops这个指针来的,这个指针存放的是当前驱动程序文件的读写数据位置,我们在哪里用到了f_ops这个指针呢?首先我们来看一下我们比较熟悉的read函数和open函数,我们知道在这两个函数中我们所要用到的参数都是一样的CC1100_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)和static ssize_t CC1100_write(struct file *filp, const char *buff, size_t count, loff_t *offp)其里面的参数都是一样的,第一个参数是file(该设备文件)、第二个参数是用户层传过来的buff指针,第三个是用户层传过来的写入或者读取长度大小(size_t),那么第四个参数是什么呢,好像我们之前都没有用过,这第四个参数保存的数据就是我们上面讲的file->f_ops,用来记录我们驱动程序文件的读取数据的位置。通常如果我们不用seek机制的话,这个参数也一般都用不到,其值永远都是0。所以从上面我们也可以推出,要想使用read或者是write的第四个参数的话,我们必须使用 seek函数来改变f_ops指针的指向seek的机制就是用来改变文件指针的值的。通常我们使用seek机制都会遵循一定的模板,首先我们要在驱动程序中编写我们自己的seek函数,大致模板为:

在驱动程序中首先要定义自己的seek函数,通常该函数的模式都是一样的:

loff_t scull_llseek(struct file *filp, loff_t off, int whence)

{

struct scull_dev *dev = filp->private_data;

loff_t newpos;

switch(whence)

{

case 0: /* SEEK_SET */ //从起始位置进行偏移

newpos = off;

break;

case 1: /* SEEK_CUR */ //从当前位置进行偏移。

newpos = filp->f_pos + off;

break;

case 2: /* SEEK_END */ //以数据容器尾部作为偏移

newpos = dev->size + off;

break;

default: /* can't happen */

return -EINVAL;

}

if (newpos < 0)

return -EINVAL;

filp->f_pos = newpos; //这句代码就是关键,改变驱动文件的f_pos的指向。

return newpos; //返回当前指针

}

同时也必须在file_operations里面指定file_operations->llseek指针的指向scull_llseek函数,方式类似open等函数。

static struct file_operations _fops =

{

.............

.llseek = scull_llseek

..............

}

编写能够与llseek配套的write函数,因为seek机制必须要和read、write等函数配套使用才能发挥其效力。

static ssize_t globalmem_write(struct file *filp, const char __user *buf,

size_t size, loff_t *ppos)

{

unsigned long p = *ppos;

unsigned int count = size;

int ret = 0;

struct globalmem_dev *dev = filp->private_data; /*获得设备结构体指针*/

/*分析和获取有效的写长度*/

if (p >= GLOBALMEM_SIZE)

return count ? - ENXIO: 0;

if (count > GLOBALMEM_SIZE - p) //当count+p> GLOBALMEM_SIZE则表示如果按照当前的读取数据大小//和文件指针值读取数据的话,将会超过数据的最大值

count = GLOBALMEM_SIZE - p;

if (down_interruptible(&dev->sem))//获得信号量

{

return - ERESTARTSYS;

}

/*用户空间->内核空间*/

//数据复制的位置将从dev->mem + p开始

if (copy_from_user(dev->mem + p, buf, count))

ret = - EFAULT;

else

{

*ppos +=count;

ret = count;

printk(KERN_INFO "written %d bytes(s) from %d\n", count, p);

}

up(&dev->sem); //释放信号量

return ret;

}

编写能够与llseek配套的read函数

static ssize_t globalmem_read(struct file *filp, char __user *buf, size_t size,

loff_t *ppos)

{

unsigned long p = *ppos;

unsigned int count = size;

int ret = 0;

struct globalmem_dev *dev = filp->private_data; /*获得设备结构体指针*/

/*分析和获取有效的写长度*/

if (p >= GLOBALMEM_SIZE)

return count ? - ENXIO: 0;

if (count > GLOBALMEM_SIZE - p)

count = GLOBALMEM_SIZE - p;

if (down_interruptible(&dev->sem))

{

return - ERESTARTSYS;

}

/*内核空间->用户空间*/

if (copy_to_user(buf, (void*)(dev->mem + p), count))

{

ret = - EFAULT;

}

else

{

*ppos += count;

ret = count;

printk(KERN_INFO "read %d bytes(s) from %d\n", count, p);

}

up(&dev->sem); //释放信号量

return ret;

}

linux seek原理,Linux内核:seek机制相关推荐

  1. Linux IO原理和零拷贝机制

    目录 1 概述 2 Linux I/O读写方式 2.1 I/O中断原理 2.2. DMA传输原理 2.3 传统I/O方式 3 零拷贝方式 3.1 用户态直接I/O 3.2 mmap + write 3 ...

  2. linux 随机数原理,Linux随机数生成器的原理和缺陷.pdf

    第17卷.第10期 计算机技术与发展 vol.17No.10 2007年10月 COMPUTERTECHNOLOGYANDDEVELOPMENT Oct.2007 Linux随机数生成器的原理及缺陷 ...

  3. linux随机数原理,Linux随机数生成器的原理与缺陷.pdf

    第17卷.第10期 计算机技术与发展 vol.17No.10 2007年10月 COMPUTERTECHNOLOGYANDDEVELOPMENT Oct.2007 Linux随机数生成器的原理及缺陷 ...

  4. linux操作系统原理_Linux内核分析-操作系统是如何工作的(二)

    linux操作系统的主要构架如图1所示,我们知道,操作系统是通过管理CPU进程.存储器.文件系统.设备驱动.以及网络接口等相关部分来工作的,我们这里主要是通过分析关于CPU的操作即进程的管理执行来分析 ...

  5. linux审计原理,Linux安全审计机制模块实现分析(1)

    2详细分析 2.1模块功能描述 本模块包含以下几个子系统: (1) 审计消息的生成和发送子系统: (2) 审计消息过滤子系统: (3) 审计系统初始化子系统: (4) 进程审计子系统: (5) 文件系 ...

  6. linux+proc+原理,Linux内核中的Proc文件系统(一)

    (1)/proc文件系统的特点和/proc文件的说明 /proc文件系统是一种特殊的.由软件创建的文件系统,内核使用它向外界导出信息,/proc系统只存在内存当中,而不占用外存空间. /proc下面的 ...

  7. linux shell 原理,linux下shell的工作原理

    linux下shell的工作原理 2009-12-8 10:19:53   出处:https://www.yqdown.com shell是用户和Linux操作系统之间的接口.Linux中有多种she ...

  8. linux bonding 原理,Linux bonding 之balance-alb 原理介绍及其实现

    Linux bonding 之balance-alb 原理介绍及其实现 要求: 首先要安***onding driver 和 ifenslave.bonding driver 是实现网卡绑定的软件基础 ...

  9. linux acl原理,linux acl详细讲解

    Linux ACL 详细讲解 用户权限管理始终是 Unix 系统管理中最重要的环节.大家对 Linux/Unix 的 UGO 权限管理方式一定不陌生,还有最常用的 chmod 命令.为了实现一些比较复 ...

  10. linux多进程原理,Linux进程调度

    极简模式 假设我的系统只有一种调度算法cfs 那么有个调度的队列 cfs_rq 所有running的进程都会 进入这个队列,不在running 或者其他情况会出队列,ok.则假设队列控制的算法有以下. ...

最新文章

  1. excel html modify,在Excel 2010中修改Series对象上的Z-index(Modify Z-index on Series object in Excel 2010)...
  2. php sem acquire,PHP | 关于php中sem_get failed for key no space left on device问题的解决方案...
  3. 容器编排技术 -- kubeadm 实现细节
  4. 机器学习(1)---数据预处理
  5. 06_day初始化PIC
  6. 计算机vfp实验小结,vfp实验1报告心得体会
  7. C++的引用一,求二次方根
  8. win10设置HTML桌面背景,win10系统分屏设置不同壁纸教程
  9. Spring Boot 整合 AWS S3协议 OSS功能 支持 七牛、阿里、Minio等一切支持S3协议的云厂商
  10. H5viedo标签播放*.Mp4听得到音频却不显示视频的解决办法
  11. SpringBoot快速入门--基础版(包含整合常用框架、跨域)
  12. ios 视频选择封面功能
  13. View被遮挡的解决办法
  14. 2022-2028年中国康复理疗行业市场发展现状及竞争格局预测报告
  15. Flowable入门系列文章47 - 电子邮件任务
  16. python汉明距离检索_【LeetCode 461】汉明距离(Python)
  17. 时间序列分析的基本思路与步骤
  18. 2018年世界计算机销售排名,2018年第二季全球笔记本电脑出货量排名
  19. python 绘制科赫雪花
  20. Nginx 入门基础

热门文章

  1. Accelio 代码笔记
  2. 关于HTML预处理器Pug的使用文档
  3. python建站部署_2个Python学习网站制作教程
  4. nod32半年升级id
  5. mysql tmp mysql.sock_MySQL搭建过程中的“/tmp/mysql.sock错误解决
  6. 2021,自动驾驶的“五代十国”
  7. android绘制立方体带坐标,Android: 直接在bitmap上绘制一个立方体
  8. fmask云检测 matlab_ENVI5.4中的云检测/掩膜工具
  9. 计算机软件的四种人才
  10. Word分栏出现空白怎么解决