參考資料:LDD3,精通Linux設備驅動程序
關鍵字: 圖解雜設備驅動程序
Linux版本:3.3
混雜驅動程序是那些簡單的字符驅動程序,它們擁有一些相同的特性。內核將這些共同性抽象至一個API中,這簡化了這些驅動程序初始化的方式。所有的混雜設備都被分配一個主設備號10,但每個設備可選擇一個單獨的次設備號。
之前的字符設備的註冊需要使用以下幾個API:
- 通過alloc_chrdev_region()及相關函數分配主/次設備號。
- 使用device_create()創建/dev和/sys節點。
- 使用cdev_init()和cdev_add()將自身註冊爲字符驅動程序。
而混雜設備只需要使用一個API即可: misc_register(),內核已經幫我們做好了一切。
使用MISC_DYNAMIC_MINOR內核會自動分配一個次設備號,但主設備號是固定爲10的。
簡單的雜設備驅動程序實例
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
static int myopen(struct inode *inode, struct file *filp)
{
printk("myopen!\n");
return 0;
}
static int myrelease(struct inode *inode, struct file *filp)
{
printk("myrelease\n");
return 0;
}
static int myread(struct file *filp, const char __user *buf, size_t len, loff_t *loff)
{
printk("myread\n");
return 0;
}
static int mywrite(struct file *filp, const char __user *buf, size_t len, loff_t *loff)
{
printk("mywrite!\n");
return 0;
}
struct file_operations fops = {
.owner = THIS_MODULE,
.open = myopen,
.release = myrelease,
.read = myread,
.write = mywrite,
};
/*
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;
umode_t mode;
};
*/
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR, //動態分配次設備號
.name = "my_misc",
.fops = &fops, //將fops和設備關聯
};
static int __init test_init(void)
{
int res;
printk("hello kernel!\n");
/**
* int misc_register(struct miscdevice *misc)
*/
res = misc_register(&misc);
return res;
}
static void __exit test_exit(void)
{
printk("exit kernel!\n");
misc_deregister(&misc);
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("HGL");
insmod test.ko後就可以在相應的目錄下找到相應的文件了。
misc_register分析流程圖
這裏就不貼代碼了.基於linux kernel3.3。