0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

嵌入式驅(qū)動(dòng)的構(gòu)造分析總結(jié)

Q4MP_gh_c472c21 ? 2018-03-03 09:23 ? 次閱讀

Linux系統(tǒng)上編寫驅(qū)動(dòng)程序,說簡(jiǎn)單也簡(jiǎn)單,說難也難。難在于對(duì)算法的編寫和設(shè)備的控制方面,是比較讓人頭疼的;說它簡(jiǎn)單是因?yàn)樵贚inux下已經(jīng)有一套驅(qū)動(dòng)開發(fā)的模式,編寫的時(shí)候只需要按照這個(gè)模式寫就可以了,而這個(gè)模式就是它事先定義好的一些結(jié)構(gòu)體,在驅(qū)動(dòng)編寫的時(shí)候,只要對(duì)這些結(jié)構(gòu)體根據(jù)設(shè)備的需求進(jìn)行適當(dāng)?shù)奶畛?,就?shí)現(xiàn)了驅(qū)動(dòng)的編寫。

首先在Linux下,視一切事物皆為文件,它同樣把驅(qū)動(dòng)設(shè)備也看成是文件,對(duì)于簡(jiǎn)單的文件操作,無(wú)非就是open/close/read/write,在Linux對(duì)于文件的操作有一個(gè)關(guān)鍵的數(shù)據(jù)結(jié)構(gòu):file_operation,它的定義在源碼目錄下的include/linux/fs.h中,內(nèi)容如下:

[cpp]view plaincopy

1.structfile_operations{

2.structmodule*owner;

3.loff_t(*llseek)(structfile*,loff_t,int);

4.ssize_t(*read)(structfile*,char__user*,size_t,loff_t*);

5.ssize_t(*write)(structfile*,constchar__user*,size_t,loff_t*);

6.ssize_t(*aio_read)(structkiocb*,conststructiovec*,unsignedlong,loff_t);

7.ssize_t(*aio_write)(structkiocb*,conststructiovec*,unsignedlong,loff_t);

8.int(*readdir)(structfile*,void*,filldir_t);

9.unsignedint(*poll)(structfile*,structpoll_table_struct*);

10.int(*ioctl)(structinode*,structfile*,unsignedint,unsignedlong);

11.long(*unlocked_ioctl)(structfile*,unsignedint,unsignedlong);

12.long(*compat_ioctl)(structfile*,unsignedint,unsignedlong);

13.int(*mmap)(structfile*,structvm_area_struct*);

14.int(*open)(structinode*,structfile*);

15.int(*flush)(structfile*,fl_owner_tid);

16.int(*release)(structinode*,structfile*);

17.int(*fsync)(structfile*,intdatasync);

18.int(*aio_fsync)(structkiocb*,intdatasync);

19.int(*fasync)(int,structfile*,int);

20.int(*lock)(structfile*,int,structfile_lock*);

21.ssize_t(*sendpage)(structfile*,structpage*,int,size_t,loff_t*,int);

22.unsignedlong(*get_unmapped_area)(structfile*,unsignedlong,unsignedlong,unsignedlong,unsignedlong);

23.int(*check_flags)(int);

24.int(*flock)(structfile*,int,structfile_lock*);

25.ssize_t(*splice_write)(structpipe_inode_info*,structfile*,loff_t*,size_t,unsignedint);

26.ssize_t(*splice_read)(structfile*,loff_t*,structpipe_inode_info*,size_t,unsignedint);

27.int(*setlease)(structfile*,long,structfile_lock**);

28.};

對(duì)于這個(gè)結(jié)構(gòu)體中的元素來說,大家可以看到每個(gè)函數(shù)名前都有一個(gè)“*”,所以它們都是指向函數(shù)的指針。目前我們只需要關(guān)心

ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);

ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);

int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);

int (*open) (struct inode *, struct file *);

int (*release) (struct inode *, struct file *);

這幾條,因?yàn)檫@篇文章就叫簡(jiǎn)單驅(qū)動(dòng)。就是讀(read)、寫(write)、控制(ioctl)、打開(open)、卸載(release)。這個(gè)結(jié)構(gòu)體在驅(qū)動(dòng)中的作用就是把系統(tǒng)調(diào)用和驅(qū)動(dòng)程序關(guān)聯(lián)起來,它本身就是一系列指針的集合,每一個(gè)都對(duì)應(yīng)一個(gè)系統(tǒng)調(diào)用。

