【迅为iTop4412学习笔记】20.生成设备节点(未完成)

声明

以下都是我刚开始看驱动视频的个人强行解读,如果有误请指出,共同进步。

本节目标

注册字符类设备


仅上代码,此处以后再写。

实例
https://blog.csdn.net/qq_28992301/article/details/52343585

超有用
https://www.cnblogs.com/chen-farsight/p/6155518.html

查看设备类
ls /sys/class
设备类mryang_ascdev

查看设备
cat /proc/devices
设备mryang_ascdev

查看设备节点
ls /dev
mryang_ascdev0和mryang_ascdev1

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/slab.h>
#include <linux/device.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("MrYang");

#define DEV_MAJOR		0				/* 默认主设备号(为0则linux自动分配可用号码) */
#define DEV_MINOR		0				/* 默认次设备号(为0则linux自动分配可用号码) */
#define DEV_MINOR_NUM	2				/* 要注册的次设备的数量 */
#define DEV_NAME		"mryang_ascdev"	/* 设备名 */

// 初始化主次设备号
int device_major = DEV_MAJOR;
int device_minor = DEV_MINOR;

// cdev结构体
struct cdev *my_cdev_ptr;

// 文件操作结构体
struct file_operations my_fops = {
	.owner = THIS_MODULE,
};

struct class *myclass;

static int mryang_init(void)
{
	int ret, i;
	dev_t mryang_dev;
	
	printk(KERN_EMERG "HELLO MrYang\n");
	
	// 动态申请设备号
	ret = alloc_chrdev_region(&mryang_dev, device_minor, DEV_MINOR_NUM, DEV_NAME);
	if(ret < 0)
		printk(KERN_EMERG "failed!\n");
	else
		printk(KERN_EMERG "success!\n");
	
	// 提取主、次设备号
	device_major = MAJOR(mryang_dev);
	device_minor = MINOR(mryang_dev);
	printk(KERN_EMERG "major: %d, minor: %d\n", device_major, device_minor);
	
	// 注册设备类
	myclass = class_create(THIS_MODULE, DEV_NAME);
	
	
	// 静态申请内存大小(设备数*结构体就是大小)
	my_cdev_ptr = kmalloc( DEV_MINOR_NUM * sizeof(struct cdev), GFP_KERNEL);
	if(my_cdev_ptr==NULL)
	{
		printk(KERN_EMERG "kmalloc failed!\n");
		return -1;
	}
	
	// memset(my_cdev_ptr, 0, DEV_MINOR_NUM * sizeof( struct cdev ) );		// 可省略,init会自动memset,看源码
	
	for(i=0;i<DEV_MINOR_NUM;i++)
	{
		// 初始化cdev,并绑定文件操作函数
		cdev_init(&my_cdev_ptr[i], &my_fops);
		// 赋值
		my_cdev_ptr[i].owner = THIS_MODULE;
		my_cdev_ptr[i].ops = &my_fops;
		// 注册到系统
		ret = cdev_add(&my_cdev_ptr[i], MKDEV(device_major, device_minor+i), 1);
		if( ret < 0 )
			printk(KERN_EMERG "cdev_add %d failed!\n", i);
		else
			printk(KERN_EMERG "cdev_add %d success!\n", i);
		/* 创建设备节点 */
		device_create(myclass,NULL, MKDEV(device_major, device_minor+i), NULL, DEV_NAME"%d",i);
	}
	
	return 0;
}

static void mryang_exit(void)
{
	int i;
	dev_t mryang_dev;
	// 设备号
	mryang_dev = MKDEV(device_major, device_minor);

	for(i=0;i<DEV_MINOR_NUM;i++)
	{	// 注销字符设备
		cdev_del(&my_cdev_ptr[i]);
		device_destroy(myclass,MKDEV(device_major, device_minor+i));
	}
	// 注销内存
	kfree(my_cdev_ptr);
	// 注销设备号
	unregister_chrdev_region(mryang_dev, DEV_MINOR_NUM);
	
	printk(KERN_EMERG "Bye MrYang\n");
}

module_init(mryang_init);
module_exit(mryang_exit);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值