Linux字符设备驱动实例


globalmem

linux 设备驱动开发详解时,字符设备驱动一章,写的测试代码和应用程序,加上自己的操作,对初学者我觉得非常有帮助。

写这篇文章的原因是因为我看了我之前发表的文章,还没有写过字符设备相关的,至于里面提到的结构体的作用,有很多详细的文章说明,我就不做更深的叙述。

代码在github上,点击下面阅读原文可以直达

https://github.com/weiqifa0/globalmem/blob/main/README.md

把这部分放在github上也有好处,后续可以增加删除一些东西,以后自己需要使用的时候也方便许多。

我们讨论字符设备驱动,就有必要知道他的结构体和头文件,像一些后来的封装什么的,大部分还是脱离不了操作这个结构体里面的东西。

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_CDEV_H
#define _LINUX_CDEV_H#include <linux/kobject.h>
#include <linux/kdev_t.h>
#include <linux/list.h>
#include <linux/device.h>struct file_operations;
struct inode;
struct module;struct cdev {struct kobject kobj; /*内嵌kobject结构体,方便以后应用,也会在sys下生成相关设备文件*/struct module *owner;/*所属于的模块,正常就是本模块THIS_MODULE*/const struct file_operations *ops;/*文件的操作结构体,设备也是一个文件*/struct list_head list;/*字符设备的链表头*/dev_t dev;/*设备号*/unsigned int count;
} __randomize_layout;
/*初始化cdev,并建立和file_operation的联系*/
void cdev_init(struct cdev *, const struct file_operations *);
/*申请cdev内存*/
struct cdev *cdev_alloc(void);void cdev_put(struct cdev *p);int cdev_add(struct cdev *, dev_t, unsigned);void cdev_set_parent(struct cdev *p, struct kobject *kobj);
int cdev_device_add(struct cdev *cdev, struct device *dev);
void cdev_device_del(struct cdev *cdev, struct device *dev);void cdev_del(struct cdev *);void cd_forget(struct inode *);#endif


加载内核模块insmod globalmem.ko 错误需要的修改。

insmod: can't insert 'globalmem.ko': Device or resource busy

出错的原因:

模块使用的是静态分配设备号的方式,而这个设备号已经被系统中的其他设备所占用。查看未被占用的设备号,需要到pro/devices下面去查看。

查看设备号的方法:

# cat /proc/devices

编译内核版本

#uname -a
Linux bsp-ubuntu1804 4.15.0-117-generic #118-Ubuntu SMP Fri Sep 4 20:02:41 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

加载模块之后使用lsmod查看模块

weiqifa@bsp-ubuntu1804:~/c/globalmem$ sudo insmod globalmem.koweiqifa@bsp-ubuntu1804:~/c/globalmem$ lsmod |grep global
globalmem              16384  0
weiqifa@bsp-ubuntu1804:~/c/globalmem$weiqifa@bsp-ubuntu1804:~/c/globalmem$ cat /proc/devices |grep global
230 globalmem
weiqifa@bsp-ubuntu1804:~/c/globalmem$

创建设备文件节点

使用mknod创建设备节点的时候,后面跟上的参数需要跟我们在/proc/devices下面看到的对应,也就是我们在驱动里面申请的主设备号。

weiqifa@bsp-ubuntu1804:~/c/globalmem$ sudo mknod /dev/globalmem c 230 0
weiqifa@bsp-ubuntu1804:~/c/globalmem$ ls /dev/globalmem -al
crw-r--r-- 1 root root 230, 0 Dec 22 16:19 /dev/globalmem
weiqifa@bsp-ubuntu1804:~/c/globalmem$

使用命令读写设备文件

Linux 下的 echo 和cat 命令是十分有用,这两个命令可以让在不写代码的情况下就可以完成调试读写设备。

weiqifa@bsp-ubuntu1804:~/c/globalmem$ sudo chmod 777 /dev/globalmem
weiqifa@bsp-ubuntu1804:~/c/globalmem$ sudo echo "linux" > /dev/globalmem
weiqifa@bsp-ubuntu1804:~/c/globalmem$ cat /dev/globalmem
linux
cat: /dev/globalmem: No such device or address
weiqifa@bsp-ubuntu1804:~/c/globalmem$ cat /dev/globalmem
linux
cat: /dev/globalmem: No such device or address
weiqifa@bsp-ubuntu1804:~/c/globalmem$ sudo echo "linuxgdb" > /dev/globalmem
weiqifa@bsp-ubuntu1804:~/c/globalmem$ cat /dev/globalmem
linuxgdb
cat: /dev/globalmem: No such device or address
weiqifa@bsp-ubuntu1804:~/c/globalmem$

通过代码来读写设备文件

代码在下面阅读原文的链接里面。

weiqifa@bsp-ubuntu1804:~/c/globalmem$ gcc app-main.c && ./a.out
str:LINUX,GDB
weiqifa@bsp-ubuntu1804:~/c/globalmem$

使用传入参数设置主设备号

内核模块参数我觉得是一个比较冷门的知识点,冷门的原因是因为我们在做项目的时候很少使用这个参数,但是实际上这个参数非常有用。