但是畢竟file_operation是針對(duì)文件定義的一個(gè)結(jié)構(gòu)體,所以在寫驅(qū)動(dòng)時(shí),其中有一些元素是用不到的,所以在2.6版本引入了一個(gè)針對(duì)驅(qū)動(dòng)的結(jié)構(gòu)體框架:platform,它是通過結(jié)構(gòu)體platform_device來描述設(shè)備,用platform_driver描述設(shè)備驅(qū)動(dòng),它們都在源代碼目錄下的include/linux/platform_device.h中定義,內(nèi)容如下:

[cpp]view plaincopy

1.structplatform_device{

2.constchar*name;

3.intid;

4.structdevicedev;

5.u32num_resources;

6.structresource*resource;

7.conststructplatform_device_id*id_entry;

8./*archspecificadditions*/

9.structpdev_archdataarchdata;

10.};

11.structplatform_driver{

12.int(*probe)(structplatform_device*);

13.int(*remove)(structplatform_device*);

14.void(*shutdown)(structplatform_device*);

15.int(*suspend)(structplatform_device*,pm_message_tstate);

16.int(*resume)(structplatform_device*);

17.structdevice_driverdriver;

18.conststructplatform_device_id*id_table;

19.};

對(duì)于第一個(gè)結(jié)構(gòu)體來說,它的作用就是給一個(gè)設(shè)備進(jìn)行登記作用,相當(dāng)于設(shè)備的身份證,要有姓名,身份證號(hào),還有你的住址,當(dāng)然其他一些東西就直接從舊身份證上copy過來,這就是其中的struct device dev,這是傳統(tǒng)設(shè)備的一個(gè)封裝,基本就是copy的意思了。對(duì)于第二個(gè)結(jié)構(gòu)體,因?yàn)長(zhǎng)inux源代碼都是C語(yǔ)言編寫的,對(duì)于這里它是利用結(jié)構(gòu)體和函數(shù)指針,來實(shí)現(xiàn)了C語(yǔ)言中沒有的“類”這一種結(jié)構(gòu),使得驅(qū)動(dòng)模型成為一個(gè)面向?qū)ο蟮慕Y(jié)構(gòu)。對(duì)于其中的struct device_driver driver,它是描述設(shè)備驅(qū)動(dòng)的基本數(shù)據(jù)結(jié)構(gòu),它是在源代碼目錄下的include/linux/device.h中定義的,內(nèi)容如下:

[cpp]view plaincopy

1.structdevice_driver{

2.constchar*name;

3.structbus_type*bus;

4.structmodule*owner;

5.constchar*mod_name;/*usedforbuilt-inmodules*/

6.boolsuppress_bind_attrs;/*disablesbind/unbindviasysfs*/

7.#ifdefined(CONFIG_OF)

8.conststructof_device_id*of_match_table;

9.#endif

10.int(*probe)(structdevice*dev);

11.int(*remove)(structdevice*dev);

12.void(*shutdown)(structdevice*dev);

13.int(*suspend)(structdevice*dev,pm_message_tstate);

14.int(*resume)(structdevice*dev);

15.conststructattribute_group**groups;

16.conststructdev_pm_ops*pm;

17.structdriver_private*p;

18.};

依然全部都是以指針的形式定義的所有元素,對(duì)于驅(qū)動(dòng)這一塊來說,每一項(xiàng)肯定都是需要一個(gè)函數(shù)來實(shí)現(xiàn)的,如果不把它們集合起來,是很難管理的,而且很容易找不到,而且對(duì)于不同的驅(qū)動(dòng)設(shè)備,它的每一個(gè)功能的函數(shù)名必定是不一樣的,那么我們?cè)陂_發(fā)的時(shí)候,需要用到這些函數(shù)的時(shí)候,就會(huì)很不方便,不可能在使用的時(shí)候去查找對(duì)應(yīng)的源代碼吧,所以就要進(jìn)行一個(gè)封裝,對(duì)于函數(shù)的封裝,在C語(yǔ)言中一個(gè)對(duì)好的辦法就是在結(jié)構(gòu)體中使用指向函數(shù)的指針,這種方法其實(shí)我們?cè)谄綍r(shí)的程序開發(fā)中也可以使用,原則就是體現(xiàn)出一個(gè)“類”的感覺,就是面向?qū)ο蟮乃枷搿?/p>

在Linux系統(tǒng)中,設(shè)備可以大致分為3類:字符設(shè)備、塊設(shè)備和網(wǎng)絡(luò)設(shè)備,而每種設(shè)備中又分為不同的子系統(tǒng),由于具有自身的一些特殊性質(zhì),所以有不能歸到某個(gè)已經(jīng)存在的子類中,所以可以說是便于管理,也可以說是為了達(dá)到同一種定義模式,所以linux系統(tǒng)把這些子系統(tǒng)歸為一個(gè)新類:misc ,以結(jié)構(gòu)體miscdevice描述,在源代碼目錄下的include/linux/miscdevice.h中定義,內(nèi)容如下:

