当前位置:网站首页>自动生成设备节点
自动生成设备节点
2022-08-09 16:16:00 【酸菜。】
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/fs.h>
#include<linux/slab.h>
#include<linux/timer.h>
#include<linux/sched.h>
#include<linux/list.h>
#include<linux/interrupt.h>
#include<linux/cdev.h> //cdev_init() cdev_add() cdev_del()
#include<linux/types.h> //dev_t
#include<linux/kdev_t.h> //有两个宏获取主设备号和次设备号
MODULE_AUTHOR("Tan xujia");
MODULE_LICENSE("Dual BSD/GPL");
dev_t c_devt; //设备的主次设备号
/*定义一个结构体,包含了cdev,类似与继承,把这个设备文件的属性给继承过来*/
struct char_dev {
struct cdev c_dev;
char c;
};
/*定义一个变量*/
struct char_dev *cdev_p;
/*设备的操作方法*/
int
char_open(struct inode *inode, struct file *filp)
{
printk("char_open, %d, %d\n", iminor(inode), MINOR(inode->i_cdev->dev));
return 0;
}
ssize_t
char_read(struct file *filp, char __user *buf, size_t count, loff_t *fpos)
{
printk("char_read\n");
return 0;
}
ssize_t
char_write(struct file *filp, const char __user *buf, size_t count, loff_t *fpos)
{
printk("char_write\n");
return count;
}
int
char_release(struct inode *inode, struct file *filp)
{
printk("char_release\n");
return 0;
}
struct file_operations char_fops = {
.owner = THIS_MODULE,
.read = char_read,
.write = char_write,
.open = char_open,
.release = char_release,
};
struct class *cdev_class;
static
int __init hello_init (void)
{
printk("hello_init\n");
int ret = 0, index = 0;
ret = alloc_chrdev_region(&c_devt, 10, 2, "char_dev");
if(ret)
printk("alloc_chrdev_region fail\n");
printk("major = %d, minor = %d\n", MAJOR(c_devt), MINOR(c_devt));
cdev_p = kzalloc(sizeof(struct char_dev) * 2, GFP_KERNEL);
if(!cdev_p)
printk("alloc fail\n");
for(index = 0; index < 2; index++) {
cdev_init(&cdev_p[index].c_dev, &char_fops);
cdev_p[index].c_dev.owner = THIS_MODULE;
ret = cdev_add(&cdev_p[index].c_dev,
MKDEV(MAJOR(c_devt), MINOR(c_devt) + index), 1);
if(ret)
printk("cdev_add fail\n");
}
/*根据以下api替代mknod生成设备节点*/
cdev_class = class_create(THIS_MODULE, "c_dev");
if(!cdev_class)
printk("class_create fail\n");
for(index = 0; index < 2; index++) {
device_create(cdev_class, NULL,
MKDEV(MAJOR(c_devt), MINOR(c_devt) + index),
NULL, "c_dev%d", index);
}
return 0;
}
static
void __exit hello_exit (void)
{
printk("hello_exit\n");
int index = 0;
for(index = 0; index < 2; index++) {
device_destory(cdev_class,
MKDEV(MAJOR(c_devt), MINOR(c_devt) + index));
}
class_destory(cdev_class);
for(index = 0; index < 2; index++) {
cdev_del(&cdev_p[index].c_dev);
}
kfree(cdev_p);
unregister_chrdev_region(c_devt, 2);
}
module_init(hello_init);
module_exit(hello_exit);
/* MAJOR(dev_t dev) //获取主设备号 MINOR(dev_t dev) //获取次设备号 MKDEV(int major, int minor) //合成设备号 设备号的分配: int register_chrdev_region(dev_t first, unsigned int count, char *name) int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name) 设备号的释放: void unregister_chrdev_region(dev_t first, unsigned int count) */
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
obj-m :=cdev_register_node.o
all:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.* .tmp_versions *.mod *.order *.symvers *.dwo
利用cat和echo测试可以看到相关的函数流程执行,使用dmesg可以看到相关的打印信息。
边栏推荐
猜你喜欢
随机推荐
OpenCV image transformation - histogram equalization
Use SourceTree to add SSH public key and clone the code cloud project (note finishing)
期货开户交易所的手续费和查询方法
重谈联想5G编码投票事件
What is control board custom development?
WeChat developer tools error, prompt did not find the entrance to the app. The json file
Installation and use of Lombok plugin in IDEA
如何让button中的内容分两行显示
微软 .NET Core 3.1 年底将结束支持,请升级到.NET 6
元宇宙虚拟场景互动获得生活、工作、学习新鲜体验
《.NET物联网从零开始》系列
【燃】是时候展现真正的实力了!一文看懂2022华为开发者大赛技术亮点
嵌入式软件开发的特点和流程
【.NET 6】开发minimal api以及依赖注入的实现和代码演示
微信开发者工具报错,提示 未找到入口 app.json 文件
对象模型-虚指针虚表
数据可视化的类别及其重要性
Account opening requirements and exemptions for special futures such as crude oil
The article details of the qiucode.cn website realize the code block can be copied by clicking the button
[ Kitex Source Code Interpretation ] Request to retry