我们可以把内核模块当做main函数,main函数是可以接收传参的,内核模块也可以在加载的时候接收传入的参数。

如下是把主设备号传给内核模块,但是需要注意,这个主设备号不能被占用了。


weiqifa@bsp-ubuntu1804:~/c/globalmem$ sudo insmod globalmem.ko globalmem_major=231
weiqifa@bsp-ubuntu1804:~/c/globalmem$ cat /proc/devices |grep globalmem
231 globalmem
weiqifa@bsp-ubuntu1804:~/c/globalmem$

增加自动创建设备节点的驱动文件

每次手动创建设备文件节点总是很麻烦,而且在实际编写设备驱动的时候,不会出现自己手动创建设备节点这种低端的操作。

当然了,聪明的内核提供了接口让我们在注册驱动的时候也把设备文件节点注册上去。

具体代码可以查看globalmem2.c里面的代码。

weiqifa@bsp-ubuntu1804:~/c/globalmem$ chmod 777 globalmem.ko
weiqifa@bsp-ubuntu1804:~/c/globalmem$ sudo insmod globalmem.ko
[sudo] password for weiqifa:
weiqifa@bsp-ubuntu1804:~/c/globalmem$ ls /dev/globalmem
/dev/globalmem
weiqifa@bsp-ubuntu1804:~/c/globalmem$ ls /dev/globalmem -al
crw------- 1 root root 238, 0 Dec 22 17:18 /dev/globalmem
weiqifa@bsp-ubuntu1804:~/c/globalmem$/*修改权限后才可以正常进行独写操作*/
weiqifa@bsp-ubuntu1804:~/c/globalmem$ sudo chmod 777 /dev/globalmem
weiqifa@bsp-ubuntu1804:~/c/globalmem$ gcc app-main.c && ./a.out
write data ok!
str:LINUX,GDB
weiqifa@bsp-ubuntu1804:~/c/globalmem$

使用lseek操作文件位置

具体对应的文件是app-main2.c

weiqifa@bsp-ubuntu1804:~/c/globalmem$ gcc app-main2.c && ./a.out
file ret:0
write data ok! fd:3
str:123456789ABCDEF10111213141516171819201617181920
lseek:1
str:23456789ABCDEF10111213141516171819201617181920
weiqifa@bsp-ubuntu1804:~/c/globalmem$

推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/466745.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

8-[函数]-嵌套函数,匿名函数,高阶函数

1.嵌套函数 &#xff08;1&#xff09;多层函数套用 name "Alex"def change_name():name "Alex2"def change_name2():name "Alex3"print("第3层打印", name)change_name2() # 调用内层函数print("第2层打印", name)chan…

c语言画谢宾斯基三角形

谢宾斯基三角形是一个有意思的图形&#xff0c;&#xff08;英语&#xff1a;Sierpinski triangle&#xff09;是一种分形&#xff0c;由波兰数学家谢尔宾斯基在1915年提出,它是一种典型的自相似集。先画一个三角形&#xff0c;然后呢&#xff0c;取三角形的中点&#xff0c;组…

进程间的通信——无名管道

进程间的通信——无名管道 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 一、进程间的通信 &#xff08;1&#xff09;同主机进程间数据交互机制&#xff1a;无名管道&#xff08;PIPE&#xff09;&#xff0c;有名管道&#xff08;FIFO&#xff09;…

sklearn官网-多分类问题

sklearn实战-乳腺癌细胞数据挖掘&#xff08;博主亲自录制视频&#xff09; https://study.163.com/course/introduction.htm?courseId1005269003&utm_campaigncommission&utm_sourcecp-400000000398149&utm_mediumshare 1.12.6. Multioutput classification Mult…

剖析C语言是如何画出这样的三角形的

哈哈&#xff0c;就是喜欢这些有意思的C语言上篇文章是这样写的c语言画谢宾斯基三角形那篇文章写的有点不直接&#xff0c;然后再查了下资料&#xff0c;看到了下面这些&#xff0c;我觉得解释更加好&#xff0c;这里主要是运用了光栅法&#xff0c;至于光栅法&#xff0c;可以…

NILMTK在Windows下的安装教程

近期&#xff0c;要进行负荷辨识&#xff0c;找到NILMTK安装包&#xff0c;特意将过程记录下来。 &#xff08;1&#xff09;Windows安装 本机已安装了Anaconda&#xff0c;环境是Python3&#xff0c;NILMTK包的项目地址为&#xff1a;https://github.com/nilmtk/nilm_metada…

修改cmdline 把内存改成512MB

#添加cmdline的方式— — 在BoardConfig.mk中修改device/mediateksample/aiv8167sm3_bsp/BoardConfig.mk BOARD_KERNEL_CMDLINE bootopt64S3,32N2,32N2 mem512MB— — 在dts 里面修改kernel-4.4\arch\arm\boot\dts\*.dts / {model "Atmel AT91SAM9M10G45-EK";compa…

NILMTK——经典数据集REDD介绍和使用