[cpp]view plaincopy

1.structmiscdevice{

2.intminor;

3.constchar*name;

4.conststructfile_operations*fops;

5.structlist_headlist;

6.structdevice*parent;

7.structdevice*this_device;

8.constchar*nodename;

9.mode_tmode;

10.};

對(duì)于這些設(shè)備,它們都擁有一個(gè)共同主設(shè)備號(hào)10,所以它們是以次設(shè)備號(hào)來區(qū)分的,對(duì)于它里面的元素,大應(yīng)該很眼熟吧,而且還有一個(gè)我們更熟悉的list_head的元素,這里也可以應(yīng)證我之前說的list_head就是一個(gè)橋梁的說法了。

其實(shí)對(duì)于上面介紹的結(jié)構(gòu)體,里面的元素的作用基本可以見名思意了,所以不用贅述了。其實(shí)寫一個(gè)驅(qū)動(dòng)模塊就是填充上述的結(jié)構(gòu)體,根據(jù)設(shè)備的功能和用途寫相應(yīng)的函數(shù),然后對(duì)應(yīng)到結(jié)構(gòu)體中的指針,然后再寫一個(gè)入口一個(gè)出口(就是模塊編程中的init和exit)就可以了,一般情況下入口程序就是在注冊(cè)platform_device和platform_driver(當(dāng)然,這樣說是針對(duì)以platform模式編寫驅(qū)動(dòng)程序)。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5060

    文章

    18978

    瀏覽量

    302225

原文標(biāo)題:搞嵌入式Linux驅(qū)動(dòng)說簡(jiǎn)單也簡(jiǎn)單,說難也難!嵌入式驅(qū)動(dòng)的結(jié)構(gòu)分析

