Linux里面的misc杂项设备是主设备号为10的驱动设备,它的注册跟使用比较的简单,所以比较适用于功能简单的设备。
它有自己的设备结构体:
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;
};
它在头文件linux/miscdevice.h里面有定义,
其中minor是misc设备的副设备号,misc设备主要依赖minor去区分,如果设置为MISC_DYNAMIC_MINOR则表示系统自动分配未使用的minor
nodename是在/dev下面创建的设备驱动节点,
fops是驱动主体处理函数入口指针
主要使用到的函数有:
int misc_register(struct miscdevice * misc);
int misc_deregister(struct miscdevice *misc);
misc01.c文件
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/miscdevice.h>
- /
- MODULE_LICENSE("Dual BSD/GPL");
- int open_state = 0;
- /
- int misc01_open(struct inode *inode, struct file *filp)
- {
- if (open_state == 0)
- {
- open_state = 1;
- printk("misc01 open!\n");
- return 0;
- }
- printk("misc01 has been open!\n");
- return -1;
- }
- int misc01_release(struct inode *inode, struct file *filp)
- {
- if (open_state == 1)
- {
- open_state = 0;
- printk("misc01 release!\n");
- return 0;
- }
- printk("misc01 has not been open yet!\n");
- return -1;
- }
- ssize_t misc01_read(struct file *filp, char *buf,
- size_t count, loff_t fpos)
- {
- printk("misc01 read!\n");
- return 0;
- }
- ssize_t misc01_write(struct file *filp, char *buf,
- size_t count, loff_t fpos)
- {
- printk("misc01 write!\n");
- return 0;
- }
- int misc01_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
- {
- printk("ioctl is called!\n");
- printk("cmd:%d arg:%d\n", cmd, arg);
- return 0;
- }
- /
- struct file_operations fops =
- {
- .owner = THIS_MODULE,
- .open = misc01_open,
- .release = misc01_release,
- .write = misc01_write,
- .read = misc01_read,
- .ioctl = misc01_ioctl
- };
- struct miscdevice dev =
- {
- .minor = MISC_DYNAMIC_MINOR,
- .fops = &fops,
- .name = "misc01",
- .nodename = "misc01_node"
- };
- int setup_misc01(void)
- {
- return misc_register(&dev);
- }
- /
- static int __init misc01_init(void)
- {
- printk("misc01 init!\n");
- return setup_misc01();
- }
- static void __exit misc01_exit(void)
- {
- printk("misc01 exit!\n");
- misc_deregister(&dev);
- }
- /
- module_init(misc01_init);
- module_exit(misc01_exit);
Makefile文件
- #Makefile
- obj-m := misc01.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:misc01_test.o
- gcc -o $@ {1}lt;
misc01_test.c文件
- #include <stdio.h>
- #include <sys/stat.h>
- #include <sys/ioctl.h>
- #include <fcntl.h>
- #include <errno.h>
- /
- int main(int argc, char **argv)
- {
- int fd;
- fd = open("/dev/misc01_node", O_RDONLY);
- if (fd < 0)
- {
- printf("open /dev/misc01_node failed!\n");
- printf("%s\n", strerror(errno));
- return -1;
- }
- printf("open /dev/misc01_node ok!\n");
- if (ioctl(fd, 6) != 0)
- {
- printf("ioctl failed!\n");
- printf("%s\n", strerror(errno));
- }
- else
- printf("ioctl ok!\n");
- close(fd);
- return 0;
- }