新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 嵌入式Linux設備驅動開發之:字符設備驅動編程

        嵌入式Linux設備驅動開發之:字符設備驅動編程

        作者: 時間:2013-09-13 來源:網絡 收藏

        本文引用地址:http://www.104case.com/article/257111.htm

        (5)釋放設備。

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

        釋放設備時要完成的工作如下。

        n 遞減計數器MOD_DEC_USE_COUNT(最新版本已經不再使用)。

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

        n 在最后一次釋放設備操作時關閉設備。

        (6)讀寫設備。

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

        表11.5 read、write函數接口語法要點

        所需頭文件

        #includelinux/fs.h>

        函數原型

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

        函數傳入值

        filp:文件指針

        buff:指向用戶緩沖區

        count:傳入的數據長度

        offp:用戶在文件中的位置

        函數返回值

        成功:寫入的數據長度

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

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

        表11.6 copy_to_user()/copy_from_user()函數語法要點

        所需頭文件

        #includeasm/uaccess.h>

        函數原型

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

        函數傳入值

        to:數據目的緩沖區

        from:數據源緩沖區

        count:數據長度

        函數返回值

        成功:寫入的數據長度
        失?。?EFAULT

        要注意,這兩個函數不僅實現了用戶空間和內核空間的數據轉換,而且還會檢查用戶空間指針的有效性。如果指針無效,那么就不進行復制。

        (7)ioctl。

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

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

        表11.7 ioctl函數接口語法要點

        所需頭文件

        #includelinux/fs.h>

        函數原型

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

        函數傳入值

        inode:文件的內核內部結構指針

        filp:被打開的文件描述符

        cmd:命令類型

        arg:命令相關參數

        下面列出其他在驅動程序中常用的內核函數。

        (8)獲取內存。

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

        以頁為單位分配內存的函數如下所示。

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

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

        n get_dma_pages():獲得用于DMA傳輸的頁面。

        與之相對應的釋放內存用也有kfree()或free_page函數族。

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

        表11.8 kmalloc()函數語法要點

        所需頭文件

        #includelinux/malloc.h>

        函數原型

        void*kmalloc(unsignedintlen,intflags)

        函數傳入值

        len:希望申請的字節數

        flags

        GFP_KERNEL:內核內存的通常分配方法,可能引起睡眠

        GFP_BUFFER:用于管理緩沖區高速緩存

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

        GFP_USER:用戶分配內存,可能引起睡眠

        GFP_HIGHUSER:優先高端內存分配

        __GFP_DMA:DMA數據傳輸請求內存

        __GFP_HIGHMEN:請求高端內存

        函數返回值

        成功:寫入的數據長度
        失敗:-EFAULT

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

        linux相關文章:linux教程




        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 阳江市| 汝南县| 迁西县| 伊吾县| 定结县| 晋州市| 辛集市| 临猗县| 邢台县| 司法| 石屏县| 荥阳市| 枣强县| 巴中市| 吉水县| 彰化县| 茌平县| 视频| 樟树市| 洛浦县| 绥化市| 永胜县| 新绛县| 瑞安市| 綦江县| 弥勒县| 梅河口市| 修武县| 永仁县| 双柏县| 潼关县| 出国| 凤城市| 克什克腾旗| 通山县| 鲁甸县| 炎陵县| 上虞市| 宜兰县| 信丰县| 昌吉市|