999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

從數據關聯的角度剖析字符設備驅動中的初始化函數

2019-05-24 14:12:12劉海秋馬慧敏江朝暉
電腦知識與技術 2019年7期

劉海秋 馬慧敏 江朝暉

摘要:嵌入式系統的應用覆蓋了消費類電子、智能家居、汽車電子等諸多領域,字符設備驅動是嵌入式系統課程教學中的重點和難點內容,其中初始化函數作為向Linux內核加載驅動程序的入口函數,實現了字符設備、設備文件和設備驅動之間的相互關聯。介紹了有關初始化函數的關鍵數據結構體,深入剖析了關鍵數據結構體之間的信息傳遞模式和關系建立方法,并給出了初始化函數的典型代碼結構。本研究有助于電子信息工程等相關專業的學生對字符設備驅動程序中初始化函數的理解,提高學生在嵌入式系統應用開發中的實踐能力。

關鍵詞:嵌入式系統;字符設備驅動;初始化函數;數據關聯

中圖分類號:G642 文獻標識碼:A

文章編號:1009-3044(2019)07-0013-04

Abstract:Embedded systems have been applied to many fields, such as consumer electronics, intelligent households and automotive electronics. Character device drivers are the key and difficult contents in embedded systems teaching. Initialization functions, as entries into the Linux kernel, implement the correlation between character devices, device files and device drivers. In this study, pivotal data structures associated with initialization functions are first introduced, and information transfer mode and the relation establishment method between the pivotal data structures are then analyzed, finally, the typical code structures of initialization functions are present. This study is expected to help students in electronic information engineering and other related majors understand the initialization function in the character device drivers and improve their practical abilities in the application and development of embedded systems.

Key words:Embedded systems;Character device drivers;Initialization functions;Data association

1 引言

近年來,嵌入式系統廣泛應用于消費類電子、智能家居、汽車電子、醫療電子等諸多領域[1],幾乎人手一部的智能手機是嵌入式系統的一項典型應用,嵌入式系統電子產品正在改變人們生活和工作方式,同時,也激發了社會對嵌入式系統開發高級人才的強烈需求[2-5]。為此,各大高校的電子信息工程、自動控制、通信工程等相關專業相繼開設了“嵌入式系統”課程,以培養學生掌握嵌入式系統開發技術,適應社會對嵌入式人才的需求[6-8]。

字符設備驅動囊括了硬件架構、操作系統、文件系統以及編程語言等相關知識點,具有極強的綜合性、應用性和工程性[9],是嵌入式系統教學的重點和難點內容。初始化函數作為向內核加載驅動程序的入口函數,實現了關聯字符設備、設備文件和設備驅動等重要功能[10],是學習字符設備的驅動程序的入門知識。文章從關鍵數據結構之間信息傳遞模式的角度,剖析了字符設備驅動中的初始化函數的工作機理,期望有助于學生正確梳理字符設備、設備文件和設備驅動三者之間的內在關聯,掌握初始化函數的代碼結構,并應用于課程實踐中。

2 字符設備驅動的典型結構介紹

一方面,加載后的驅動程序以獨立模塊的形式存在于Linux內核中,字符設備驅動遵循模塊的代碼結構。另一方面,Linux內核抽象了對硬件的處理,在應用層,對設備的操作處理與普通文件相同,只需調用內核提供的開關、讀寫等系統函數,便可以實現相應操作;與普通文件不同的是,在內核層,將有關文件操作的開關、讀寫等函數封裝到file_operation結構體中,而函數的具體實現由驅動程序完成,因此,字符設備驅動程序除了包含模塊必需的代碼之外,還包括file_operation結構體中相關等函數的具體實現。

綜合以上兩方面,字符設備驅動的典型代碼結構如下:

static int xxx_open() //打開

static int xxx_release()//關閉

static ssize_t xxx_read()//讀

static ssize_t xxx_write()//寫

static int _init xxx_init( )//初始化函數

static void _exit xxx_exit( ) //退出函數

module_init( xxx_init ) //入口設置

module_exit( xxx_exit ) //出口設置

3 初始化函數中數據關聯的建立

3.1 關鍵數據結構體的介紹

字符設備驅動程序通常涉及三個關鍵的數據結構體:cdev、inode和file_operations結構體,實現該三個結構體之間關聯的正確建立是字符設備驅動程序中初始化函數的基本任務。

3.1.1 cdev結構體

Linux內核提供了cdev結構體,實現對字符設備的抽象。cdev結構體中包含了字符設備的設備號、文件操作函數指針等關鍵信息。cdev結構體的關鍵成員如下:

struct cdev {

const struct file_operations *ops; // 文件操作結構體

dev_t dev; //設備號

unsigned int count; //設備數目

};

在字符設備初始化函數中,需要完成cdev結構體的初始化、關聯cdev與該設備對應的文件操作函數、將cdev結構體插入到內核中的字符設備列表中。

