字符设备: IO传输过程中以字符为单位,没有缓冲,比如:i2c spi
块设备: IO 传输过程中以块为单位。和存储有关的,TF卡 硬盘
网络设备:以socket 套接字来访问;
杂项设备是字符设备的一种,自动生成设备节点,降低了开发难度
cat /proc/misc 可以查看杂项设备
杂项设备的主设备号是相同的 10,次设备号是不同的,主设备号相同可以节省内核资源
杂项设备描述
杂项设备使用结构体 miscdevice进行描述,定义在: include/linux/miscdevice.h
cpp
Struct miscdevice{
Int minor;
Const char *name;
Const struct file_operations *fops;
Struct list_head list;
Struct device *parent;
Struct device *this_device;
Const struct attribute_grop **groups;
Const char *nodename;
Umode_t mode;
}
相关函数
注册杂项设备:
extern int misc_register(struct miscdevice *misc);
注销杂项设备:
extern int misc_deregister(struct miscdevice *misc);
例程:
cpp
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/modulepram.h>
#include <linux/kdev_t.h>
#include <linux/miscdevice.h>
#include <linux/asm-generic/uaccess.h>
static int major;
static int minor;
module_param(major,int,S_IRUGO);
MODULE_PARAM_DESC(major,"e.g:major=1");
module_param(minor,int,S_IRUGO);
MODULE_PARAM_DESC(minor,"e.g:minor=1");
static struct cdev cdev_test;
struct class *class;
struct device *device;
static int misc_test_open(struct inode *node, struct file *file)
{
printk("misc_test_open \n");
return 0;
}
static int misc_test_release(struct inode *node, struct file *file)
{
printk("misc_test_release \n");
return 0;
}
static ssize_t misc_test_read (struct file *file, char __user *buf, size_t size, loff_t *off)
{
char kbuf[64]="123456hello";
copy_to_user(buf,kbuf,strlen(kbuf));
printk("misc_test_read \n");
}
static ssize_t misc_test_write (struct file *file, const char __user *buf, size_t size, loff_t *off)
{
char kbuf[64];
copy_from_user(kbuf,buf,size);
printk("write buf[%s]\n",kbuf);
printk("misc_test_write\n");
}
struct file_operations misc_test_ops={
.owner=THIS_MODULE,
.open=misc_test_open,
.release=misc_test_release,
.read=misc_test_read,
.write=misc_test_write,
.ioctl=misc_test_ioctl
};
struct miscdevice misc_dev={
.minor= MISC_DYNAMIC_MINOR,
.name=test,
.fops=&misc_test_ops
};
static int misc_init(void)
{
int ret;
ret = misc_register(&misc_dev);
if(ret <0 )
printk(" misc_register err\n");
printk("cdv init\n");
return 0;
}
static void misc_exit(void)
{
misc_deregister(&misc_dev);
printk("cdv exit\n");
return 0;
}
module_init(misc_init);
module_exit(misc_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("SONG");
MODULE_VERSION("v1.0");