嵌入式LINUX設(shè)備驅(qū)動(dòng)程序課件_第1頁(yè)
嵌入式LINUX設(shè)備驅(qū)動(dòng)程序課件_第2頁(yè)
嵌入式LINUX設(shè)備驅(qū)動(dòng)程序課件_第3頁(yè)
嵌入式LINUX設(shè)備驅(qū)動(dòng)程序課件_第4頁(yè)
嵌入式LINUX設(shè)備驅(qū)動(dòng)程序課件_第5頁(yè)
已閱讀5頁(yè),還剩47頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

嵌入式LINUX設(shè)備驅(qū)動(dòng)程序課件本講主要內(nèi)容嵌入式linux設(shè)備驅(qū)動(dòng)的基本框架與實(shí)現(xiàn)數(shù)碼管顯示驅(qū)動(dòng)程序分析幀緩沖顯示驅(qū)動(dòng)實(shí)現(xiàn)方法。Linux系統(tǒng)中的設(shè)備文件Linux將所有外部設(shè)備看成是一類特殊文件,稱之為“設(shè)備文件”。如果說(shuō)系統(tǒng)調(diào)用是Linux內(nèi)核和應(yīng)用程序之間的接口,那么設(shè)備驅(qū)動(dòng)程序則可以看成是Linux內(nèi)核與外部設(shè)備之間的接口。設(shè)備驅(qū)動(dòng)程序向應(yīng)用程序屏蔽了硬件在實(shí)現(xiàn)上的細(xì)節(jié),使得應(yīng)用程序可以像操作普通文件一樣來(lái)操作外部設(shè)備Linux設(shè)備驅(qū)動(dòng)在系統(tǒng)中的層次設(shè)備驅(qū)動(dòng)的作用設(shè)備驅(qū)動(dòng)是位于應(yīng)用和物理設(shè)備之間的軟件層,負(fù)責(zé)完成二者間的I/O操作;在LINUX系統(tǒng)里,對(duì)用戶程序,設(shè)備驅(qū)動(dòng)隱藏了設(shè)備的具體細(xì)節(jié),為不同設(shè)備提供了一致的接口;設(shè)備驅(qū)動(dòng)是嵌入式系統(tǒng)開(kāi)發(fā)的重要內(nèi)容之一設(shè)備驅(qū)動(dòng)完成的主要功能對(duì)設(shè)備的初始化和釋放;將數(shù)據(jù)從內(nèi)核傳遞到硬件設(shè)備,以及從硬件讀取數(shù)據(jù);讀取應(yīng)用程序傳送給設(shè)備文件的數(shù)據(jù),并回送應(yīng)用程序請(qǐng)求的數(shù)據(jù)。這需要在用戶空間、內(nèi)核空間、總線以及外設(shè)之間傳輸數(shù)據(jù);檢查和處理設(shè)備出現(xiàn)的錯(cuò)誤。設(shè)備驅(qū)動(dòng)的分類Linux支持3種不同類型的設(shè)備字符設(shè)備塊設(shè)備網(wǎng)絡(luò)接口字符設(shè)備能夠像字節(jié)流一樣被訪問(wèn)的設(shè)備,一般不需要緩存技術(shù),也不支持隨機(jī)訪問(wèn)。典型的字符設(shè)備有:鼠標(biāo)、鍵盤、I/O設(shè)備等。設(shè)備驅(qū)動(dòng)的分類塊設(shè)備支持面向塊訪問(wèn)的設(shè)備,每塊包含2的N次冪字節(jié)數(shù)據(jù),典型的塊大小為512或1024B;大多數(shù)塊設(shè)備允許隨機(jī)訪問(wèn),而且常常采用buffer、cache等緩存技術(shù);塊設(shè)備的訪問(wèn)常常通過(guò)文件系統(tǒng)來(lái)進(jìn)行;典型的塊設(shè)備有:如磁盤、硬盤、光盤驅(qū)動(dòng)器等。設(shè)備驅(qū)動(dòng)的分類網(wǎng)絡(luò)接口能夠和其他主機(jī)交換數(shù)據(jù)的設(shè)備接口。網(wǎng)絡(luò)接口只是面向數(shù)據(jù)包而不是數(shù)據(jù)流,它沒(méi)有被映射為任何設(shè)備文件,其訪問(wèn)要通過(guò)BSD套接口進(jìn)行。設(shè)備驅(qū)動(dòng)的分類主設(shè)備號(hào)與次設(shè)備號(hào)LINUX系統(tǒng)中,設(shè)備由一個(gè)主設(shè)備號(hào)和一個(gè)次設(shè)備號(hào)來(lái)唯一標(biāo)識(shí);主設(shè)備號(hào)唯一標(biāo)識(shí)了設(shè)備類型,即設(shè)備驅(qū)動(dòng)程序類型,它是塊設(shè)備表或字符設(shè)備表中設(shè)備表項(xiàng)的索引。一些典型設(shè)備的主設(shè)備號(hào)已經(jīng)基本固定下來(lái),例如,軟驅(qū)的主設(shè)備號(hào)為2,IDE硬盤的主設(shè)備號(hào)為3等等。設(shè)備宏操作MAJOR()可以獲取主設(shè)備號(hào)。主設(shè)備號(hào)與次設(shè)備號(hào)次設(shè)備號(hào)用于標(biāo)識(shí)使用同一設(shè)備驅(qū)動(dòng)程序的不同硬件,并僅由設(shè)備驅(qū)動(dòng)程序解釋

