《驱动学习 —— 杂项设备》

1.杂项设备

  杂项设备,本质上就是字符设备驱动,只不过是一个特殊一点的。杂项设备的主设备号,被固定在 10,通过次设备号进行区分设备。杂项设备注册之后,在 /dev/ 目录下就有 name 设备节点,在 /sys/clas/misc 下面,也会自动生成的类信息,因此,一定程度上,比标准的的字符设备驱动简单了。

 

2.杂项设备的注册与注销

注册:

int misc_register(struct miscdevice * misc)

  

注销:

int misc_deregister(struct miscdevice *misc)

  可以看到,基本就是围绕着miscdevice结构体。

struct miscdevice  { 
    int minor; 
    const char *name;      // 名字 
    const struct file_operations *fops;  // 文件操作结构体 
    struct list_head list; 
    struct device *parent; 
    struct device *this_device; 
    const char *nodename; 
    mode_t mode; 
};

  结构体中,name 是注册的名字,以后将会在 /dev 目录下,进行显示的 name,里面最主要的是 struct file_operations ,在注册杂项设备的时候,字符设备的结构体与杂项设备进行绑定, minor 为 MISC_DYNAMIC_MINOR 的时候,miscdevice 核心层会自动寻找一个空闲的次设备号。

 

3.杂项设备驱动编写流程

struct const file_operations xxxx_fops = {
    .unlock_ioctl = xxx_ioctl,
     xxxx
};

    struct miscdevice xxx_dev = {

    .minor = MISC_DYNAMIC_MINOR,

    .name = “xxx”,

    .fops = xxxx_fops
};

static int __init xxx_init()
{
    return misc_register(&xxx_dev );
}

void __exit xxx_exit()
{
    return misc_deregister(&xxx_dev) ;
}

  当调用 misc_register(&xxx_dev ); 的时候,会在 misc_open 的帮助下,实现将 xxx_dev 成为 file 的private_data,也就是 系统会帮助我们实现 file->private_data = xxx_dev。

4.实例

#include <linux/init.h>
#include <linux/module.h>

/*驱动注册的头文件,包含驱动的结构体和注册和卸载的函数*/
#include <linux/platform_device.h>
/*注册杂项设备头文件*/
#include <linux/miscdevice.h>
/*注册设备节点的文件结构体*/
#include <linux/fs.h>

#define DRIVER_NAME "hello_ctl"
#define DEVICE_NAME "hello_ctl123"
MODULE_LICENSE("Dual BSD/GPL");


static long hello_ioctl( struct file *files, unsigned int cmd, unsigned long arg){

	
	printk("cmd is %d,arg is %d\n",cmd,arg);
	return 0;
}

static int hello_release(struct inode *inode, struct file *file){
	printk(KERN_EMERG "hello release\n");
	return 0;
}

static int hello_open(struct inode *inode, struct file *file){
	printk(KERN_EMERG "hello open\n");
	return 0;
}

static struct file_operations hello_ops = {
	.owner = THIS_MODULE,
	.open = hello_open,
	.release = hello_release,
	.unlocked_ioctl = hello_ioctl,
};

static  struct miscdevice hello_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = DEVICE_NAME,
	.fops = &hello_ops,
};


static int hello_probe(struct platform_device *pdv){
	
	printk(KERN_EMERG "\tinitialized\n");
	misc_register(&hello_dev);
	
	return 0;
}

static int hello_remove(struct platform_device *pdv){
	
	printk(KERN_EMERG "\tremove\n");
	misc_deregister(&hello_dev);
	return 0;
}

static void hello_shutdown(struct platform_device *pdv){
	
	;
}

static int hello_suspend(struct platform_device *pdv,pm_message_t pmt){
	
	return 0;
}

static int hello_resume(struct platform_device *pdv){
	
	return 0;
}

struct platform_driver hello_driver = {
	.probe = hello_probe,
	.remove = hello_remove,
	.shutdown = hello_shutdown,
	.suspend = hello_suspend,
	.resume = hello_resume,
	.driver = {
		.name = DRIVER_NAME,
		.owner = THIS_MODULE,
	}
};


static int hello_init(void)
{
	int DriverState;
	
	printk(KERN_EMERG "HELLO WORLD enter!\n");
	DriverState = platform_driver_register(&hello_driver);
	
	printk(KERN_EMERG "\tDriverState is %d\n",DriverState);
	return 0;
}


static void hello_exit(void)
{
	printk(KERN_EMERG "HELLO WORLD exit!\n");
	
	platform_driver_unregister(&hello_driver);	
}

module_init(hello_init);
module_exit(hello_exit);

  https://www.cnblogs.com/qxj511/p/5514271.html

 

posted @ 2020-10-21 11:29  一个不知道干嘛的小萌新  阅读(471)  评论(0编辑  收藏  举报