文章出處:【微信號(hào):gh_c472c2199c88,微信公眾號(hào):嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    嵌入式Linux命令總結(jié)

    嵌入式Linux命令總結(jié)
    發(fā)表于 09-19 16:30 ?503次閱讀

    如何構(gòu)造運(yùn)行良好的嵌入式設(shè)備的驅(qū)動(dòng)程序?

    嵌入式系統(tǒng)需要支持的外部設(shè)備種類繁多,如何構(gòu)造運(yùn)行良好的嵌入式設(shè)備的驅(qū)動(dòng)程序,對(duì)嵌入式操作系統(tǒng)的實(shí)際應(yīng)用有重要意義。
    發(fā)表于 09-25 07:44

    嵌入式linux學(xué)習(xí)方法總結(jié)

    嵌入式linux學(xué)習(xí)方法總結(jié) 嵌入式linux的學(xué)習(xí)現(xiàn)在挺流行
    發(fā)表于 09-10 10:44 ?3523次閱讀

    ARM嵌入式系統(tǒng)的問題總結(jié)分析

    摘要: 本文是作者關(guān)于嵌入式系統(tǒng)一些基本問題的思考和總結(jié)。主要是從嵌入式處理器與硬件、ARM處
    發(fā)表于 11-17 18:28 ?766次閱讀

    精通嵌入式Linux編程—構(gòu)造自己的GUI環(huán)境

    精通嵌入式Linux編程—構(gòu)造自己的GUI環(huán)境
    發(fā)表于 10-30 09:04 ?16次下載
    精通<b class='flag-5'>嵌入式</b>Linux編程—<b class='flag-5'>構(gòu)造</b>自己的GUI環(huán)境

    基于嵌入式Linux LCD設(shè)備驅(qū)動(dòng)分析

    基于嵌入式Linux LCD設(shè)備驅(qū)動(dòng)分析
    發(fā)表于 10-30 16:20 ?14次下載
    基于<b class='flag-5'>嵌入式</b>Linux LCD設(shè)備<b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>分析</b>

    嵌入式Linux設(shè)備驅(qū)動(dòng)程序開發(fā)基礎(chǔ)知識(shí)總結(jié)免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是嵌入式Linux設(shè)備驅(qū)動(dòng)程序開發(fā)基礎(chǔ)知識(shí)總結(jié)免費(fèi)下載 嵌入式Linux設(shè)備驅(qū)動(dòng)程序分類靜態(tài)加載的
    發(fā)表于 10-23 16:10 ?13次下載

    嵌入式系統(tǒng)論文總結(jié)

    嵌入式系統(tǒng)論文總結(jié)(嵌入式開發(fā)用什么編程語(yǔ)言)-該文檔為嵌入式系統(tǒng)論文總結(jié)文檔,是一份很不錯(cuò)的參考資料,具有較高參考價(jià)值,感興趣的可以下載看
    發(fā)表于 07-30 10:19 ?8次下載
    <b class='flag-5'>嵌入式</b>系統(tǒng)論文<b class='flag-5'>總結(jié)</b>

    嵌入式知識(shí)點(diǎn)總結(jié)

    嵌入式知識(shí)點(diǎn)總結(jié)(arm嵌入式開發(fā)led過程)-嵌入式知識(shí)點(diǎn)總結(jié)? ? ? ? ? ? ? ? ? ??
    發(fā)表于 07-30 14:20 ?23次下載
    <b class='flag-5'>嵌入式</b>知識(shí)點(diǎn)<b class='flag-5'>總結(jié)</b>

    arm嵌入式系統(tǒng)基礎(chǔ)總結(jié)教程

    arm嵌入式系統(tǒng)基礎(chǔ)總結(jié)教程(嵌入式開發(fā)板有哪些外設(shè))-該文檔為arm嵌入式系統(tǒng)基礎(chǔ)總結(jié)教程文檔,是一份很不錯(cuò)的參考資料,具有較高參考價(jià)值,
    發(fā)表于 08-04 11:15 ?6次下載
    arm<b class='flag-5'>嵌入式</b>系統(tǒng)基礎(chǔ)<b class='flag-5'>總結(jié)</b>教程

    嵌入式】基于ARM的嵌入式Linux開發(fā)總結(jié)

    --arm-linux進(jìn)程編程嵌入式知識(shí)點(diǎn)復(fù)習(xí)六 --arm-linux網(wǎng)絡(luò)編程嵌入式知識(shí)點(diǎn)復(fù)習(xí)七 --linux字符型設(shè)備驅(qū)動(dòng)初步嵌入式知識(shí)點(diǎn)復(fù)習(xí)一1、
    發(fā)表于 10-19 18:32 ?26次下載
    【<b class='flag-5'>嵌入式</b>】基于ARM的<b class='flag-5'>嵌入式</b>Linux開發(fā)<b class='flag-5'>總結(jié)</b>

    嵌入式驅(qū)動(dòng)組成概論3.9

    嵌入式系統(tǒng)的組成:嵌入式設(shè)備的組成:硬件CPUi/o內(nèi)存軟件系統(tǒng)軟件:應(yīng)用軟件:未來工作方向:硬件軟件:1.嵌入式系統(tǒng)工程師:設(shè)計(jì)、開發(fā)嵌入式系統(tǒng);
    發(fā)表于 10-19 18:33 ?3次下載
    <b class='flag-5'>嵌入式</b><b class='flag-5'>驅(qū)動(dòng)</b>組成概論3.9

    三級(jí)嵌入式總結(jié)

    三級(jí)嵌入式總結(jié)嵌入式系統(tǒng)? 嵌入式系統(tǒng)上的軟件具有結(jié)構(gòu)精簡(jiǎn),代碼輕量化,占用存儲(chǔ)資源少的特點(diǎn)。? 嵌入式系統(tǒng)和計(jì)算機(jī)操作系統(tǒng)的共同特征是:
    發(fā)表于 10-20 14:51 ?8次下載
    三級(jí)<b class='flag-5'>嵌入式</b><b class='flag-5'>總結(jié)</b>

    嵌入式分層概括總結(jié)

    最近重新進(jìn)入嵌入式領(lǐng)域,有必要對(duì)嵌入式分層架構(gòu)有一個(gè)清晰的理解。經(jīng)過多方查閱以及個(gè)人的理解,本人對(duì)嵌入式分層架構(gòu)概括總結(jié)如下:比較細(xì)的層次由下到上可分為:(硬件層) 硬件
    發(fā)表于 10-21 10:51 ?11次下載
    <b class='flag-5'>嵌入式</b>分層概括<b class='flag-5'>總結(jié)</b>

    嵌入式linux編譯 ko,嵌入式linux:編譯linux驅(qū)動(dòng)模塊

    嵌入式系統(tǒng)應(yīng)用中,嵌入式linux是非常重要的一個(gè)方面,而linux驅(qū)動(dòng)編譯又是嵌入式linux中至關(guān)重要的一個(gè)環(huán)節(jié)。下面,本文將詳細(xì)講解如何編譯linux
    發(fā)表于 11-01 16:31 ?9次下載
    <b class='flag-5'>嵌入式</b>linux編譯 ko,<b class='flag-5'>嵌入式</b>linux:編譯linux<b class='flag-5'>驅(qū)動(dòng)</b>模塊