當(dāng)應(yīng)用程序操作某個(gè)設(shè)備文件時(shí),Linux內(nèi)核根據(jù)其主設(shè)備號(hào)調(diào)用相應(yīng)的驅(qū)動(dòng)程序,并從用戶態(tài)進(jìn)入內(nèi)核態(tài)驅(qū)動(dòng)程序判斷次設(shè)備號(hào),并完成相應(yīng)的硬件操作。

用戶空間和內(nèi)核空間Linux運(yùn)行在2種模式下內(nèi)核模式用戶模式內(nèi)核模式對(duì)應(yīng)內(nèi)核空間,而用戶模式對(duì)應(yīng)用戶空間。驅(qū)動(dòng)程序作為內(nèi)核的一部分,它對(duì)應(yīng)內(nèi)核空間,應(yīng)用程序不能直接訪問(wèn)其數(shù)據(jù),用戶空間和內(nèi)核空間用戶空間和內(nèi)核空間的數(shù)據(jù)傳遞:copy_to_user(void*to,constvoid*from,unsignedlongcount);copy_from_user(void*to,constvoid*from,unsignedlongcount);__copy_to_user()__copy_from_user()第一種方法在復(fù)制數(shù)據(jù)的同時(shí),會(huì)進(jìn)行地址空間的有效性檢查。內(nèi)核設(shè)備驅(qū)動(dòng)模塊設(shè)備驅(qū)動(dòng)程序以兩種方式添加到內(nèi)核:Buildin直接把驅(qū)動(dòng)程序編譯到內(nèi)核代碼中Module以模塊的方式加載驅(qū)動(dòng)程序加載:insmoddriver.o卸載:rmmoddriver查看:lsmodLinux設(shè)備節(jié)點(diǎn)的添加設(shè)備節(jié)點(diǎn)位于/dev路徑下可用如下命令添加dev節(jié)點(diǎn),b代表塊設(shè)備,C表示字符設(shè)備mknod/dev/hda1b(/c)1271 塊設(shè)備,主設(shè)備號(hào)127,次設(shè)備號(hào)1Linux設(shè)備驅(qū)動(dòng)代碼的分布/char:字符設(shè)備驅(qū)動(dòng)源碼;/block:塊設(shè)備驅(qū)動(dòng)源碼;/cdrom:LinuxCDROM驅(qū)動(dòng)源碼。這里可以找到某些特殊的CDROM設(shè)備(如SoundblasterCDROM)。IDE接口的CD驅(qū)動(dòng)位于drivers/ide/ide-cd.c中而SCSICD驅(qū)動(dòng)位于drivers/scsi/scsi.c中。/pci:它包含了PCI偽設(shè)備驅(qū)動(dòng)源碼。這里可以找到關(guān)于PCI子系統(tǒng)映射與初始化的代碼。Linux設(shè)備驅(qū)動(dòng)代碼的分布/scsi:所有的SCSI代碼以及Linux支持的SCSI設(shè)備的設(shè)備驅(qū)動(dòng)。/net:包含網(wǎng)絡(luò)驅(qū)動(dòng)源碼。/sound:所有的聲卡驅(qū)動(dòng)源碼。/video:所有的視頻卡驅(qū)動(dòng)源碼。Linux設(shè)備驅(qū)動(dòng)的代碼結(jié)構(gòu)驅(qū)動(dòng)程序的注冊(cè)與注銷設(shè)備的打開(kāi)與釋放設(shè)備的讀寫操作設(shè)備的控制操作設(shè)備的中斷和輪詢處理等

