版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
嵌入式操作系統(tǒng)第十八章嵌入式Linux驅(qū)動開發(fā)戚隆寧〔一〕Linux驅(qū)動概述Linux下驅(qū)動程序主要特點(diǎn)宿主為Linux內(nèi)核靜態(tài)鏈接動態(tài)加載總體分為3類字符設(shè)備驅(qū)動塊設(shè)備驅(qū)動網(wǎng)絡(luò)設(shè)備驅(qū)動設(shè)備被抽象為文件進(jìn)行訪問允許中斷的局部處理被推遲執(zhí)行以保證實時性嵌入式Linux驅(qū)動開發(fā)Linux驅(qū)動概述Linux驅(qū)動的架構(gòu)Linux驅(qū)動的中斷機(jī)制嵌入式Linux驅(qū)動的構(gòu)建〔一〕Linux驅(qū)動概述驅(qū)動程序的宿主Linux驅(qū)動在內(nèi)核空間可在生成內(nèi)核鏡像時被靜態(tài)編譯鏈接進(jìn)內(nèi)核也可將驅(qū)動編譯為模塊,在內(nèi)核運(yùn)行時動態(tài)的將驅(qū)動模塊加載進(jìn)內(nèi)核運(yùn)行KernelDriverKernelDriverinsmod〔一〕Linux驅(qū)動概述共分為三類設(shè)備驅(qū)動字符設(shè)備驅(qū)動字符設(shè)備指以字符為單位以串行順序進(jìn)行訪問的設(shè)備,一般不需要快速緩沖如:打印機(jī)、觸摸屏、串口、磁帶機(jī)驅(qū)動器等塊設(shè)備驅(qū)動塊設(shè)備指以一定大小的數(shù)據(jù)塊為單位可進(jìn)行隨機(jī)位置訪問的設(shè)備,一般需要快速緩沖如:磁盤、光盤、閃存等網(wǎng)絡(luò)設(shè)備驅(qū)動網(wǎng)絡(luò)設(shè)備是通過網(wǎng)絡(luò)傳輸數(shù)據(jù)的設(shè)備,這類驅(qū)動面向數(shù)據(jù)包的收發(fā)設(shè)計,架構(gòu)與接口與以上兩種完全不同Linux中的驅(qū)動根本都屬于這三類但有些特殊的復(fù)雜驅(qū)動〔如LCD驅(qū)動〕也有其獨(dú)特的驅(qū)動體系結(jié)構(gòu)我們重點(diǎn)關(guān)注的還應(yīng)是字符設(shè)備驅(qū)動與塊設(shè)備驅(qū)動〔一〕Linux驅(qū)動概述設(shè)備文件在Linux中通過文件的形式訪問設(shè)備〔網(wǎng)絡(luò)設(shè)備除外〕可以使用和操作文件相同的、標(biāo)準(zhǔn)的系統(tǒng)調(diào)用接口來完成翻開、關(guān)閉、讀寫和I/O控制操作,對用戶來說,設(shè)備文件與普通文件并無區(qū)別字符設(shè)備和塊設(shè)備是通過文件節(jié)點(diǎn)訪問的。在Linux的文件系統(tǒng)中,設(shè)備有對應(yīng)的文件名,稱這種文件為設(shè)備文件,一般位于/dev目錄下如:/dev/hda1、/dev/lp0等〔一〕Linux驅(qū)動概述設(shè)備文件在Linux中通過文件的形式訪問設(shè)備〔網(wǎng)絡(luò)設(shè)備除外〕每個設(shè)備用一個主設(shè)備號和次設(shè)備號標(biāo)識主設(shè)備號:標(biāo)識該設(shè)備的種類,也標(biāo)識了該設(shè)備所使用的驅(qū)動程序次設(shè)備號:標(biāo)識使用同一設(shè)備驅(qū)動程序的不同硬件設(shè)備可采用mknod命令創(chuàng)立設(shè)備文件節(jié)點(diǎn)例如:mknodflowledc2490〔一〕Linux驅(qū)動概述設(shè)備文件設(shè)備文件的例子可以通過文件系統(tǒng)的系統(tǒng)調(diào)用接口 open〔〕、write〔〕、read〔〕、close〔〕 或C庫函數(shù)fopen〔〕、fwrite〔〕、fread〔〕、fclose〔〕等 來訪問字符設(shè)備與塊設(shè)備〔一〕Linux驅(qū)動概述驅(qū)動的中斷處理驅(qū)動程序向系統(tǒng)申請中斷及釋放中斷中斷的局部非緊急處理可推遲執(zhí)行中斷執(zhí)行時間盡可能短以保證實時性中斷處理的工作量并不小〔一〕Linux驅(qū)動概述驅(qū)動的中斷處理中斷的局部非緊急處理可推遲執(zhí)行中斷執(zhí)行時間盡可能短以保證實時性中斷處理的工作量并不小頂半部〔緊急的硬件操作〕中斷底半部〔推遲處理的耗時操作〕頂半部完成最重要的操作,如讀取存放器狀態(tài)、清中斷等,不能被中斷底半部完成后續(xù)大多數(shù)工作,可以被中斷營造了一個和諧的中斷環(huán)境!〔二〕Linux驅(qū)動的架構(gòu)Linux驅(qū)動程序在系統(tǒng)架構(gòu)中應(yīng)用程序Linux系統(tǒng)調(diào)用C庫硬件文件系統(tǒng)〔VFS〕磁盤文件系統(tǒng)塊設(shè)備驅(qū)動字符設(shè)備驅(qū)動套接字TCP/IP網(wǎng)絡(luò)設(shè)備驅(qū)動進(jìn)程管理內(nèi)存管理〔二〕Linux驅(qū)動的架構(gòu)Linux驅(qū)動程序表現(xiàn)為內(nèi)核模塊Linux內(nèi)核運(yùn)行時動態(tài)擴(kuò)展的一種技術(shù)一組可以動態(tài)加載/卸載的程序Linux驅(qū)動以內(nèi)核模塊的方式實現(xiàn)通過insmod動態(tài)加載進(jìn)內(nèi)核通過rmmod從內(nèi)核卸載〔二〕Linux驅(qū)動的架構(gòu)Linux內(nèi)核模塊框架staticintinit_routine(void){ …}voidcleanup_routine(void){ …}module_init(init_routine);module_exit(cleanup_routine);MODULE_LICENSE("GPL");〔二〕Linux驅(qū)動的架構(gòu)Linux驅(qū)動程序編程框架初始化設(shè)備初始化硬件,注冊設(shè)備,創(chuàng)立設(shè)備節(jié)點(diǎn)…定義需要實現(xiàn)的功能函數(shù)按照規(guī)定的接口定義所需要的功能函數(shù)中斷處理申請中斷,編寫中斷效勞例程卸載設(shè)備與初始化相反…〔二〕Linux驅(qū)動的架構(gòu)字符設(shè)備驅(qū)動的接口file_operations數(shù)據(jù)結(jié)構(gòu)在驅(qū)動中實現(xiàn)當(dāng)應(yīng)用程序調(diào)用文件系統(tǒng)調(diào)用時將會調(diào)用這些函數(shù)可以有選擇性的實現(xiàn)〔二〕Linux驅(qū)動的架構(gòu)字符設(shè)備驅(qū)動的接口staticstructfile_operationsdriver_fops={ //填寫需要實現(xiàn)的函數(shù)指針};int__initinit_routine(void){ //初始化設(shè)備}voidcleanup_routine(void){ //卸載設(shè)備}〔二〕Linux驅(qū)動的架構(gòu)定義需要的功能函數(shù)staticintmy_open(structinode*inode,structfile*filp){設(shè)備翻開時的操作…}staticintmy_release(structinode*inode,structfile*filp){設(shè)備關(guān)閉時的操作…}staticintmy_read(structfile*file,constchar*buffer,size_tcount,loff_t*ppos){設(shè)備讀取時的操作…}〔二〕Linux驅(qū)動的架構(gòu)定義需要的功能函數(shù)Staticintmy_ioctl(structinode*inode,structfile*filp,unsignedintcmd,unsignedlongarg){設(shè)備的控制操作……}staticstructfile_operationsmy_fops={對文件操作結(jié)構(gòu)體成員定義初始值…}staticintmy_write(structfile*file,constchar*buffer,size_tcount,loff_t*ppos){設(shè)備寫入時的操作…}〔二〕Linux驅(qū)動的架構(gòu)file_operations結(jié)構(gòu)體初始化staticstructfile_operationsmy_fops={ .owner=THIS_MODULE, .read=my_read, .write=my_write, .ioctl=my_ioctl, .open=my_open, .release=my_release,};NotANSIC,ButGNUC!〔二〕Linux驅(qū)動的架構(gòu)內(nèi)核與用戶空間數(shù)據(jù)交換方式copy_to_user(void__user*to,constvoid*from,unsignedlongn);copy_from_user(void*to,constvoid__user*from,unsignedlongn);在字符設(shè)備驅(qū)動中,一般用于read、write操作:例如:
staticintmy_read(structfile*file,constchar*buffer,size_tcount,loff_t*ppos) { …
copy_to_user(buffer,&my_var,sizeof(int)); … }〔二〕Linux驅(qū)動的架構(gòu)塊設(shè)備驅(qū)動的接口block_device_operations數(shù)據(jù)結(jié)構(gòu)structblock_device_operations{int(*open)(structinode*,structfile*);/*翻開*/int(*release)(structinode*,structfile*);/*釋放*/int(*ioctl)(structinode*,structfile*,unsigned,unsignedlong);long(*unlocked_ioctl)(structfile*,unsigned,unsignedlong);long(*compat_ioctl)(structfile*,unsigned,unsignedlong);int(*direct_access)(structblock_device*,sector_t,unsignedlong*);int(*media_changed)(structgendisk*);/*介質(zhì)被改變?*/int(*revalidate_disk)(structgendisk*);/*使介質(zhì)改變*/int(*getgeo)(structblock_device*,structhd_geometry*);/*填充驅(qū)動器信息*/structmodule*owner;/*模塊擁有者,一般初始化為THIS_MODULE*/};〔二〕Linux驅(qū)動的架構(gòu)塊設(shè)備驅(qū)動的接口block_device_operations主要成員函數(shù)作用1.翻開和釋放int(*open)(structinode*inode,structfile*filp);int(*release)(structinode*inode,structfile*filp);當(dāng)設(shè)備翻開和關(guān)閉時將調(diào)用它們2.IO控制int(*ioctl)(structinode*inode,structfile*filpuusignwdintcmd,unsignedlongarg)上述函數(shù)是ioctrl()系統(tǒng)調(diào)用的實現(xiàn),塊設(shè)備包含大量的標(biāo)準(zhǔn)請求,這些標(biāo)準(zhǔn)請求由linux塊設(shè)備層處理,因此大局部塊設(shè)備驅(qū)動的ioctrl〔〕函數(shù)相當(dāng)短〔二〕Linux驅(qū)動的架構(gòu)塊設(shè)備驅(qū)動的接口block_device_operations主要成員函數(shù)作用3.介質(zhì)改變int(*check_media_change)(kdev_t);被內(nèi)核調(diào)用來檢查是否驅(qū)動器中的介質(zhì)已經(jīng)改變,如果是,那么返回一個非0值,否那么返回0.這個函數(shù)進(jìn)時用于支持可移動介質(zhì)的驅(qū)動器。通常需要在驅(qū)動中增加一個表示介質(zhì)狀態(tài)時否改變的標(biāo)志變量,非可移動設(shè)備的驅(qū)動不需要實現(xiàn)這個方法?!捕矻inux驅(qū)動的架構(gòu)塊設(shè)備驅(qū)動的接口block_device_operations主要成員函數(shù)作用4.使介質(zhì)有效int(*revalidate)(kdev_t);該函數(shù)被調(diào)用來響應(yīng)一個介質(zhì)改變,它給驅(qū)動一個時機(jī)來進(jìn)行必要的工作使得新介質(zhì)準(zhǔn)備好?!捕矻inux驅(qū)動的架構(gòu)塊設(shè)備驅(qū)動的接口block_device_operations主要成員函數(shù)作用5.獲得驅(qū)動信息int(*getgeo)(structblock_device
*,structhd_geometry*);該函數(shù)根據(jù)驅(qū)動器的幾何信息填充一個hd_geometry結(jié)構(gòu)體,hd_geometry結(jié)構(gòu)體包含磁頭,扇區(qū),柱面等信息?!捕矻inux驅(qū)動的架構(gòu)塊設(shè)備驅(qū)動的接口為何沒有數(shù)據(jù)I/O的接口函數(shù)?voidrequest〔request_queue_t*queue〕該函數(shù)不能由驅(qū)動自己調(diào)用,只有內(nèi)核認(rèn)為應(yīng)該讓驅(qū)動處理對設(shè)備的讀寫時才會調(diào)用該函數(shù)〔二〕Linux驅(qū)動的架構(gòu)塊設(shè)備驅(qū)動的接口為何沒有數(shù)據(jù)I/O的接口函數(shù)?voidrequest〔request_queue_t*queue〕該函數(shù)不能由驅(qū)動自己調(diào)用,只有內(nèi)核認(rèn)為應(yīng)該讓驅(qū)動處理對設(shè)備的讀寫時才會調(diào)用該函數(shù)這是由塊設(shè)備數(shù)據(jù)讀寫的特點(diǎn)決定的!緩沖區(qū)的存在,使得對扇區(qū)的讀寫順序可以被調(diào)整,以使分散的訪問變得連續(xù)以提提高性能〔二〕Linux驅(qū)動的架構(gòu)塊設(shè)備驅(qū)動的接口請求扇區(qū)1請求扇區(qū)22請求扇區(qū)3請求扇區(qū)2請求扇區(qū)1請求扇區(qū)2請求扇區(qū)3請求扇區(qū)22〔三〕Linux驅(qū)動的中斷機(jī)制申請及釋放中斷申請中斷Request_irq()的定義:
intrequest_irq(unsignedintirq,
void(*handler)(intirq,void*dev_id,structpt_regs*regs),
unsignedlongirqflags,
constchar*devname,
void*dev_id);irq是要申請的硬件中斷號handler是向系統(tǒng)登記的中斷處理函數(shù),為回調(diào)函數(shù);產(chǎn)生中斷時系統(tǒng)調(diào)用該函數(shù),dev_id參數(shù)將被傳遞給它釋放中斷函數(shù):voidfree_irq(unsignedintirq,void*dev_id);〔三〕Linux驅(qū)動的中斷機(jī)制中斷的底半部機(jī)制tasklet工作隊列〔三〕Linux驅(qū)動的中斷機(jī)制中斷的底半部機(jī)制tasklet自己定義一個小任務(wù)函數(shù),由該函數(shù)完成后續(xù)工作定義一個tasklet結(jié)構(gòu),并將該結(jié)構(gòu)與小任務(wù)函數(shù)關(guān)聯(lián)采用相應(yīng)的系統(tǒng)調(diào)用可轉(zhuǎn)入該小任務(wù)函數(shù)〔即為底半部〕執(zhí)行tasklet仍在中斷上下文中,不能掛起,但頂半部可以響應(yīng)中斷〔三〕Linux驅(qū)動的中斷機(jī)制中斷的底半部機(jī)制tasklet定義一個小任務(wù)函數(shù)voidmy_tasklet_func(void);定義一個tasklet結(jié)構(gòu)my_tasklet,與my_tasklet_func函數(shù)關(guān)聯(lián)DECLARE_TASKLET(my_tasklet,my_tasklet_func,data);在中斷中采用如下方式可轉(zhuǎn)入底半部函數(shù)my_tasklet_functasklet_schedule(&my_tasklet)
〔三〕Linux驅(qū)動的中斷機(jī)制中斷的底半部機(jī)制工作隊列將工作交給內(nèi)核線程執(zhí)行允許重新調(diào)度或睡眠與tasklet使用的區(qū)別假設(shè)推后執(zhí)行的任務(wù)不需要休眠掛起那么可采用tasklet〔三〕Linux驅(qū)動的中斷機(jī)制中斷的底半部機(jī)制Discussion:中斷一定需要底半部嗎?〔四〕嵌入式Linux驅(qū)動的構(gòu)建編輯代碼及配置文件在相應(yīng)的驅(qū)動目錄下建立驅(qū)動源文件在/linux/driver/char/my_char/下面新建一個my_testchar.c按照上述標(biāo)準(zhǔn)編寫需要的源代碼修改Kconfig和Makefile在相應(yīng)的字符型驅(qū)動的目錄頂部的Kconfig中添加如下語句: configMY_TESTCHAR tristate"my_testchar"在相同目錄下的Makefile中添加如下語句: obj-$(CONFIG_MY_T
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 高考物理總復(fù)習(xí)專題十一交變電流第1講交變電流的產(chǎn)生和描述練習(xí)含答案
- 清算風(fēng)險管理協(xié)議
- 油漆購銷合同范例
- 九年級道德與法治上冊 第一單元 富強(qiáng)與創(chuàng)新 第一課 踏上強(qiáng)國之路 第2框走向共同富裕教案1 新人教版
- 二年級品德與生活上冊 玩中有發(fā)現(xiàn)教案1 首師大版
- 2024-2025學(xué)年新教材高中生物 第四章 生物的變異 第一節(jié) 基因突變可能引起性狀改變教案(2)浙科版必修2
- 2024-2025學(xué)年高中歷史 第一單元 第1課 第一次世界大戰(zhàn)的爆發(fā)教案1 新人教版選修3
- 2024-2025學(xué)年高中地理 第二章 中國的主要自然災(zāi)害 2.1 自然資源利用中存在的問題教案 中圖版選修6
- 廣東省佛山市順德區(qū)江義初級中學(xué)九年級化學(xué)上冊 3.1 分子和原子教案3 (新版)新人教版
- 2023七年級語文下冊 第四單元 寫作 怎樣選材配套教案 新人教版
- 品牌管理智慧樹知到課后章節(jié)答案2023年下齊魯工業(yè)大學(xué)
- 比亞迪財務(wù)報表分析
- 水壓試驗報告(帶曲線圖)
- Units68單元大單元教學(xué)設(shè)計課件英語七年級上冊
- 2023年CSCO尿路上皮癌診療指南
- 在高三學(xué)生月考總結(jié)表彰會上的講話
- 高價值醫(yī)療設(shè)備產(chǎn)品定價過程
- 保險行業(yè)創(chuàng)說會-課件
- 初中語文-江城子·密州出獵蘇軾教學(xué)設(shè)計學(xué)情分析教材分析課后反思
- 壓裂隊安全管理制度
- -讓生活更美好 作文批改評語
評論
0/150
提交評論