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檔案
#Makefileobj-m:=misc01.oPWD:=$(shell pwd)K_DIR:=/lib/modules/$(shell uname -r)/buildall:$(MAKE) -C $(K_DIR) M=$(PWD) modulesclean:$(MAKE) -C $(K_DIR) M=$(PWD) cleantest:misc01_test.ogcc -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;}