3.1.2 inode結構體

Linux內核提供了inode結構體,封裝與文件操作有關的信息,inode結構體的關鍵成員如下:

struct inode {

dev_t i_rdev;//設備文件的設備號

struct cdev *i_cdev;//字符設備cdev結構體指針

};

其中的設備號i_rdev和指向cdev結構體的指針*i_cdev是與字符設備驅動開發關系最大的兩個成員。

3.1.3 file_operations結構體

file_operations結構體集合了大量的成員函數,用以實現文件的開關、讀寫等操作,其中與字符設備驅動密切相關的函數包括:

struct file_operations {

ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);//從設備中讀取數據

ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);//向設備發送數據

int (*open) (struct inode *, struct file *); //打開

int (*release) (struct inode *, struct file *); //關閉

};

在應用中,根據需要選取一部分成員函數進行實現即可,成員函數的具體實現是設備驅動程序設計的核心內容。

3.2 數據結構體之間關聯的分析

字符設備涉及三個基本概念:設備、設備文件和驅動程序,三者之間通過設備號關聯,如圖1所示。當應用程序訪問設備文件時,內核根據文件名確定相應的設備號,找到對應的驅動程序,執行驅動程序中的函數,當函數中涉及控制具體設備時,內核根據設備號找到相關的字符設備,實現設備的控制。實際上,內核是通過設備號關聯設備、設備文件以及驅動程序的。

為了實現設備、設備文件和驅動程序三者之間的關聯,在驅動程序開發過程中需要完成以下六個步驟,如圖2所示。

3.2.1 申請設備號并關聯設備號和驅動程序

設備號分為主設備號和次設備號,主設備號用以區分設備類型,次設備號用以區分同一類型設備中的不同個體。通過設備類型和設備號能夠對設備進行唯一標示。因此,必須為每個設備向內核申請獨立的設備號。

此外,對設備的具體操作由相應的驅動程序實現,Linux內核通過設備號正確地找到對應的驅動程序,是順利完成設備操作的首要前提。因此,需要將驅動程序與設備號相互關聯。

3.2.2 創建字符設備cdev

Linux內核采用cdev結構體來表征一個字符設備,當添加新的字符設備之后,需要為新加的字符設備創建cdev結構體,該結構體中包含了設備號和操作函數指針。

3.2.3 關聯字符設備cdev與設備號并將字符設備插入字符設備列表中

Linux內核中存在字符設備列表,如圖2所示,當內核訪問某設備時,以設備號為索引遍歷設備列表,確定相應的表項,表項中保存了該設備的指針。因此,若要字符設備能夠被內核訪問,必須將字符設備的cdev結構體與設備號相關聯,并以設備號為索引,將該字符設備的指針保存到字符設備列表相應的表項中。

3.2.4 關聯字符設備cdev和file_operation結構體

Linux內核為每個設備文件分配了表征文件屬性的inode結構體和文件操作結構體file_operations。當內核對設備進行操作時,需要訪問相應的file_operation結構體,為了使內核正確地找到file_operation結構體,必須將字符設備的cdev和file_operation相互關聯。

3.2.5 關聯file_operation中的成員函數和驅動程序中的函數

對字符設備的操作主要采用file_operation結構體中的open、release、read等成員函數,這些函數在驅動程序中實現。當應用程序調用file_operation結構體中的成員函數時,實際上調用的是驅動程序中的相關函數。因此,必須將file_operation結構體中的成員函數和驅動程序中的函數相互關聯。

3.2.6 創建設備文件并關聯設備文件和設備號

Linux內核將設備抽象成文件的形式,使應用程序對設備的訪問如同訪問普通文件,因此,需要創建設備文件。此外,為了使應用程序訪問設備文件時,內核能夠根據設備文件名正確地找到與之對應的設備以及其驅動程序,必須將設備文件和能夠唯一標示設備的設備號關聯起來。

3.3 數據結構體之間關聯的建立

3.3.1 申請設備號并關聯設備號和驅動程序的實現

通過向內核注冊驅動程序,實現設備號的申請,以及設備號與驅動程序之間的相互關聯。設備號的分配方式分為兩種:靜態分配和動態分配,靜態分配是由用戶指定主設備號,由內核檢查設備號的可用性,可用則返回零,不可用則返回負數。動態分配是由內核根據設備號的實用情況,為設備分配空閑的設備號。

Linux內核提供的用于靜態分配設備號的注冊函數為:

register_chrdev_region(dev_t first, unsigned int count, char *name)

參數說明如下:first : 需用戶指定的主設備號; count:次設備號的個數;name:相關聯的驅動名稱。返回值說明如下: 成功:返回值為0;失敗:返回值小于0。

Linux內核提供的用于動態分配設備號的注冊函數為:

