linux驱动开发中常用函数copy_from_user open read write详解

目录
  • linux驱动常用函数(copy_from_user open read write)
    • 1.open
    • 2.read
    • 3.write
    • 4.copy_to_user
    • 5.copy_from_user

linux驱动常用函数(copy_from_user open read write)

1.open

函数定义:
int open( const char * pathname, int flags);
int open( const char * pathname,int flags, mode_t mode);
参数说明:
  pathname :文件的名称,可以包含(绝对和相对)路径
  flags:文件打开模式
  mode: 用来规定对该文件的所有者,文件的用户组及系统中其他用户的访问权限,则文件权限为:mode&(~umask)
函数说明:
参数pathname 指向欲打开的文件路径字符串。下列是参数flags 所能使用的旗标:

  • O_RDONLY 以只读方式打开文件;
  • O_WRONLY 以只写方式打开文件;
  • O_RDWR 以可读写方式打开文件;

上述三种旗标是互斥的,也就是不可同时使用,但可与下列的旗标利用OR(|)运算符组合;

  • O_CREAT 若欲打开的文件不存在则自动建立该文件;
  • O_EXCL 如果O_CREAT也被设置,此指令会去检查文件是否存在。文件若不存在则建立该文件,否则将导致打开文件错误,此外,若O_CREAT与O_EXCL同时设置,并且欲打开的文件为符号连接,则会打开文件失败。
  • O_NOCTTY 如果欲打开的文件为终端机设备时,则不会将该终端机当成进程控制终端机;
  • O_TRUNC 若文件存在并且以可写的方式打开时,此旗标会令文件长度清为0,而原来存于该文件的资料也会消失;
  • O_APPEND 当读写文件时会从文件尾开始移动,也就是所写入的数据会以附加的方式加入到文件后面;
  • O_NONBLOCK 以不可阻断的方式打开文件,也就是无论有无数据读取或等待,都会立即返回进程之中;
  • O_NDELAY 同O_NONBLOCK;
  • O_SYNC 以同步的方式打开文件;
  • O_NOFOLLOW 如果参数pathname 所指的文件为一符号连接,则会令打开文件失败;
  • O_DIRECTORY 如果参数pathname 所指的文件并非为一目录,则会令打开文件失败。

此为Linux2.2以后特有的旗标,以避免一些系统安全问题。参数mode 则有下列数种组合,只有在建立新文件时才会生效,此外真正建文件时的权限会受到umask值所影响,因此该文件权限应该为(mode-umaks)。

  • S_IRWXU00700 权限,代表该文件所有者具有可读、可写及可执行的权限;
  • S_IRUSR 或S_IREAD,00400权限,代表该文件所有者具有可读取的权限;
  • **S_IWUSR 或S_IWRITE,00200 **权限,代表该文件所有者具有可写入的权限;
  • S_IXUSR 或S_IEXEC,00100 权限,代表该文件所有者具有可执行的权限;
  • S_IRWXG 00070权限,代表该文件用户组具有可读、可写及可执行的权限;
  • S_IRGRP 00040 权限,代表该文件用户组具有可读的权限;
  • S_IWGRP 00020权限,代表该文件用户组具有可写入的权限;
  • S_IXGRP 00010 权限,代表该文件用户组具有可执行的权限;
  • S_IRWXO 00007权限,代表其他用户具有可读、可写及可执行的权限;
  • S_IROTH 00004 权限,代表其他用户具有可读的权限;
  • S_IWOTH 00002权限,代表其他用户具有可写入的权限;
  • S_IXOTH 00001 权限,代表其他用户具有可执行的权限。

返回值:
若所有欲核查的权限都通过了检查则返回0值,表示成功,只要有一个权限被禁止则返回-1。

错误代码:
EEXIST 参数pathname 所指的文件已存在,却使用了O_CREAT和O_EXCL旗标;
EACCESS 参数pathname所指的文件不符合所要求测试的权限;
EROFS 欲测试写入权限的文件存在于只读文件系统内;
EFAULT 参数pathname指针超出可存取内存空间;
EINVAL 参数mode 不正确;
ENAMETOOLONG 参数pathname太长;
ENOTDIR 参数pathname不是目;
ENOMEM 核心内存不足;
ELOOP 参数pathname有过多符号连接问题;
EIO I/O 存取错误。

