雜項裝置的原理就是註冊乙個主裝置號,將各種雜類裝置都歸屬於該主裝置號之下。
雜項裝置本質上就是字元裝置。
static int __init misc_init(void)
subsys_initcall(misc_init);//作為子系統新增到核心
//註冊字元裝置的具體實現如下
int register_chrdev(unsigned int major, const char *name,
const struct file_operations *fops)
現在我們已經將主裝置號為10的字元裝置新增到了核心,並註冊了該主裝置號下的256個次裝置號。
那麼是如何將這些次裝置號分配給各雜項裝置並為它們建立裝置節點的呢?讓我們來看乙個看門狗驅動的例子。
每乙個雜項裝置都對應乙個雜項裝置結構體:
struct miscdevice ;
在看門狗驅動中申明並初始化了乙個雜項裝置結構體(在檔案linux/drivers/char/watchdog/s3c2410_wdt.c中)
static struct miscdevice s3c2410wdt_miscdev = ;
操作函式集
s3c2410wdt_fops在檔案s3c2410_wdt.c中申明並實現:
static const struct file_operations s3c2410wdt_fops = ;
該看門狗裝置不僅作為雜項裝置還作為平台裝置而存在。
以下是平台裝置驅動探測函式:
static int s3c2410wdt_probe(struct platform_device *pdev)
。 。。return ret;}
int misc_register(struct miscdevice * misc)}
//如果雜項裝置的裝置號被置為misc_dynamic_minor,則表明該裝置的裝置號要從新自動分配。
if (misc->minor == misc_dynamic_minor)
misc->minor = i;//將在位圖中找到的位置的索引號作為該裝置的次裝置號。}
if (misc->minor < dynamic_minors)
misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);//
將次裝置號對應為置1表明該裝置號已被占用。
//計算裝置號主裝置號為misc_major(10),即是我們先前註冊的字元裝置的主裝置號
dev = mkdev(misc_major, misc->minor);
misc->this_device = device_create(misc_class, misc->parent, dev, null,//建立裝置節點裝置號為dev
"%s", misc->name);
if (is_err(misc->this_device))
list_add(&misc->list, &misc_list);//將該雜項裝置新增到雜項裝置鍊錶。
out:
mutex_unlock(&misc_mtx);
return err;}
到此乙個雜項裝置就被新增到了核心,並為之建立了裝置節點。
所有的雜項裝置都共用乙個主裝置號,但各有各的操作函式集,各雜項裝置被是如何找到自己的操作函式集的呢?
先前我們註冊了乙個字元裝置,裝置名為"misc",主裝置號為misc_major,操作函式集為misc_fops。
該字元裝置管理著主裝置號misc_major下的所有雜項裝置。
操作函式集misc_fops在檔案linux/drivers/char/misc.c中申明並初始化。
static const struct file_operations misc_fops = ;
//該操作函式集只有乙個開啟函式,讓我們看看在裝置開啟時做了哪些工作。
//使用者空間的檔案操作函式直接呼叫的是主裝置號對應的那個裝置的操作函式集中的函式。
//所以使用者空間開啟乙個雜項裝置時直接呼叫的開啟函式必是此處的
misc_open()而不是
//各雜項裝置自己的開啟函式。
static int misc_open(struct inode * inode, struct file * file)
}//如果操作函式集不存在,說明該雜項裝置模組沒有被載入,則請求載入該模組request_module()
//並重新遍歷鍊錶misc_list找出雜項裝置結構體並獲取它的操作函式集。
if (!new_fops)
}if (!new_fops)
goto fail;
}err = 0;
old_fops = file->f_op;//儲存舊的操作函式集,即是操作函式集misc_fops。
file->f_op = new_fops;//讓file->f_op指向新的操作函式集。
if (file->f_op->open)
}fops_put(old_fops);//增加old_fops的引用計數
fail:
mutex_unlock(&misc_mtx);
unlock_kernel();
return err;
}//雜項裝置檔案開啟的主要工作就是尋找次裝置號對應雜項裝置,並獲取該雜項裝置操作函式集,用新的操作函式集中的
//開啟函式實現裝置的真正開啟。
本文**於
在此表示感謝!
雜項裝置的實現
linux核心提供的雜項裝置 miscdevice 具有很強的包容性,在實際開發過程中使用簡單。但是有乙個較大的缺點就是,雜項裝置的次裝置號的分配都是軟體開發者自己隨意分配的,因此移植性較差,有時會造成掛載後無法使用的情況,因此在選擇次裝置號前應當對其核心中雜項裝置號的分配進行查詢後再分配合適的次裝...
雜項裝置(misc device)
雜項裝置也是在嵌入式系統中用得比較多的一種裝置驅動。在 linux 核心的include linux目錄下有miscdevice.h檔案,要把自己定義的misc device從裝置定義在這裡。其實是因為這些字元裝置不符合預先確定的字元裝置範疇,所有這些裝置採用主編號10 一起歸於misc devic...
雜項裝置示例
原理 雜項裝置的misc init函式中,建立了乙個misc class,同時註冊了乙個字元裝置驅動,該字元裝置的主裝置號為10,在呼叫misc register函式去註冊乙個雜項裝置時,最終會建立乙個裝置節點,如果雜項裝置的minor為misc dynamic minor,表示由系統分配乙個次裝置...