int alloc_chrdev_region (dev_t dev, unsigned int baseminor, unsigned int count, char name)

參數說明如下:dev:輸出型參數,獲得分配到的設備號;baseminor :次設備號的基準;其余參數同上。返回值說明如下: 成功:分配得到的設備號由dev帶出來;失敗:返回值小于0。

當用戶不需要某個設備時,可以注銷設備驅動程序,Linux內核提供的注銷函數如下:

unregister_chrdev_region (dev_t first, unsigned int count)

參數說明同上。

3.3.2 創建字符設備cdev結構體的實現

用戶可以采用如下語句定義一個字符設備my_cdev結構體對象,之后Linux內核會為該結構體分配存儲空間,完成字符設備my_cdev的創建。

struct cdev my_cdev

3.3.3 關聯字符設備cdev與設備號的實現

Linux內核提供了cdev_add函數,通過將設備號賦值給cdev結構體中的dev成員,實現字符設備cdev與設備號之間的相互關聯,利用設備號索引字符設備列表中的表項,并將存儲字符設備cdev結構體的地址賦給該表項,以便于內核通過設備號正確地找到字符設備cdev結構體。

cdev_add函數的定義為:

cdev_add (cdev *, dev_t, count)

參數說明如下:dev_t:設備號;cdev * :字符設備結構體的指針;count : 設備號的個數。返回值說明如下:成功:返回值為0;失敗:返回值小于0。

該函數以內核分配的設備號為輸入參數,因此,在字符設備驅動程序的初始化函數中,該函數必須位于注冊函數的后面。

3.3.4 關聯字符設備的cdev結構體和file_operation結構體的實現

Linux內核提供了cdev_init函數,通過將存儲文件操作結構體file_operations的地址賦給字符設備cdev結構體中的ofp成員,實現字符設備cdev和文件操作file_operation的相互關聯,以便于Linux內核正確地找到與字符設備cdev對應的file_operation。

該函數的定義為:

cdev_init (cdev *, file_operations *)

參數說明如下:cdev*: 字符設備結構體的指針;file_operations*: 文件操作函數的指針。

3.4.5 關聯file_operation結構體中的成員函數和驅動程序中函數的實現

通過在驅動程序中添加填充函數,明確file_operation結構體中的成員函數和驅動程序中函數之間的對應關系,進而實現兩者的關聯。

填充函數的代碼結構如下:

file_operations xxx_ops =

{ .open = xxx_ open,

.release = xxx_ release,

.read = xxx_read,

.write = xxx_write,

. ioctl = xxx_ioctl,

…}

該填充函數以驅動程序中的xxx_open、xxx_release、xxx_read等函數為參數,因此,在字符設備驅動程序中,填充函數必須位于上訴函數定義的后面。

3.3.6 創建設備文件并關聯設備文件和設備號的實現

Linux內核提供了mknod命令,為指定類型的設備創建設備文件,并將設備文件與設備號相互關聯,以便于應用程序訪問設備文件時,內核能夠根據設備文件名正確地找到與之對應的設備號,進而確定該設備的驅動程序。

mknod命令的具體格式如下:

mknod /dev/xxx c M m

參數說明如下:/dev/xxx:創建的設備文件;c:字符設備類型;M:主設備號;m:次設備號。

值得注意的是,當驅動程序的初始化函數中采用動態分配設備號時,每次驅動程序加載內核分配的設備號可能不同,為了在運用mknod命令時,輸入正確的設備號,必須在成功加載了字符設備驅動程序之后,采用cat命令查看所加載的字符設備的主、次設備號,而后才能運用mknod上述命令創建設備文件。

4 初始化函數的典型結構

綜合上述數據結構體之間關聯的建立方法,形成如下所示的字符設備驅動程序中初始化函數的典型結構。

static int major = 250; //主設備號

static int minor = 0; //次設備號

static dev_t devno; //設備號

static struct cdev mycdev; //創建1個字符設備

static int _init xxx_init(void) //初始化函數

{

int ret;

devno = MKDEV(major,minor); // 由主設備號和次設備號構成設備號

ret = register_chrdev_region(devno, 1, "xxx"); //注冊驅動程序

cdev_init(&mycdev,&xxx_ops); //將設備和file_operation關聯

ret = cdev_add(&mycdev,devno,1);//向內核添加mycdev

return 0;

}

static void _exit xxx_exit (void) //退出函數

{

cdev_del(&mycdev); //從內核中移除mycdev

unregister_chrdev_region(devno,1); // 注銷驅動程序

}

module_init( xxx_init ) //入口函數設置

module_exit( xxx_exit ) //出口函數設置

Linux內核為加載模塊提供了insmod命令,加載后的驅動從所設置的入口函數開始執行,通常將初始化函數設置為入口函數,從而實現了向內核申請設備號、關聯設備號和驅動程序等一系列功能。