配置了NILMTK包的环境之后&#xff0c;想找数据测试一下&#xff0c;在NILMTK官网的API Docs里边发现dataset_converters模块中有内置的数据集处理函数&#xff0c;如图&#xff1a; 将数据转换成HDF文件&#xff0c;这些数据都是比较优秀的&#xff0c;其中&#xff0c;常用的…

上拉电阻的作用

1、介绍使用微控制器&#xff08;MCUs&#xff09; 或任何数字逻辑设备时&#xff0c;上拉电阻器非常常见。本教程将解释何时何地使用上拉电阻器&#xff0c;然后我们将做一个简单的计算&#xff0c;以显示为什么上拉很重要。2、上拉电阻是什么&#xff1f;假设您有一个将一个引…

NILMTK——深扒组合优化(CO)和FHMM细节

前面的博客讲了具体实现&#xff0c;现在深究算法代码实现细节&#xff01;&#xff01;&#xff01; 1.CO (1)关于train 从以下代码可知&#xff0c;CO首先是对各个电器的功率数据做了train&#xff0c;为了了解其原生实现对代码进行了深究&#xff1a; classifiers {CO:…

深圳工资指导价出炉!最高月薪6万!你拖同行后腿了吗?

2020 年只剩下不到一个月了&#xff0c;年初立的 flag 有没有实现呢&#xff1f;我想多数人面临的尴尬是升职、加薪、赢取白富美、走上人生巅峰可能一步都没实现~对比周围混得风生水起的小伙伴感觉自己也不差啥啊&#xff0c;怎么就莫名其妙被甩了八条街&#xff1f;想一探究竟…

NILMTK——因子隐马尔可夫之隐马尔可夫

因子隐马尔可夫(FHMM)由Ghahramani在1997年提出&#xff0c;是一种多链隐马尔可夫模型&#xff0c;适合动态过程时间序列的建模&#xff0c;并具有强大的时序模型的分类能力&#xff0c;特别适合非平稳、再现性差的序列的分析。 1. 马尔可夫链 随机过程的研究对象是随时间演变…

CodeForces 903D Almost Difference

题目描述 Lets denote a function You are given an array aa consisting of nn integers. You have to calculate the sum of d(a_{i},a_{j})d(ai​,aj​) over all pairs (i,j)(i,j) such that 1<i<j<n1<i<j<n . 输入输出格式 输入格式&#xff1a; The fi…

据悉,深圳某工程师沦为C语言笔试枪手

事情是这样的&#xff0c;昨晚晚上&#xff0c;有个网友发消息给我&#xff0c;说他有几道C语言笔试题不会写&#xff0c;所以&#xff0c;就出现了解题的这一幕。文章中&#xff0c;我只讲解了一部分&#xff0c;有一些题目觉得没必要讲&#xff0c;然后我在pdf上做了注释&…

大数据工具使用——安装Hadoop(多台服务器)和Hive、Hbase

1.配置环境版本 资料上传百度云&#xff0c;自取&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1evVp5Zk0_X7VdjKlHGkYCw 提取码&#xff1a;ypti 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 &#xff08;之前安装的是apache版本的Hadoop2.6.4,在启…

[转] 关于 WCF 中数据压缩的几篇文章

原文:http://www.cnblogs.com/jiabao/archive/2007/12/04/982534.html在.net3.0出现以前我们进行分布式开发式有两个选择一个是webservice&#xff0c;另一个是remoting&#xff1b;在早期的项目中&#xff0c;比较喜欢remoting&#xff0c;因为remoting可控性好&#xff0c;也…

聊一聊我自己的从业经历和感悟

嵌入式学习&#xff0c;是一个很枯燥的过程&#xff0c;我记得在学习三极管的时候&#xff0c;我真的对这个东西一点感觉都没有&#xff0c;我知道三极管可以放大&#xff0c;然后电子从一个地方去到了另一个地方&#xff0c;然后就触发了某个开关&#xff0c;就发了大水。然后…

大数据——sqoop操作mysql和hive导出导入数据

1.sqoop安装 &#xff08;1&#xff09;下载CDH版本的sqoop &#xff08;2&#xff09;解压并进行环境配置 环境变量为&#xff1a; export SQOOP_HOME/home/sqoop-1.4.6-cdh5.15.1 export PATH$PATH:$SQOOP_HOME/bin 在sqoop安装目录/conf/下&#xff1a; #新建sqoop-en…

年终了,肿一下

也没有没有跟大家好好唠唠&#xff0c;一年时间过得飞快&#xff0c;我还记得那时候从老家开车来深圳&#xff0c;一路狂奔&#xff0c;在广西入境广东的时候&#xff0c;因为疫情排查&#xff0c;我们在那里堵了3个小时&#xff0c;还因为路途颠簸&#xff0c;车子一起一停&am…

大数据——spark安装部署和python环境配置

需要配置多台服务器&#xff0c;实验环境&#xff1a;master和data两台服务器&#xff0c;已安装好hadoop&#xff0c;可参考前文&#xff01;&#xff01;&#xff01; 1.spark安装 master安装 &#xff08;1&#xff09;下载scala和spark &#xff08;2&#xff09;解压并…