#include
#include
#include
#include
main()
{
    int fd,size;
    char s [ ]=”Linux Programmer!\n”,buffer[80];
    fd=open(“/tmp/temp”,O_WRONLY|O_CREAT);
    write(fd,s,sizeof(s));
    close(fd);
    fd=open(“/tmp/temp”,O_RDONLY);
    size=read(fd,buffer,sizeof(buffer));
    close(fd);
    printf(“%s”,buffer);
}

2.read

函数定义:
ssize_t read(int fd, void * buf, size_t count);

函数说明:
read()会把参数fd所指的文件传送count 个字节到buf 指针所指的内存中。

返回值:
返回值为实际读取到的字节数, 如果返回0, 表示已到达文件尾或是无可读取的数据。若参数count 为0, 则read()不会有作用并返回0。

注意:
  read时fd中的数据如果小于要读取的数据,就会引起阻塞。
  read的用法比write较为简单,此处不叙述过多。由于笔者水平也有限,如果文中有谬误之处还恳请诸位指出,以免误导大家。

3.write

函数定义:
ssize_t write (int fd, const void * buf, size_t count);

函数说明:
write()会把参数buf所指的内存写入count个字节到参数放到所指的文件内。

返回值:
如果顺利write()会返回实际写入的字节数。当有错误发生时则返回-1,错误代码存入errno中。
(1)write()函数返回值一般无0,只有当如下情况发生时才会返回0:write(fp, p1+len, (strlen(p1)-len)中第三参数为0,此时write()什么也不做,只返回0。man手册给出的write()返回值的说明如下:
(2)write()函数从buf写数据到fd中时,若buf中数据无法一次性读完,那么第二次读buf中数据时,其读位置指针(也就是第二个参数buf)不会自动移动,需要程序员编程控制
而不是简单的将buf首地址填入第二参数即可。如可按如下格式实现读位置移动:write(fp, p1+len, (strlen(p1)-len)。 这样write第二次循环时变会从p1+len处写数据到fp, 之后的也
由此类推,直至(strlen(p1)-len变为0。

以下通过一个例子具体说明write函数用法:

#include
#include
#include
int main()
{
  char *p1 = "This is a c test code";
  volatile int len = 0;

  int fp = open("/home/test.txt", O_RDWR|O_CREAT);
  for(;;)
  {
     int n;

     if((n=write(fp, p1+len, (strlen(p1)-len)))== 0)   //if((n=write(fp, p1+len, 3)) == 0)
     {                                                 //strlen(p1) = 21
         printf("n = %d \n", n);
         break;
     }
     len+=n;
  }
  return 0;
}

(3)在write一次可以写的最大数据范围内(貌似是BUFSIZ ,8192),第三参数count大小最好为buf中数据的大小,以免出现错误。(经过笔者再次试验,write一次能够写入的并不只有8192这么多,笔者尝试一次写入81920000,结果也是可以,看来其一次最大写入数据并不是8192,但内核中确实有BUFSIZ这个参数,具体指什么还有待研究)

4.copy_to_user

函数定义:
unsigned long copy_to_user(void *to, const void *from, unsigned long n)
参数说明:
to:目标地址(用户空间)
from:源地址(内核空间)
n:将要拷贝数据的字节数
函数说明:
从内核空间中读取数据到用户空间
返回值:
成功返回0,失败返回没有拷贝成功的数据字节数

5.copy_from_user

函数定义:
unsigned long copy_from_user(void *to, const void *from, unsigned long n);
参数说明:
to:目标地址(内核空间)
from:源地址(用户空间)
n:将要拷贝数据的字节数
函数说明:
从用户空间中读取数据到内核空间
返回值:
成功返回0,失败返回没有拷贝成功的数据字节数

以上就是linux驱动常用函数(copy_from_user open read write)的详细内容,更多关于linux驱动常用函数的资料请关注我们其它相关文章!,希望大家以后多多支持我们!

(0)

相关推荐

  • Linux高级篇学习手册(一)

    目录 1. Linux的用户管理 1.1 添加用户 1.2 删除用户 1.3 查询用户信息 1.4 切换用户 1.5 对组操作 2. Linux的文件权限 2.1 查看资源的权限 2.2 添加权限语法 2.3 删除权限语法 2.4 修改权限语法 2.5 实现演示 3. Linux的进程管理 3.1 查看进程ps(process) 3.3 杀死进程 4. Linux的筛选过滤 4.1 grep 4.2 管道符| 总结 1. Linux的用户管理 1.Linux系统是一个多用户多任务的操作系统,任何

  • linux内核编程container of()函数介绍

    前言 在linux 内核编程中,会经常见到一个宏函数container_of(ptr,type,member), 但是当你通过追踪源码时,像我们这样的一般人就会绝望了(这一堆都是什么呀? 函数还可以这样定义??? 怎么还有0呢???  哎,算了,还是放弃吧...). 这就是内核大佬们厉害的地方,随便两行代码就让我们怀疑人生,凡是都需要一个过程,慢慢来吧. 其实,原理很简单:  已知结构体type的成员member的地址ptr,求解结构体type的起始地址. type的起始地址 = ptr - s

  • 学习手册--Linux基础篇

    目录 1. Linux系统介绍 1.1 linux的概述 1.2 linux的优势 1.3 linux的分类 1.4 常见的发行版linux系统 2. Linux的安装 3. Linux的基础篇 3.1 目录结构 3.1.1 那具体有哪些呢? 3.1.2 需要特别知道的: 3.2 虚拟机之查看网络IP 3.2.1 查看网络IP 3.2.2 linux系统查看ip命令 3.2.3 在windows系统查看ip命令 3.2.4 在windows主机连接远程linux虚拟机系统测试 3.4 虚拟机之查

  • VS2019开发Linux C++程序的实现步骤

    一级目录 第一步, 先将自己的Linux 系统设为静态IP,具体操作如下: 1.修改/etc/network/interfaces 地址配置文件,如下所示: (注 查看ip命令: ip addr 查看网关命令: ip route show ) 2.修改 /etc/resolvconf/resolv.conf.d/base 配置DNS服务器,如下所示: 3.执行reboot 命令重启Linux系统 第二步, 对VS2019 进行设置,具体操作如下: 1.打开vs2019,选择"工具(T)"

  • linux服务监控及运维

    目录 一, 安装psutil 包 二,找到操作系统中所有的服务的name和pid 三,找到需要监控但没有启动的服务 四,监控服务,如果没有开启则自动开启,[并发邮件通知工作人员] 一, 安装psutil 包 1.1.安装压缩包:以root身份登陆CentOS依次 执行以下命令: wget https://pypi.python.org/packages/source/p/psutil/psutil-2.1.3.tar.gz 如果wget 下不下来,则直接在浏览器中复制 粘贴链接https://p

  • linux脚本基础详细介绍

    目录 1.脚本vim环境 2.shell脚本中环境的定义方法 3.shell脚本中的转译字符 4.脚本中变量的数组 5.系统中命令的别名设定 6.脚本中的传参 7.脚本中的循环函数 1.脚本vim环境 在脚本中通常要显示一些脚本信息,这些信息可以通过对vim设定使其自动出现 /etc/vimrc 此文件是vim的主配置文件,文件内容全局生效 -/.vimrc 此文件是vim子文件,在用户家目录中编辑vim的配置文件也可以控制,但是只针对当前用户生效 vim ~/.vimrc 编辑配置文件 配置信

  • Linux高级篇学习手册(二)

    目录 1. Linux的crontab定时任务 1.1 配置定时任务 2. Linux的服务管理 6.1 服务管理 2.2 服务自启动 2.3 演示效果 总结 1. Linux的crontab定时任务 任务调度:是指系统在某个时间执行的特定的命令或程序. 任务调度分类: ​ 1. 系统工作:有些重要的工作必须周而复始地执行.如病毒扫描等 2. 个别用户工作:个别用户可能希望执行某些程序,比如对 mysql数据库的备份 crontab进行定时任务的设置. 命令参数: l:显示当前用户所有的定时任务

  • linux驱动开发中常用函数copy_from_user open read write详解

    目录 linux驱动常用函数(copy_from_user open read write) 1.open 2.read 3.write 4.copy_to_user 5.copy_from_user linux驱动常用函数(copy_from_user open read write) 1.open 函数定义: int open( const char * pathname, int flags); int open( const char * pathname,int flags, mode

  • Linux中stat函数和stat命令使用详解

    stat函数和stat命令 linux文件里的[inode = index node]解释:要理解inode必须了解磁盘和[目录项],inode实际是连接[目录项]和磁盘的中间物质. 图里的大圈代表硬件的磁盘,里面的小圈代表某个文件存储在磁盘上了. [inode = index node]的node(承载node信息的结构体是:stat,stat的定义在后面 )里面有: 文件大小 文件的最后修改时间 文件的所属用户 文件的权限 硬链接计数(ls -l 显示出来的数字) 块位置:指定文件存储在磁盘

  • java开发MyBatis中常用plus实体类注解符详解

    目录 mybatis-plus常用注解符 1. 表名注解(@TableName) 2. 主键注解(@TableId) 3. 属性注解(@TableField) mybatis-plus常用注解符 1. 表名注解(@TableName) 作用:实体类和数据库中表建立对应关系:如 @TableName("thotset") public class HotsetEntity implements Serializable { private static final long serial

  • Python 中的函数装饰器和闭包详解

    函数装饰器可以被用于增强方法的某些行为,如果想自己实现装饰器,则必须了解闭包的概念. 装饰器的基本概念 装饰器是一个可调用对象,它的参数是另一个函数,称为被装饰函数.装饰器可以修改这个函数再将其返回,也可以将其替换为另一个函数或者可调用对象. 例如:有个名为 decorate 的装饰器: @decorate def target(): print('running target()') 上述代码的写法和以下写法的效果是一样的: def target(): print('running targe

  • JavaScript中匿名函数的用法及优缺点详解

    匿名函数可以有效的保证在页面上写入Javascript,而不会造成全局变量的污染. 这在给一个不是很熟悉的页面增加Javascript时非常有效,也很优美. 一.什么是匿名函数? 在Javascript定义一个函数一般有如下三种方式: 函数关键字(function)语句: function fnMethodName(x){alert(x);} 函数字面量(Function Literals): var fnMethodName = function(x){alert(x);} Function(

  • 基于开发中使用UEditor编辑器的注意事项详解

    最近在一个刚结束的一个项目中使用到了UEditor编辑器,下面总结一下遇到的问题以及使用时需要注意的地方: 1. 使用UEditor插件需要先对其进行路径配置: 在ueditor.config.js文件中 配置 ueditor.config.js文件相对Ueditor文件夹的位置: 2. UEditor的图片上传功能: 此功能需将插件部署至服务器时才可生效: 3. UEditor报错"Cannot set property 'innerHTML' of undefined": 错误的原

  • PHP中filter函数校验数据的方法详解

    介绍PHP中filter函数校验数据的方法详解,PHP过滤器包含两种类型:Validation用来验证验证项是否合法 .Sanitization用来格式化被验证的项目,因此它可能会修改验证项的值,将不合法的字符删除. input_filters_list() 用来列出当前系统所支持的所有过滤器. 复制代码 代码如下: <?php foreach(filter_list() as $id => $filter) {     echo $filter.' '.filter_id($filter).

  • Android源码中常用的接口传参实例详解

    Android源码中常用的接口传参实例详解 把MyCclass中的参数传到MyDclass /*接口传参例子2 * MyCclass.java发送MyDclass.java接收 * 原理和MyAclass.java发送MyDclass.java接收完全一样 * */ public class MyCclass { public void getEditext(GetMyFragmentData myFragmentData){ String edStr="人的生命是有限的,可是为人民服务是无限的

  • python3中sorted函数里cmp参数改变详解

    今天在刷leetcode的时候,对于179题返回最大数,用python2中的sorted(cmp)会很方便,但是在python3中这一参数被取消了,经过查找,发现应该借助functools中的cmp_to_key函数,直接贴代码 import functools def cmp(a,b): if a > b : return -1 elif a < b : return 1 else: return 0 nums = [1,2,3,4,5,6] sorted_nums = sorted(num

  • linux 驱动编写之虚拟字符设备的编写实例详解

     linux 驱动编写 前言: 昨天我们说了一些简单模块编写方法,但是终归没有涉及到设备的编写内容,今天我们就可以了解一下相关方面的内容,并且用一个实例来说明在Linux上面设备是如何编写的.虽然我不是专门做linux驱动的,却也经常收到一些朋友们的来信.在信件中,很多做驱动的朋友对自己的工作不是很满意,认为自己的工作就是把代码拷贝来拷贝去,或者说是改来改去,没有什么技术含量.有这种想法的朋友不在少数,我想这主要还是因为他们对自己的工作缺少了解导致.如果有可能,我们可以问问自己这样几个问题: (

随机推荐