19設(shè)備驅(qū)動(dòng)的注冊(cè)方法1result=devfs_register_chrdev(0,MOD_NAME,&keypad_fops)if(result<0){ return-ENODEV; }devfs_handle=devfs_register(NULL,MOD_NAME,,result,0,,&keypad_fops,NULL);MOD_NAME:設(shè)備驅(qū)動(dòng)的名稱;keypad_fops:文件操作指針。優(yōu)點(diǎn):無(wú)需手動(dòng)創(chuàng)建設(shè)備節(jié)點(diǎn),由系統(tǒng)自動(dòng)完成。對(duì)于塊設(shè)備的注冊(cè),具有類似函數(shù):devfs_register_blkdev以及操作過(guò)程。設(shè)備驅(qū)動(dòng)的注冊(cè)方法2result=register_chrdev(0,MOD_NAME,&keypad_fops);或者result=register_blkdev(0,MOD_NAME,&keypad_fops);

if(result<0){ return-ENODEV; }mknod/dev/MOD_NAMECMAJORMINOR設(shè)備驅(qū)動(dòng)的注銷方法1devfs_unregister_chrdev(MAJOR,MOD_NAME);或者devfs_unregister_blkdev(MAJOR,MOD_NAME);devfs_unregister(devfs_handle); 方法2unregister_chrdev(Major,MOD_NAME);或者unregister_blkdev(Major,MOD_NAME);rm/dev/MOD_NAME設(shè)備的打開(kāi)與釋放設(shè)備的打開(kāi)與釋放要通過(guò)文件操作結(jié)構(gòu)體中定義的相關(guān)函數(shù)open()和release()來(lái)完成;主要完成設(shè)備的初始化工作以及設(shè)備的釋放。文件操作結(jié)構(gòu)體的定義structfile_operations{ structmodule*owner; ssize_t(*read)(structfile*,char*,size_t,loff_t*); ssize_t(*write)(structfile*,constchar*,size_t,loff_t*); unsignedint(*poll)(structfile*,structpoll_table_struct*); int(*ioctl)(structinode*,structfile*,unsignedint,unsignedlong); int(*mmap)(structfile*,structvm_area_struct*); 文件操作結(jié)構(gòu)體的定義 int(*open)(structinode*,structfile*); int(*release)(structinode*,structfile*); int(*fsync)(structfile*,structdentry*,intdatasync);};文件操作結(jié)構(gòu)體的主要函數(shù)open:用于打開(kāi)文件設(shè)備release:在關(guān)閉文件的調(diào)用read:用于從設(shè)備中讀取數(shù)據(jù)write:向設(shè)備發(fā)送數(shù)據(jù)poll:查詢?cè)O(shè)備是否可讀或可寫ioctl:提供執(zhí)行設(shè)備特定命令的方法fasync:用于設(shè)備的異步通知操作設(shè)備的讀寫字符設(shè)備的讀寫操作可以直接使用read()和write()函數(shù)來(lái)完成,塊設(shè)備的讀寫,需要調(diào)用block_read()和block_write()函數(shù),這2個(gè)函數(shù)向設(shè)備請(qǐng)求表中增加讀寫請(qǐng)求;塊設(shè)備的讀寫是對(duì)內(nèi)存緩沖區(qū)進(jìn)行操作,如果內(nèi)存緩沖區(qū)中沒(méi)有要讀入的數(shù)據(jù),或者緩沖區(qū)中的數(shù)據(jù)需要寫入設(shè)備,可以通過(guò)調(diào)用數(shù)據(jù)結(jié)構(gòu)blk_dev_struct中的函數(shù)request_fn()完成。設(shè)備的控制操作對(duì)設(shè)備的控制操作可通過(guò)文件操作數(shù)據(jù)結(jié)構(gòu)中的ioctl()函數(shù)來(lái)完成。控制操作與具體的設(shè)備有密切關(guān)系,需要根據(jù)設(shè)備實(shí)際情況進(jìn)行具體分析。設(shè)備的輪詢和中斷處理輪詢方式對(duì)于不支持中斷的硬件設(shè)備,讀寫時(shí)需要輪流查詢?cè)O(shè)備的狀態(tài),以便決定隨后的數(shù)據(jù)操作。如果輪詢處理方式的驅(qū)動(dòng)程序被鏈接到內(nèi)核,則意味著查詢過(guò)程中,內(nèi)核一直處于閑置狀態(tài)。解決辦法是使用內(nèi)核定時(shí)器,進(jìn)行定期查詢。設(shè)備的輪詢和中斷處理中斷處理方式硬件在需要的時(shí)候,向內(nèi)核發(fā)出中斷請(qǐng)求信號(hào),而內(nèi)核則負(fù)責(zé)把中斷信號(hào)傳遞給相應(yīng)的設(shè)備驅(qū)動(dòng)。驅(qū)動(dòng)程序必須在設(shè)備驅(qū)動(dòng)的初始化時(shí)申請(qǐng)中斷資源,并注冊(cè)中斷處理函數(shù):申請(qǐng):request_irq(irq,irq_handler,flag,dev_name,dev_id);釋放:free_irq(irq,dev_id);其中irq為申請(qǐng)的中斷線號(hào),irq_handler為注冊(cè)的中斷處理函數(shù),dev_id用于共享中斷信號(hào)線。典型字符驅(qū)動(dòng)程序框架staticstructfile_operationsdemo_fops={ read: demo_read write: demo_write open: demo_open ……};intinit_module(void){ returndemo_init();}用于注冊(cè)設(shè)備驅(qū)動(dòng)、申請(qǐng)中斷線,初始化等voidcleanup_module(void){ demo_cleanup();}用于注銷設(shè)備驅(qū)動(dòng)、釋放中斷線等接口函數(shù)的實(shí)現(xiàn)……Example1PXA270開(kāi)發(fā)系統(tǒng)的按鍵驅(qū)動(dòng)程序與數(shù)碼顯示驅(qū)動(dòng)數(shù)碼顯示源代碼按鍵驅(qū)動(dòng)源代碼調(diào)試驅(qū)動(dòng)程序,使用printk輸出信息,信息的優(yōu)先級(jí)依次為:KERN_EMERGKERN_ALERTKERN_CRITKERN_ERRKERN_WARNINGKERN_NOTICEKERN_INFOKERN_DEBUG如果要在終端輸出信息,編譯選項(xiàng):-Wall–O2根據(jù)/kernel/printk.c的不同設(shè)置,不顯示的信息會(huì)出現(xiàn)在/var/log/messages中驅(qū)動(dòng)調(diào)試方法參見(jiàn)LinuxDeviceDriverschapter3幀緩沖設(shè)備驅(qū)動(dòng)程序LCD分類LCD可由為液晶照明的方式有兩種:傳送式和反射式傳送式屏幕要使用外加光源照明,稱為背光(backlight),照明光源要安裝在LCD的背后。傳送式LCD在正常光線及暗光線下,顯示效果都很好,但在戶外,尤其在日光下,很難辯清顯示內(nèi)容。反射式屏幕,則不需要外加照明電源,使用周圍環(huán)境的光線(或在某些筆記本中,使用前部照明系統(tǒng)的光線)。這樣,反射式屏幕就沒(méi)有背光,所以,此種屏幕在戶外或光線充足的室內(nèi),才會(huì)有出色的顯示效果,但在一般室內(nèi)光線下,這種顯示屏的顯示效果就不及背光傳送式的。

