Linux内核学习-字符设备驱动学习(二)
在Linux内核学习-字符设备驱动学习(一)中编写字符设备驱动的一种方法,但是需要手动创建设备节点。
有没有能够自动的创建设备节点的呢?
有!使用class_create()和device_create()函数可以自动创建节点。
class_create : 创建class
class_destroy : 销毁class
class_device_create : 创建device
class_device_destroy : 销毁device
class_create()
-------------------------------------------------
linux-2.6.22/include/linux/device.h
struct class *class_create(struct module *owner, const char *name)
class_create - create a struct class structure
@owner: pointer to the module that is to "own" this struct class
@name: pointer to a string for the name of this class.
在/sys/class/下创建类目录
class_device_create()
-------------------------------------------------
linux-2.6.22/include/linux/device.h
struct class_device *class_device_create(struct class *cls,
struct class_device *parent,
dev_t devt,
struct device *device,
const char *fmt, ...)
class_device_create - creates a class device and registers it with sysfs
@cls: pointer to the struct class that this device should be registered to.
@parent: pointer to the parent struct class_device of this new device, if any.
@devt: the dev_t for the char device to be added.
@device: a pointer to a struct device that is assiociated with this class device.
@fmt: string for the class device's name
在驱动模块初始化函数中实现设备节点的自动创建
设备驱动文件char01.c
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/cdev.h>
- #include <linux/device.h>
- #include <linux/kdev_t.h>
- #include <linux/fs.h>
- /
- int char01_open(struct inode *inode, struct file *filp)
- {
- printk("char01 open!/n");
- return 0;
- }
- int char01_release(struct inode *inode, struct file *filp)
- {
- printk("char01 release!/n");
- return 0;
- }
- ssize_t char01_read(struct file *filp, char *buf,
- size_t count, loff_t *fpos)
- {
- printk("char01 read!/n");
- return 0;
- }
- ssize_t char01_write(struct file *filp, const char *buf,
- size_t count, loff_t *fpos)
- {
- printk("char01 write!/n");
- return 0;
- }
- int char01_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long param)
- {
- printk("char01 ioctl!/n");
- printk("cmd:%d param:%ld/n", cmd, param);
- return 0;
- }
- /
- struct file_operations fops =
- {
- .owner = THIS_MODULE,
- .open = char01_open,
- .release = char01_release,
- .read = char01_read,
- .write = char01_write,
- .ioctl = char01_ioctl
- };
- dev_t devno;
- struct class *pclass;
- struct cdev dev;
- int char01_dev_init(void)
- {
- int result;
- result = alloc_chrdev_region(&devno, 0, 1, "char01");
- if (result != 0)
- {
- printk("alloc_chrdev_region failed!/n");
- goto ERR1;
- }
- cdev_init(&dev, &fops);
- dev.owner = THIS_MODULE;
- dev.ops = &fops;
- result = cdev_add(&dev, devno, 1);
- if (result != 0)
- {
- printk("cdev_add failed!/n");
- goto ERR2;
- }
- pclass = class_create(THIS_MODULE, "char01");
- if (IS_ERR(pclass))
- {
- printk("class_create failed!/n");
- goto ERR3;
- }
- device_create(pclass, NULL, devno, NULL, "char01");
- return 0;
- ERR3:
- cdev_del(&dev);
- ERR2:
- unregister_chrdev_region(devno, 1);
- ERR1:
- return -1;
- }
- /
- /
- /
- static int __init char01_init(void)
- {
- printk("module char01 init!/n");
- return char01_dev_init();
- }
- static void __exit char01_exit(void)
- {
- printk("module char01 exit!/n");
- class_destroy(pclass);
- device_destroy(pclass,devno);
- cdev_del(&dev);
- unregister_chrdev_region(devno, 1);
- }
- /
- MODULE_LICENSE("Dual BSD/GPL");
- MODULE_AUTHOR("Yao.GUET");
- module_init(char01_init);
- module_exit(char01_exit);
- /
#include <linux/init.h> #include <linux/module.h> #include <linux/cdev.h> #include <linux/device.h> #include <linux/kdev_t.h> #include <linux/fs.h> / int char01_open(struct inode *inode, struct file *filp) { printk("char01 open!/n"); return 0; } int char01_release(struct inode *inode, struct file *filp) { printk("char01 release!/n"); return 0; } ssize_t char01_read(struct file *filp, char *buf, size_t count, loff_t *fpos) { printk("char01 read!/n"); return 0; } ssize_t char01_write(struct file *filp, const char *buf, size_t count, loff_t *fpos) { printk("char01 write!/n"); return 0; } int char01_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long param) { printk("char01 ioctl!/n"); printk("cmd:%d param:%ld/n", cmd, param); return 0; } / struct file_operations fops = { .owner = THIS_MODULE, .open = char01_open, .release = char01_release, .read = char01_read, .write = char01_write, .ioctl = char01_ioctl }; dev_t devno; struct class *pclass; struct cdev dev; int char01_dev_init(void) { int result; result = alloc_chrdev_region(&devno, 0, 1, "char01"); if (result != 0) { printk("alloc_chrdev_region failed!/n"); goto ERR1; } cdev_init(&dev, &fops); dev.owner = THIS_MODULE; dev.ops = &fops; result = cdev_add(&dev, devno, 1); if (result != 0) { printk("cdev_add failed!/n"); goto ERR2; } pclass = class_create(THIS_MODULE, "char01"); if (IS_ERR(pclass)) { printk("class_create failed!/n"); goto ERR3; } device_create(pclass, NULL, devno, NULL, "char01"); return 0; ERR3: cdev_del(&dev); ERR2: unregister_chrdev_region(devno, 1); ERR1: return -1; } / / / static int __init char01_init(void) { printk("module char01 init!/n"); return char01_dev_init(); } static void __exit char01_exit(void) { printk("module char01 exit!/n"); class_destroy(pclass); device_destroy(pclass,devno); cdev_del(&dev); unregister_chrdev_region(devno, 1); } / MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Yao.GUET"); module_init(char01_init); module_exit(char01_exit); /
测试文件char01_test.c
- #include <stdio.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <sys/stat.h>
- /
- int main(int argc, char *argv)
- {
- int fd;
- fd = open("/dev/char01", O_RDWR);
- if (fd<0)
- {
- printf("open /dev/char01 failed!/n");
- printf("%s/n", strerror(errno));
- return -1;
- }
- printf("open /dev/char01 ok!/n");
- ioctl(fd, 0);
- close(fd);
- }
#include <stdio.h> #include <fcntl.h> #include <errno.h> #include <sys/stat.h> / int main(int argc, char *argv) { int fd; fd = open("/dev/char01", O_RDWR); if (fd<0) { printf("open /dev/char01 failed!/n"); printf("%s/n", strerror(errno)); return -1; } printf("open /dev/char01 ok!/n"); ioctl(fd, 0); close(fd); }
Makefile文件:
- obj-m := char01.o
- PWD := $(shell pwd)
- K_DIR := /lib/modules/$(shell uname -r)/build
- all:
- $(MAKE) -C $(K_DIR) M=$(PWD) modules
- clean:
- $(MAKE) -C $(K_DIR) M=$(PWD) clean
- test:char01_test.o
- gcc -o $@ $^
Linux内核学习-字符设备驱动学习(二)相关推荐
- [转载]Linux内核大讲堂 (一) 设备驱动的基石驱动模型(1)
[转载]Linux内核大讲堂 (一) 设备驱动的基石驱动模型(1) 2011年09月13日 可能把驱动模型放在第一章讲会会有点难度,但是只要能跨过这道坎,后面就会轻松很多,驱动模型是整个linux设备 ...
- Linux内核部件分析 设备驱动模型之driver ---mark 详细
Linux内核部件分析 设备驱动模型之driver 转载:https://www.linuxidc.com/Linux/2011-10/44627p7.htm 上节我们分析设备驱动模型中的device ...
- linux内核创建字符节点,Tiny6410学习ing—(四)、嵌入式Linux内核驱动进阶—(7)、高级字符设备驱动(自动创建节点)—#931...
按照国嵌的视频教程上来说的,最后就是-自动创建设备文件! 其实我感觉以前完全可以直接是手动创建了设备文件,然后就可以直接讲述自动创建设备文件,为啥非要拖到最后来讲述,我也就不清楚了!! 不管了,写完收 ...
- 驱动学习----字符设备驱动框架
字符设备驱动框架 1.字符设备驱动简介 2.file_operations 3.驱动模块的加载和卸载 4.字符设备的注册与注销 5.实现设备具体操作函数 6.添加LICENSE和作者信息 7.linu ...
- linux内核的块设备驱动框架详解
1.块设备和字符设备的差异 (1)块设备只能以块为单位接受输入和返回输出,而字符设备则以字节为单位.大多数设备是字符设备,因为它们不需要缓冲而且不以固定块大小进行操作; (2)块设备对于 I/O 请求 ...
- linux下的字符设备驱动
Linux字符设备驱动程序的一个简单示例 一.开发环境: 主 机:VMWare--Fedora 9 开发板:友善之臂mini2440--256MB Nandflash 编译器:arm-linux-g ...
- Linux内核大讲堂之设备驱动的基石驱动模型(1)
转自 http://blog.csdn.net/gqb_driver/article/details/8449588 转自:无为和尚的Linux内核大讲堂系列,并对个别地方进行了补充更正(见标红处). ...
- Linux内核大讲堂 (一) 设备驱动的基石驱动模型(1)
可能把驱动模型放在第一章讲会会有点难度,但是只要能跨过这道坎,后面就会轻松很多,驱动模型是整个linux设备驱动的基石.大部分人把驱动模型叫做设备模型,但是我查了linux的帮助文档,就是在下载源码路 ...
- 【转】Linux内核大讲堂 (一) 设备驱动的基石驱动模型(1)
原文传送门http://blog.csdn.net/z2007b/archive/2011/05/03/6388753.aspx 可能把驱动模型放在第一章讲会会有点难度,但是只要能跨过这道坎,后面就会 ...
最新文章
- 用sqlplus为oracle创建用户和表空间
- 发那科机器人注油_如何给发那科机器人做三年保养?干货!
- oracle TNS: 协议适配器错误 解决办法
- java环境变量中classpath是必须配置吗
- C语言其实不难,只是你没有找对方法!
- dnf上海2服务器维护,DNF上海2出现大面积盗号并迅速蔓延请注意
- PostgreSQL视图使用特殊名称作字段时的处理
- python中的进程(二)
- ubuntu mysql双主热备配置_mysql学习:mysql双主热备+lvs+keepalived配置
- 【集合论】容斥原理 ( 包含排斥原理 | 示例 )
- 单阶段人体姿态估计解决方案
- GStreamer 简化 Linux 多媒体开发
- 第十七章 - 垃圾回收器
- 宝华计算机维修,唐山市路北区宝华计算机维修服务
- Flashback 技术
- linux忘记root密码怎么办——重置root密码的四种方法
- android中留言板功能,Android -- 留言板的简单实现
- 广告VS电商 抖音快手的变现之争
- [2018-5-4]BNUZ你们还差得远呢
- 分布式计算,大型网站技术架构:核心原理与案例分析
热门文章
- pytorch 保存、读取 tensor 数据
- python打印进程号与线程号
- 博弈树α-β剪枝搜索学习参考资料
- Mac os更新系统后安装scrapy报错error: command ‘xcrun‘ failed with exit status 1
- python发送文件_python:socket传输大文件
- LeetCode开心刷题二十七天——51. N-Queens
- ios7之后的一些更改
- 手写分页 个人感觉还能优化,甚至抽象出来,需要高手讲解
- org.hibernate.HibernateException: 'hibernate.dialect' must be set when no Connection avalable
- Android中URI的格式