5 結論

字符設備驅動設計是電子信息工程等專業課程“嵌入式系統”的重要內容,是嵌入式系統開發的必備技術,其中的初始化函數涉及設備、文件系統、Linux內核等多個知識點,是字符設備驅動設計中的難點。文章從數據關聯的角度,深入剖析了關鍵數據結構體之間的信息傳遞模式和關系建立方法,并給出了典型的代碼結構。文章研究結果有助于電子信息工程等相關專業的學生對字符設備驅動初始化函數的理解,提高學生在綜合實驗、畢業設計等應用開發中的實踐能力。

參考文獻:

[1] 朱銘琳.嵌入式系統開發課程教學改革[J]. 信息與電腦(理論版),2017(19):231-233.

[2] 黎芳芳,柴明鋼,劉先鋒. 以創新應用能力為核心嵌入式系統教學的改進探索[J]. 時代教育,2017(19):52.

[3] 杜欽生, 唐伎玲. 應用型大學嵌入式系統人才培養模式研究[J]. 長春大學學報, 2012, 22(2):214-216.

[4] 謝斌, 任克強, 鐘文濤. 嵌入式系統應用型人才培養模式的探討[J]. 江西理工大學學報, 2010, 31(2):93-95.

[5] 張曉東, 盧濤, 曹毅. 應用型嵌入式系統人才培養模式改革與探索[J]. 中國輕工教育, 2017(2):56-58.

[6] 李文生,鄧春健,呂燚. 案例驅動的嵌入式系統教學改革探索[J]. 計算機教育,2011(2):22-25.

[7] 郭國法, 宮瑤, 張開生. 嵌入式課程遞階教學平臺的設計與實現[J]. 電腦知識與技術, 2015(11).

[8] 李巖,王小玉,孫永春. 嵌入式系統教學研究[J]. 電氣電子教學學報,2006(3):45-47+90.

[9] 周菁. 嵌入式Linux設備驅動程序設計探討[J]. 電腦編程技巧與維護, 2016(4):47-48.

[10] 陳文智. 嵌入式系統原理與設計[M]. 清華大學出版社, 2011.

【通聯編輯:王力】

主站蜘蛛池模板: 99热这里只有精品2| 亚洲欧美激情另类| 免费中文字幕一级毛片| lhav亚洲精品| 久久久亚洲色| 色有码无码视频| 国产va在线观看| www精品久久| 色婷婷狠狠干| 国产成人高清精品免费5388| 国产精品视频免费网站| 亚洲日本中文字幕乱码中文| a天堂视频在线| 91久久国产综合精品女同我| P尤物久久99国产综合精品| 欧美精品高清| 国产精品视频久| 日本不卡在线播放| 福利在线免费视频| 亚洲最新地址| 最新日本中文字幕| 亚洲男女在线| 一本大道香蕉中文日本不卡高清二区| 中文字幕资源站| 久久永久免费人妻精品| 欧美无专区| 成人综合网址| 国产www网站| 蝌蚪国产精品视频第一页| 国产丝袜丝视频在线观看| 99热最新网址| 麻豆国产精品视频| 2020国产精品视频| 999福利激情视频| 亚洲福利片无码最新在线播放| AV在线天堂进入| 色综合狠狠操| 欧洲成人免费视频| 婷婷丁香色| 成·人免费午夜无码视频在线观看 | 亚洲视频黄| 伊人久久综在合线亚洲2019| 国产午夜人做人免费视频中文| 国产精品一老牛影视频| 国产精品无码AV中文| 怡红院美国分院一区二区| 久久这里只精品国产99热8| 秋霞午夜国产精品成人片| jijzzizz老师出水喷水喷出| 亚洲人成网线在线播放va| 亚洲专区一区二区在线观看| 97青草最新免费精品视频| 国产乱子伦无码精品小说| 亚洲狼网站狼狼鲁亚洲下载| 国内黄色精品| 国产第八页| 亚洲综合久久一本伊一区| 国产香蕉在线视频| 二级毛片免费观看全程| 欧美国产综合色视频| 青青草久久伊人| 成人国产小视频| 99视频国产精品| 精品人妻一区无码视频| 亚洲永久精品ww47国产| 国产日韩久久久久无码精品| 1769国产精品免费视频| 久久综合结合久久狠狠狠97色| 国产青榴视频在线观看网站| 国产一区二区免费播放| 国产精品人人做人人爽人人添| 国产资源免费观看| 亚洲国产精品一区二区第一页免 | 激情無極限的亚洲一区免费 | 亚洲视频在线青青| 拍国产真实乱人偷精品| 无遮挡一级毛片呦女视频| 亚洲欧美综合另类图片小说区| 97se亚洲综合不卡| 欧美亚洲欧美区| 久草视频精品| 日本在线亚洲|