幀緩沖(Framebuffer)幀緩沖(framebuffer)-顯示緩沖區(qū)是Linux為顯示設(shè)備提供的一個(gè)接口,是把顯存抽象后的一種設(shè)備,他允許上層應(yīng)用程序在圖形模式下直接對(duì)顯示緩沖區(qū)進(jìn)行讀寫操作。

Xwindow繪制窗口,顯示漢字都是通過(guò)fb幀緩沖設(shè)備Linux可支持最多32個(gè)/dev/fb0~/dev/fb31缺省是/dev/fb0可以直接拷貝位圖到fb來(lái)顯示到屏幕cp/bitmap/penguin.bin/dev/fb0幀緩沖設(shè)備驅(qū)動(dòng)原理幀緩沖設(shè)備屬于字符設(shè)備,其目的就是通過(guò)配置PXA270的寄存器,在一段指定的內(nèi)存與LCD之間建立一個(gè)自動(dòng)傳輸?shù)耐ǖ?。這樣,任何程序只要修改這段內(nèi)存中的數(shù)據(jù),就可以改變LCD上的顯示內(nèi)容。

幀緩沖設(shè)備的文件操作層接口staticstructfile_operationsfb_fops={

owner:THIS_MODULE,

read:fb_read,/*讀操作*/

write:fb_write,/*寫操作*/

ioctl:fb_ioctl,/*控制操作*/

mmap:fb_mmap,/*映射操作*/

open:fb_open,/*打開(kāi)操作*/

release:fb_release,/*關(guān)閉操作*/

};

