Preface

前面对linux设备驱动的相应知识点进行了总结,现在进入实践阶段!

linux设备驱动入门篇》:http://infohacker.blog.51cto.com/6751239/1218461

linux设备驱动扫盲篇》:http://infohacker.blog.51cto.com/6751239/1218747

fedora下的字符设备驱动开发》:http://infohacker.blog.51cto.com/6751239/1155153


开发一个基本的字符设备驱动

在Linux内核驱动中,字符设备是最基本的设备驱动。

字符设备包括了设备最基本的操作,如打开设备、关闭设备、I/O控制等。

功能:❶建立一个名为GlobalChar的虚拟设备,设备内部只有一个全局变量供用户操作。设备提供了❷读函数读取全局变量的值并且返回给用户,❸写函数把用户设定的值写入全局变量。

代码如下:

//GlobalCharDev.c
#include <linux/fs.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("mystery");
#define DEV_NAME "GlobalChar"
static ssize_t GlobalRead(struct file *, char *, size_t, loff_t *);
static ssize_t GlobalWrite(struct file *, const char *, size_t, loff_t *);static int char_major = 0;
static int GlobalData = 0;  // "GlobalData" 设备的全局变量
//初始化字符设备驱动的file_operations结构体
static const struct file_operations globalchar_fops =
{.read = GlobalRead,.write = GlobalWrite
}; //注意分号啊!!!
//模块初始化函数
static int __init GlobalChar_init(void)
{int ret;ret = register_chrdev(char_major, DEV_NAME, &globalchar_fops);  //注册设备驱动if (ret < 0){printk(KERN_ALERT "GlobalChar Reg Fail ! \n");}else{printk(KERN_ALERT "GlobalChar Reg Success ! \n");char_major = ret;printk(KERN_ALTER "Major = %d \n",char_major);}return ret;
}
//模块卸载函数
static void __exit GlobalChar_exit(void)
{unregister_chrdev(char_major, DEV_NAME);    //注销设备驱动return;
}
//设备驱动读函数
static ssize_t GlobalRead(struct file *filp, char *buf, size_t len, loff_t *off)
{if(copy_to_user(buf, &GlobalData, sizeof(int))) //从内核空间复制GlobalData到用户空间{return -EFAULT;}return sizeof(int);
}
//设备驱动写函数
static ssize_t GlobalWrite(struct file *filp, const char *buf, size_t len, loff_t *off)
{if(copy_from_user(&GlobalData, buf, sizeof(int)))   //从用户空间复制GlobalData到内核空间{return -EFAULT;}return sizeof(int);
}
module_init(GlobalChar_init);
module_exit(GlobalChar_exit);

在内核中操作数据要区分数据的来源,对于用户空间的数据要使用copy_from_user()函数复制,使用copy_to_user()函数回写,不能直接操作用户空间的数据,否则会产生内存访问错误。

②编写Makefile

obj-m := GlobalCharDev.o
KDIR := /lib/modules/$(shell uname -r)/build
SRCPWD := $(shell pwd)
all:make -C $(KDIR) M=$(SRCPWD) modules

③编译并加载内核模块

④查看内核分配的主设备号

⑤使用mknod命令建立一个设备文件

mknod命令使用-m参数指定GlobalChar设备可以被所有用户访问。

249即上面查询的主设备号。

到这里,我们就已经正确地添加了一个字符设备到内核,下面需要测试一下驱动程序能否正常工作。


测试字符设备驱动

为了测试编写的字符设备是否能正常工作,我们编写一个应用程序测试一下能否正常读写字符设备。

测试代码:

//GlobalCharTest.c
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#define DEV_NAME "/dev/GlobalChar"
int main()
{int fd,num;fd = open(DEV_NAME, O_RDWR, S_IRUSR | S_IWUSR); //打开设备文件if (fd < 0){printf("Open Deivece Fail ! \n");return -1;}read(fd, &num, sizeof(int));printf("The GlobalChar is %d \n", num); //获取当前设备数值printf("Please input a number written to GlobalChar: ");scanf("%d", &num);write(fd, &num, sizeof(int));   //写入新的数值read(fd, &num, sizeof(int));printf("The GlobalChar is %d \n", num); //重新读取设备数值close(fd);return 0;
}

程序首先使用open函数打开设备文件,然后使用read()函数读取字符设备的值,open()系统调用最终会被解释为字符设备注册的read调用。

   测试结果:

从程序输出结果来看,最初从设备得到的数值是0,输入520后写入到字符设备,重新读出的数值也是520,与设置相同,表示设备驱动程序功能正确。


总结

linux字符设备驱动也不过如此嘛,嘿嘿,虽然只实现了read和write两个函数,不过其它函数也大同小异。

重点:实践再实践!!!

本文出自 “成鹏致远” 博客,请务必保留此出处http://infohacker.blog.51cto.com/6751239/1219217

转载于:https://www.cnblogs.com/lcw/p/3159384.html

