1:什么是misc驅(qū)動(dòng)模型?
2:為什么要有misc驅(qū)動(dòng)模型?
3:misc驅(qū)動(dòng)模型的代碼實(shí)現(xiàn)
4:misc驅(qū)動(dòng)模型實(shí)戰(zhàn)
參考:
http://blog.csdn.net/yicao821/article/details/6785738
http://www.thinksaas.cn/topics/0/507/507168.html
http://www.cnblogs.com/fellow1988/p/6235080.html
https://www.zhihu.com/question/21508904
http://www.cnblogs.com/snake-hand/p/3212483.html
http://blog.csdn.net/chenlong12580/article/details/7339127
--------------------------------------------------------------------------------------------------------------------------------------------------------------
1:什么是misc驅(qū)動(dòng)模型
Linux包含了許多的設(shè)備驅(qū)動(dòng)類型,而不管分類有多細(xì),總會(huì)有些漏網(wǎng)的,這就是我們經(jīng)常說(shuō)到的“其他的”等等。
在Linux里面,把無(wú)法歸類的五花八門的設(shè)備定義為混雜設(shè)備(用miscdevice結(jié)構(gòu)體來(lái)描述)。Linux/內(nèi)核所提供的miscdevice有很強(qiáng)的包容性。如NVRAM,看門狗,DS1286等實(shí)時(shí)時(shí)鐘,字符LCD,AMD 768隨機(jī)數(shù)發(fā)生器。
miscdevice共享一個(gè)主設(shè)備號(hào)MISC_MAJOR(10),但此設(shè)備號(hào)不同,所有的miscdevice設(shè)備形成一個(gè)鏈表,對(duì)設(shè)備訪問(wèn)時(shí)內(nèi)核根據(jù)次設(shè)備號(hào)查找對(duì)應(yīng)的 miscdevice設(shè)備,然后調(diào)用其中的file_operations結(jié)構(gòu)體中注冊(cè)的文件操作接口進(jìn)程操作。
2:為什么要有misc驅(qū)動(dòng)模型
第一,節(jié)省主設(shè)備號(hào):
使用普通字符設(shè)備,不管該驅(qū)動(dòng)的主設(shè)備號(hào)是靜態(tài)還是動(dòng)態(tài)分配,都會(huì)消耗一個(gè)主設(shè)備號(hào),這太浪費(fèi)了。而且如果你的這個(gè)驅(qū)動(dòng)最終會(huì)提交到內(nèi)核主線版本上的話,需要申請(qǐng)一個(gè)專門的主設(shè)備號(hào),這也麻煩。
如果使用misc驅(qū)動(dòng)的話就好多了。因?yàn)閮?nèi)核中已經(jīng)為misc驅(qū)動(dòng)分配了一個(gè)主設(shè)備號(hào)。當(dāng)系統(tǒng)中擁有多個(gè)misc設(shè)備驅(qū)動(dòng)時(shí),那么它們的主設(shè)備號(hào)相同,而用子設(shè)備號(hào)來(lái)區(qū)分它們。
第二,使用簡(jiǎn)單:
有時(shí)候驅(qū)動(dòng)開發(fā)人員需要開發(fā)一個(gè)功能較簡(jiǎn)單的字符設(shè)備驅(qū)動(dòng),導(dǎo)出接口讓用戶空間程序方便地控制硬件,只需要使用misc子系統(tǒng)提供的接口即可快速地創(chuàng)建一個(gè)misc設(shè)備驅(qū)動(dòng)。
當(dāng)使用普通的字符設(shè)備驅(qū)動(dòng)時(shí),如果開發(fā)人員需要導(dǎo)出操作接口給用戶空間的話,需要自己去注冊(cè)字符驅(qū)動(dòng),并創(chuàng)建字符設(shè)備class以自動(dòng)在/dev下生成設(shè)備節(jié)點(diǎn),相對(duì)麻煩一點(diǎn)。而misc驅(qū)動(dòng)則無(wú)需考慮這些,基本上只需要把一些基本信息通過(guò)struct miscdevice交給misc_register()去處理即可。
本質(zhì)上misc驅(qū)動(dòng)也是一個(gè)字符設(shè)備驅(qū)動(dòng),可能相對(duì)特殊一點(diǎn)而已。在drivers/char/misc.c的misc驅(qū)動(dòng)初始化函數(shù)misc_init()中實(shí)際上使用了MISC_MAJOR(主設(shè)備號(hào)為10)并調(diào)用register_chrdev()去注冊(cè)了一個(gè)字符設(shè)備驅(qū)動(dòng)。同時(shí)也創(chuàng)建了一個(gè)misc_class,使得最后可自動(dòng)在/dev下自動(dòng)生成一個(gè)主設(shè)備號(hào)為10的字符設(shè)備??偟膩?lái)講,如果使用misc驅(qū)動(dòng)可以滿足要求的話,那么這可以為開發(fā)人員剩下不少麻煩。
所以說(shuō)misc驅(qū)動(dòng)模型讓我們很簡(jiǎn)單的在底層實(shí)現(xiàn)了字符設(shè)備驅(qū)動(dòng),并且在在應(yīng)用層給予了一定的接口,節(jié)省了主設(shè)備號(hào);其實(shí)就相當(dāng)于一個(gè)雜貨鋪,亂七八糟的字符設(shè)備驅(qū)動(dòng)模型都可以往里面堆。
3:驅(qū)動(dòng)模型代碼實(shí)現(xiàn):
misc驅(qū)動(dòng)的實(shí)現(xiàn)代碼在driver/char/misc.c目錄下,
misc_init函數(shù):
1 static int __init misc_init(void)
2 {
3 int err;
4
5 #ifdef CONFIG_PROC_FS
6 proc_create('misc', 0, NULL, &misc_proc_fops);
7 #endif
8 misc_class = class_create(THIS_MODULE, 'misc');
9 err = PTR_ERR(misc_class);
10 if (IS_ERR(misc_class))
11 goto fail_remove;
12
13 err = -EIO;
14 if (register_chrdev(MISC_MAJOR,'misc',&misc_fops))
15 goto fail_printk;
16 misc_class->devnode = misc_devnode;
17 return 0;
18
19 fail_printk:
20 printk('unable to get major %d for misc devicesn', MISC_MAJOR);
21 class_destroy(misc_class);
22 fail_remove:
23 remove_proc_entry('misc', NULL);
24 return err;
25 }
26 subsys_initcall(misc_init);
misc_init
class_create 創(chuàng)建了一個(gè)名為misc的類
register_chrdev(MISC_MAJOR,'misc',&misc_fops) 使用register_chrdev注冊(cè)了一個(gè)字符設(shè)備驅(qū)動(dòng),主設(shè)備號(hào)為MISC_MAJOR(10);
1 static const struct file_operations misc_fops = {
2 .owner = THIS_MODULE,
3 .open = misc_open,
4 };
misc類型驅(qū)動(dòng)提供了一個(gè)統(tǒng)一.open函數(shù)misc_open函數(shù);
misc_open 這個(gè)函數(shù)的實(shí)質(zhì)是通過(guò)inode找到misc類的次設(shè)備號(hào)minor,然后在通過(guò)次設(shè)備號(hào)和misc鏈表的次設(shè)備號(hào)進(jìn)行匹配,匹配好以后取出
1 static int misc_open(struct inode * inode, struct file * file)
2 {
3 int minor = iminor(inode);
4 struct miscdevice *c;
5 int err = -ENODEV;
6 const struct file_operations *old_fops, *new_fops = NULL;
7
8 mutex_lock(&misc_mtx);
9
10 list_for_each_entry(c, &misc_list, list) {
11 if (c->minor == minor) {
12 new_fops = fops_get(c->fops);
13 break;
14 }
15 }
16
17 if (!new_fops) {
18 mutex_unlock(&misc_mtx);
19 request_module('char-major-%d-%d', MISC_MAJOR, minor);
20 mutex_lock(&misc_mtx);
21
22 list_for_each_entry(c, &misc_list, list) {
23 if (c->minor == minor) {
24 new_fops = fops_get(c->fops);
25 break;
26 }
27 }
28 if (!new_fops)
29 goto fail;
30 }
31
32 err = 0;
33 old_fops = file->f_op;
34 file->f_op = new_fops;
35 if (file->f_op->open) {
36 file->private_data = c;
37 err=file->f_op->open(inode,file);
38 if (err) {
39 fops_put(file->f_op);
40 file->f_op = fops_get(old_fops);
41 }
42 }
43 fops_put(old_fops);
44 fail:
45 mutex_unlock(&misc_mtx);
46 return err;
47 }
1 int misc_register(struct miscdevice * misc)
2 {
3 struct miscdevice *c;
4 dev_t dev;
5 int err = 0;
6
7 INIT_LIST_HEAD(&misc->list);
8
9 mutex_lock(&misc_mtx);
10 list_for_each_entry(c, &misc_list, list) {
11 if (c->minor == misc->minor) {
12 mutex_unlock(&misc_mtx);
13 return -EBUSY;
14 }
15 }
16
17 if (misc->minor == MISC_DYNAMIC_MINOR) {
18 int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS);
19 if (i >= DYNAMIC_MINORS) {
20 mutex_unlock(&misc_mtx);
21 return -EBUSY;
22 }
23 misc->minor = DYNAMIC_MINORS - i - 1;
24 set_bit(i, misc_minors);
25 }
26
27 dev = MKDEV(MISC_MAJOR, misc->minor);
28
29 misc->this_device = device_create(misc_class, misc->parent, dev,
30 misc, '%s', misc->name);
31 if (IS_ERR(misc->this_device)) {
32 int i = DYNAMIC_MINORS - misc->minor - 1;
33 if (i < DYNAMIC_MINORS && i >= 0)
34 clear_bit(i, misc_minors);
35 err = PTR_ERR(misc->this_device);
36 goto out;
37 }
38
39 /*
40 * Add it to the front, so that later devices can 'override'
41 * earlier defaults
42 */
43 list_add(&misc->list, &misc_list);
44 out:
45 mutex_unlock(&misc_mtx);
46 return err;
47 }
在include/linux/miscdevice.h中定義了miscdevice 結(jié)構(gòu)體,所有的misc模型驅(qū)動(dòng)設(shè)備;都在內(nèi)核圍護(hù)的一個(gè)misc_list鏈表中;
內(nèi)核維護(hù)一個(gè)misc_list鏈表,misc設(shè)備在misc_register注冊(cè)的時(shí)候鏈接到這個(gè)鏈表,在misc_deregister中解除鏈接。
1 struct miscdevice {
2 int minor; //次設(shè)備號(hào),若為 MISC_DYNAMIC_MINOR 自動(dòng)分配
3 const char *name; //設(shè)備名
4 const struct file_operations *fops; //設(shè)備文件操作結(jié)構(gòu)體
5 struct list_head list; //misc_list鏈表頭
6 struct device *parent;
7 struct device *this_device;
8 const char *nodename;
9 mode_t mode;
10 };
misc_register函數(shù)
1 int misc_register(struct miscdevice * misc)
2 {
3 struct miscdevice *c;
4 dev_t dev;
5 int err = 0;
6
7 INIT_LIST_HEAD(&misc->list);
8
9 mutex_lock(&misc_mtx);
10 list_for_each_entry(c, &misc_list, list) {
11 if (c->minor == misc->minor) {
12 mutex_unlock(&misc_mtx);
13 return -EBUSY;
14 }
15 }
16
17 if (misc->minor == MISC_DYNAMIC_MINOR) {
18 int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS);
19 if (i >= DYNAMIC_MINORS) {
20 mutex_unlock(&misc_mtx);
21 return -EBUSY;
22 }
23 misc->minor = DYNAMIC_MINORS - i - 1;
24 set_bit(i, misc_minors);
25 }
26
27 dev = MKDEV(MISC_MAJOR, misc->minor);
28
29 misc->this_device = device_create(misc_class, misc->parent, dev,
30 misc, '%s', misc->name);
31 if (IS_ERR(misc->this_device)) {
上一篇:從samsung提供內(nèi)核進(jìn)行移植
下一篇:linux驅(qū)動(dòng)開發(fā)之九鼎板載蜂鳴器驅(qū)動(dòng)測(cè)試
推薦閱讀最新更新時(shí)間:2025-06-06 09:30





設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦
- 神經(jīng)形態(tài)芯片可能是革新機(jī)器人實(shí)時(shí)電機(jī)控制的未來(lái)
- 從三個(gè)方面理解ARM嵌入式系統(tǒng)
- 自動(dòng)報(bào)警 基于MCU的家庭防盜報(bào)警系統(tǒng)的設(shè)計(jì)
- 存儲(chǔ)控制器及其訪問(wèn)外設(shè)的原理
- 基于51系列單片機(jī)的智能照明控制系統(tǒng)設(shè)計(jì)方案
- 基于STM32的四旋翼飛行器控制系統(tǒng)
- 單片機(jī)應(yīng)用編程技巧解析
- 基于89C52的教室智能節(jié)能照明系統(tǒng)設(shè)計(jì)
- 一種新型的雨量光照傳感器的設(shè)計(jì)
- ZSR800GTA 8 伏正電流調(diào)節(jié)器的典型應(yīng)用
- #第七屆立創(chuàng)電賽#電流電壓表
- 5050LED驅(qū)動(dòng)
- 具有串行控制功能的 LTC4556 智能卡接口的典型應(yīng)用
- LTC2946IMS 雙電源、電荷和能量監(jiān)視器的典型應(yīng)用,使用單個(gè)光耦合器進(jìn)行電流隔離,并在任一電源出現(xiàn)故障時(shí)使用阻塞二極管來(lái)保持?jǐn)?shù)據(jù)
- 征集令 |物聯(lián)網(wǎng)之光——學(xué)習(xí)陪伴小夜燈
- lm3886-singel
- AM3GW-2405DZ ±5V 3 瓦 DC-DC 轉(zhuǎn)換器的典型應(yīng)用
- 使用 LT1054IN8 數(shù)字可編程負(fù)電源的典型應(yīng)用
- TRK-KEA8、Kinetis KEA8 StarterTRAK 用于低端汽車應(yīng)用
- 磁翻板液位計(jì)三大專利技術(shù)克服了傳統(tǒng)液位計(jì)的缺陷
- 絕緣電阻測(cè)試儀使用指導(dǎo)
- 一加10 Pro手機(jī)在京東等開啟預(yù)約
- 三星電子正式成立機(jī)器人業(yè)務(wù)團(tuán)隊(duì)
- 小白學(xué)習(xí)HC-05藍(lán)牙透?jìng)髂K
- TOF在消費(fèi)類電子市場(chǎng)打持久戰(zhàn) 傳今年只蘋果一個(gè)玩家?
- 在使用矢量網(wǎng)絡(luò)分析儀時(shí)要注意的細(xì)節(jié)
- 蘋果兩項(xiàng)新專利獲批:可監(jiān)測(cè)用戶的每個(gè)動(dòng)作
- Bourns 發(fā)布全新大功率金屬片電流檢測(cè)電阻, 采用 SMD 2010 緊湊型封裝
- 意法半導(dǎo)體推出先進(jìn)的 1600 V IGBT,面向高性價(jià)比節(jié)能家電市場(chǎng)
- EDPF-NT+分散控制系統(tǒng)網(wǎng)絡(luò)防護(hù)解決方案
- 基于PLC控制的易驅(qū)變頻器在布袋除塵器上的應(yīng)用
- 如何利用伺服自動(dòng)化實(shí)現(xiàn)成本降低和產(chǎn)能最大化?
- 壓力傳感器有哪些抗干擾措施?
- 破局!補(bǔ)盲dToF固態(tài)激光雷達(dá)輪番“出手”,禾賽FT120也要靠邊
- 利用正壓送風(fēng)壓力傳感器自動(dòng)控制火災(zāi)風(fēng)口壓力
- 多個(gè)傳感器間相互位置關(guān)系校準(zhǔn)方法
- 樓宇自控BA系統(tǒng)傳感器有哪些?
- 寶馬與四維圖新合作,在中國(guó)加速布局自動(dòng)駕駛
- 馬斯克與Autopilot團(tuán)隊(duì)關(guān)系糟糕,自動(dòng)駕駛雄心將遭遇重挫?
- 探訪寶馬的生產(chǎn)車間,人工智能到底有多強(qiáng)大?
- 恒大與國(guó)家電網(wǎng)正式合作,“充電難”困境是否能被打破
- Wi-Fi技術(shù)在低功耗物聯(lián)網(wǎng)應(yīng)用中前景無(wú)限
- 52.5億元賽晶亞太嘉善IGBT項(xiàng)目9月或量產(chǎn)
- 彌知科技張?zhí)旆颍鹤匝蠾ebAR算法助3D數(shù)字化技術(shù)深入千行百業(yè)
- 彭博:小米正在考慮參與黑芝麻智能科技最新一輪融資
- NAND Flash控制IC廠群聯(lián)宣布要全面漲價(jià)!
- 最高法:聚焦高端芯片、集成電路等關(guān)鍵技術(shù)重點(diǎn)領(lǐng)域