其中的成員函數(shù)都在文件linux/driver/video/fbmem.c中定義

幀緩沖設(shè)備的文件操作層接口控制操作函數(shù)fb_ioctl通過(guò)以下參數(shù)來(lái)傳遞控制命令FBIOGET_VSCREENINFOFBIOPUT_VSCREENINFOFBIOGET_FSCREENINFO映射操作函數(shù)fb_mmap將顯示緩存映射到用戶空間幀緩沖設(shè)備的驅(qū)動(dòng)層接口—fb_infostructfb_info{charmodename; /*defaultvideomode*/charfontname; /*defaultfontname*/……structfb_var_screeninfovar;/*Currentvar*/structfb_fix_screeninfofix;/*Currentfix*/……structfb_ops*fbops;char*screen_base;/*Virtualaddress*/……};幀緩沖設(shè)備的驅(qū)動(dòng)層接口—fb_infoModename:設(shè)備名稱;Fontname:顯示字體;fb_var_screeninfo:記錄用戶可修改的顯示控制器參數(shù),包括屏幕分辨率和每個(gè)像素點(diǎn)的比特?cái)?shù),其中的xres定義屏幕一行有多少個(gè)象素點(diǎn),yres定義屏幕一列有多少個(gè)象素點(diǎn),bits_per_pixel定義每個(gè)象素點(diǎn)用多少個(gè)字節(jié)表示;幀緩沖設(shè)備的驅(qū)動(dòng)層接口—fb_infofb_fix_screeninfo:記錄用戶不能修改的顯示控制器的參數(shù),如屏幕緩沖區(qū)的物理地址,長(zhǎng)度。當(dāng)對(duì)幀緩沖設(shè)備進(jìn)行映射操作的時(shí)候,就是從fb_fix_screeninfo中取得緩沖區(qū)物理地址的。Fb_ops:指向底層操作的函數(shù)的指針;結(jié)構(gòu)體fb_info的定義如何寫幀緩沖設(shè)備驅(qū)動(dòng)遵循設(shè)備驅(qū)動(dòng)程序的結(jié)構(gòu),設(shè)備注冊(cè)、定義file_operations接口、初始化LCDC寄存器初始化一個(gè)fb_info結(jié)構(gòu),填充其中的成員變量,并調(diào)用register_framebuffer(&fb_info),將fb_info登記入內(nèi)核。

實(shí)現(xiàn)定義的各個(gè)接口函數(shù)幀緩沖驅(qū)動(dòng)程序—初始化函數(shù)新的FB驅(qū)動(dòng)程序,需要向fbmem.c(drivers/video)中的結(jié)構(gòu)體fb_drivers中添加相應(yīng)的參數(shù)來(lái)給出初始化函數(shù)的入口。staticstruct{ constchar*name; int(*init)(void); int(*setup)(char*);}fb_drivers[]__initdata={#ifdefCONFIG_FB_PXA… {"pxa",pxafb_init,pxafb_setup},#endif……}幀緩沖驅(qū)動(dòng)程序—初始化函數(shù)dbmx1fb_init的主要操作初始化相關(guān)的寄存器初始化一個(gè)fb_info結(jié)構(gòu),填充其中的成員變量利用register_framebuffer()向內(nèi)核注冊(cè)該設(shè)備。

如何寫幀緩沖的應(yīng)用程序在應(yīng)用程序中,操作幀緩沖設(shè)備的一般步驟如下:1.

打開(kāi)/dev/fb設(shè)備文件。2.

用ioctrl操作取得當(dāng)前顯示屏幕的參數(shù),如屏幕分辨率,每個(gè)像素點(diǎn)的比特?cái)?shù)。根據(jù)屏幕參數(shù)可計(jì)算屏幕緩沖區(qū)的大小。3.

將屏幕緩沖區(qū)映射到用戶空間。4.

映射后就可以直接讀寫屏幕緩沖區(qū),進(jìn)行繪圖和圖片顯示典型應(yīng)用的代碼結(jié)構(gòu)(1)intmain()

{

intfbfd=0;

structfb_var_screeninfovinfo;

structfb_fix_screeninfofinfo;

longintscreens

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論