【驱动】linux设备驱动·字符设备驱动开发相关推荐

  1. linux 设备驱动(一)——字符设备驱动

    linux 设备驱动(一)--字符设备驱动 一.概述 1.1 设备驱动介绍 1.2. 设备结构 1.2.1 设备号 1.2.2 驱动层次 1.3 设备驱动对外接口 1.4 设备驱动特点 二.字符设备驱 ...

  2. Linux驱动框架与杂项字符设备框架介绍

    1. Linux下驱动框架介绍 1.1 驱动框架分类 Linux下驱动框架分为3大类型: 字符设备 --------- 块设备 存储设备 SD 硬盘 网络设备 网卡 无线 有线 字符设备和块设备都会生 ...

  3. 【笔试/面试】—— Linux(块设备与字符设备/cron 和 crontab)

    块设备与字符设备 是一种具有一定结构的随机存取设备,对这种设备的读写是按块进行的,他使用缓冲区来(先)存放暂时的数据,待条件成熟后,从缓存一次性写入设备或从设备中一次性读出放入到缓冲区,如磁盘和文件系 ...

  4. 你知道什么是 块设备 和 字符设备 吗?以及如何查看 块设备文件 和 字符设备文件 ?

    关于块设备 和 字符设备 介绍: 系统中能够随机(不需要按顺序)访问固定大小数据片(chunks)的设备被称作块设备,这些数据片就称作块.                 最常见的块设备是硬盘,除此以 ...

  5. I/O输入输出——I/O设备(块设备与字符设备)

    无论是块设备还是字符设备,都是属于IO硬件,在整个硬件到软件层之前的了解,有助于我们理解. I/O设备 块设备 是一种具有一定结构的随机存取设备,对这种设备的读写是按块进行的,他使用缓冲区来存放暂时的 ...

  6. linux设备模型 字符设备,Linux 字符设备驱动模型之框架解说

    一.软件操作硬件设备模型 在进行嵌入式开发的过程中,在常做的事情就是驱动配置硬件设 备,然后根据功能需求使用硬件设备,实现功能的逻辑.如下图为其 相互之间的关系. 如上图所示: 驱动程序:主要作为操作 ...

  7. linux下的字符设备驱动

    Linux字符设备驱动程序的一个简单示例 一.开发环境: 主  机:VMWare--Fedora 9 开发板:友善之臂mini2440--256MB Nandflash 编译器:arm-linux-g ...

  8. Linux:驱动之自动创建字符设备的设备文件(未完)

    自动创建字符设备的设备文件 目前尚不是最终版本,还望有心人自己学习的时候,把自己整合的知识点相关的答案也好问题也好,或者实践过程中的一些操作截图,再或者其他的一些想要分享材料发给笔者邮箱:uestc_ ...

  9. linux驱动编写(虚拟字符设备编写)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 昨天我们说了一些简单模块编写方法,但是终归没有涉及到设备的编写内容,今天我们就可以了解一下相关 ...

  10. linux如何查看硬件驱动,linux查看硬件信息及驱动设备相关整理

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 联系我登录 首页 业界新闻 技术文章 资源分享 微语 linux查看硬件信息及驱动设备相关整理[转] 蓝猫 发布于:2014-5-30 17:48 分类: ...

最新文章

  1. json数组 js html标签,js定义json对象数组 json 数组也是数组 //
  2. 网络安全模型_基于TCM的网络安全访问模型
  3. 变量初始化赋值_java数组的定义及初始化
  4. PostgreSQL的高可用与数据复制方案
  5. 動態語句的使用方法(exec/sp_executesql)
  6. github和git@osc提交问题
  7. 【XSY2469】graph 分治 并查集
  8. 0ctf2017-babyheap调试记录fastbin-attack
  9. codeforces 385C Bear and Prime Numbers
  10. 恋恋风辰 对于redis底层框架的理解(一)
  11. LaTeX 修改中文摘要名字
  12. PHP学习九--会话控制session和cookie
  13. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(6)-Unity 2.x依赖注入by运行时注入[附源码]...
  14. Axure RP 9 下载安装
  15. U盘装机大师安装GHOST WIN10系统
  16. 1218. 最长定差子序列【我亦无他唯手熟尔】
  17. hdu4114.Disney's FastPass
  18. HTML+CSS注册页面案例【Java源代码】
  19. Java位运算,常见的位运算
  20. 欢迎光临Simon个人空间

热门文章

  1. linux network io,Linux network I/O
  2. 在群晖synoboot.img引导文件中加入网卡驱动_群晖DS1819+使用记录
  3. Tensorflow2.0数据和部署(一)——基于浏览器的模型与TensorFlow.js
  4. 基于CNN实现对摄像头捕捉的人脸进行性别和年龄的预测
  5. 深度神经网络基本问题的原理详细分析和推导
  6. 关机时无人照管更新正在运行_路辉物流设备:无人化分拣作业驱动物流业降本增效...
  7. 用newlisp管理windows下的nginx
  8. Windows 8 Directx 开发学习笔记(十四)使用几何着色器实现三角形细分
  9. 《阿里巴巴中国总裁叶朋:B2B从1.0向2.0的升级》阅读整理
  10. glMatrixMode()函数