<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 嵌入式Linux設(shè)備驅(qū)動開發(fā)之:字符設(shè)備驅(qū)動編程

          嵌入式Linux設(shè)備驅(qū)動開發(fā)之:字符設(shè)備驅(qū)動編程

          作者: 時間:2013-09-13 來源:網(wǎng)絡(luò) 收藏

          本文引用地址:http://www.ex-cimer.com/article/257111.htm

          (5)釋放設(shè)備。

          釋放設(shè)備的函數(shù)接口是release()。要注意釋放設(shè)備和關(guān)閉設(shè)備是完全不同的。當(dāng)一個進(jìn)程釋放設(shè)備時,其他進(jìn)程還能繼續(xù)使用該設(shè)備,只是該進(jìn)程暫時停止對該設(shè)備的使用;而當(dāng)一個進(jìn)程關(guān)閉設(shè)備時,其他進(jìn)程必須重新打開此設(shè)備才能使用它。

          釋放設(shè)備時要完成的工作如下。

          n 遞減計(jì)數(shù)器MOD_DEC_USE_COUNT(最新版本已經(jīng)不再使用)。

          n 釋放打開設(shè)備時系統(tǒng)所分配的內(nèi)存空間(包括filp->private_data指向的內(nèi)存空間)。

          n 在最后一次釋放設(shè)備操作時關(guān)閉設(shè)備。

          (6)讀寫設(shè)備。

          讀寫設(shè)備的主要任務(wù)就是把內(nèi)核空間的數(shù)據(jù)復(fù)制到用戶空間,或者從用戶空間復(fù)制到內(nèi)核空間,也就是將內(nèi)核空間緩沖區(qū)里的數(shù)據(jù)復(fù)制到用戶空間的緩沖區(qū)中或者相反。這里首先解釋一個read()和write()函數(shù)的入口函數(shù),如表11.5所示。

          表11.5 read、write函數(shù)接口語法要點(diǎn)

          所需頭文件

          #includelinux/fs.h>

          函數(shù)原型

          ssize_t(*read)(structfile*filp,char*buff,size_tcount,loff_t*offp)
          ssize_t(*write)(structfile*filp,constchar*buff,size_tcount,loff_t*offp)

          函數(shù)傳入值

          filp:文件指針

          buff:指向用戶緩沖區(qū)

          count:傳入的數(shù)據(jù)長度

          offp:用戶在文件中的位置

          函數(shù)返回值

          成功:寫入的數(shù)據(jù)長度

          雖然這個過程看起來很簡單,但是內(nèi)核空間地址和應(yīng)用空間地址是有很大區(qū)別的,其中一個區(qū)別是用戶空間的內(nèi)存是可以被換出的,因此可能會出現(xiàn)頁面失效等情況。所以不能使用諸如memcpy()之類的函數(shù)來完成這樣的操作。在這里要使用copy_to_user()或copy_from_user()等函數(shù),它們是用來實(shí)現(xiàn)用戶空間和內(nèi)核空間的數(shù)據(jù)交換的。

          copy_to_user()和copy_from_user()的格式如表11.6所示。

          表11.6 copy_to_user()/copy_from_user()函數(shù)語法要點(diǎn)

          所需頭文件

          #includeasm/uaccess.h>

          函數(shù)原型

          unsignedlongcopy_to_user(void*to,constvoid*from,unsignedlongcount)
          unsignedlongcopy_from_user(void*to,constvoid*from,unsignedlongcount)

          函數(shù)傳入值

          to:數(shù)據(jù)目的緩沖區(qū)

          from:數(shù)據(jù)源緩沖區(qū)

          count:數(shù)據(jù)長度

          函數(shù)返回值

          成功:寫入的數(shù)據(jù)長度
          失敗:-EFAULT

          要注意,這兩個函數(shù)不僅實(shí)現(xiàn)了用戶空間和內(nèi)核空間的數(shù)據(jù)轉(zhuǎn)換,而且還會檢查用戶空間指針的有效性。如果指針無效,那么就不進(jìn)行復(fù)制。

          (7)ioctl。

          大部分設(shè)備除了讀寫操作,還需要硬件配置和控制(例如,設(shè)置串口設(shè)備的波特率)等很多其他操作。在字符中ioctl函數(shù)接口給用戶提供對設(shè)備的非讀寫操作機(jī)制。

          ioctl函數(shù)接口的具體格式如表11.7所示。

          表11.7 ioctl函數(shù)接口語法要點(diǎn)

          所需頭文件

          #includelinux/fs.h>

          函數(shù)原型

          int(*ioctl)(structinode*inode,structfile*filp,unsignedintcmd,unsignedlongarg)

          函數(shù)傳入值

          inode:文件的內(nèi)核內(nèi)部結(jié)構(gòu)指針

          filp:被打開的文件描述符

          cmd:命令類型

          arg:命令相關(guān)參數(shù)

          下面列出其他在驅(qū)動程序中常用的內(nèi)核函數(shù)。

          (8)獲取內(nèi)存。

          在應(yīng)用程序中獲取內(nèi)存通常使用函數(shù)malloc(),但在程序中動態(tài)開辟內(nèi)存可以以字節(jié)或頁面為單位。其中,以字節(jié)為單位分配內(nèi)存的函數(shù)有kmalloc(),注意的是,kmalloc()函數(shù)返回的是物理地址,而malloc()等返回的是線性虛擬地址,因此在驅(qū)動程序中不能使用malloc()函數(shù)。與malloc()不同,kmalloc()申請空間有大小限制。長度是2的整次方,并且不會對所獲取的內(nèi)存空間清零。

          以頁為單位分配內(nèi)存的函數(shù)如下所示。

          n get_zeroed_page():獲得一個已清零頁面。

          n get_free_page():獲得一個或幾個連續(xù)頁面。

          n get_dma_pages():獲得用于DMA傳輸?shù)捻撁妗?/p>

          與之相對應(yīng)的釋放內(nèi)存用也有kfree()或free_page函數(shù)族。

          表11.8給出了kmalloc()函數(shù)的語法格式。

          表11.8 kmalloc()函數(shù)語法要點(diǎn)

          所需頭文件

          #includelinux/malloc.h>

          函數(shù)原型

          void*kmalloc(unsignedintlen,intflags)

          函數(shù)傳入值

          len:希望申請的字節(jié)數(shù)

          flags

          GFP_KERNEL:內(nèi)核內(nèi)存的通常分配方法,可能引起睡眠

          GFP_BUFFER:用于管理緩沖區(qū)高速緩存

          GFP_ATOMIC:為中斷處理程序或其他運(yùn)行于進(jìn)程上下文之外的代碼分配內(nèi)存,且不會引起睡眠

          GFP_USER:用戶分配內(nèi)存,可能引起睡眠

          GFP_HIGHUSER:優(yōu)先高端內(nèi)存分配

          __GFP_DMA:DMA數(shù)據(jù)傳輸請求內(nèi)存

          __GFP_HIGHMEN:請求高端內(nèi)存

          函數(shù)返回值

          成功:寫入的數(shù)據(jù)長度
          失敗:-EFAULT

          linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

          linux相關(guān)文章:linux教程




          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();