Linux設備驅(qū)動-中斷、并發(fā)請求及周期性事件處理_第1頁
Linux設備驅(qū)動-中斷、并發(fā)請求及周期性事件處理_第2頁
Linux設備驅(qū)動-中斷、并發(fā)請求及周期性事件處理_第3頁
Linux設備驅(qū)動-中斷、并發(fā)請求及周期性事件處理_第4頁
Linux設備驅(qū)動-中斷、并發(fā)請求及周期性事件處理_第5頁
已閱讀5頁,還剩24頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1Linux設備驅(qū)動設計中斷、并發(fā)請求及周期性事件處理2大綱Linux內(nèi)核中斷處理Linux內(nèi)核異步數(shù)據(jù)處理_kfifoLinux內(nèi)核并發(fā)與同步機制Linux下延時與內(nèi)核定時器3大綱Linux內(nèi)核中斷處理Linux內(nèi)核異步數(shù)據(jù)處理_kfifoLinux內(nèi)核并發(fā)與同步機制Linux下延時與內(nèi)核定時器4Linux內(nèi)核中斷處理

Linux操作系統(tǒng)下同裸機程序一樣,需要利用中斷機制來處理硬件的異步事件,但用戶態(tài)不允許中斷事件,因此中斷必須由設備驅(qū)動程序來接收與處理同裸機一樣,linux下的中斷分為兩種:irq、fiq

fiq又稱快速中斷,在此期間機器的其他部分被鎖定,不會響應其它任何中斷

irq又稱慢速中斷,處理需要較長的時間,在此期間可能發(fā)生其它更高等級的中斷如果CPU接收到一個中斷,它會停止一切工作,調(diào)用中斷處理函數(shù),此時進程調(diào)度也會停止,所以就要求我們的中斷處理一定要快5Linux內(nèi)核中斷處理#include

<asm/irq.h>

//內(nèi)核中使用中斷需添加此文件//申請中斷intrequest_irq(unsignedintirq,

void(*handler)(int,void*,structpt_regs*),

unsignedlongirqflag,

constchar*devname,void*dev_id);參數(shù)1:中斷號,所申請的中斷向量,比如EXIT0、uart中斷等參數(shù)2:中斷服務程序參數(shù)3:中斷屬性設置//SA_INTERRUPT,

快速中斷,禁止其他中斷//SA_SHIRQ,

共享中斷//SA_SAMPLE_RANDOM,

中斷可能被用來產(chǎn)生隨機數(shù)//

dev_id:

在共享中斷時用于區(qū)分不同的中斷處理程序參數(shù)4:中斷名字,cat/proc/interrupts可察看系統(tǒng)中斷申請與使用情況參數(shù)5:中斷參數(shù),作為共享中斷時的中斷區(qū)別參數(shù)6Linux內(nèi)核中斷處理//釋放中斷voidfree_irq(unsignedintirq,void*dev_id);參數(shù)1:所要清除中斷服務程序的中斷號參數(shù)2:中斷參數(shù),同申請時的值一致//使能中斷voidenable_irq(unsignedintirq);//禁止中斷voiddisable_irq(unsignedintirq);參數(shù):中斷號7Linux內(nèi)核中斷處理#include

<asm/irq.h>//S3C2410使能GPIO的外部中斷功能intset_external_irq(intirq,intedge,intpullup);//參數(shù)1:中斷號//參數(shù)2:外部中斷觸發(fā)方式//EXT_LOWLEVEL,//EXT_HIGHLEVEL,//EXT_FALLING_EDGE,//EXT_RISING_EDGE,//EXT_BOTH_EDGES//參數(shù)3:上拉是否使能0:使能1:禁止8Linux內(nèi)核中斷處理//示例//中斷處理程序voidhandler(intirq,void*dev_id,structpt_regs*regs){//中斷處理}參數(shù)1:中斷號,在不同中斷共用一個中斷服務程序時區(qū)分各中斷參數(shù)2:中斷參數(shù),不同設備分享同一中斷時,區(qū)分中斷來源參數(shù)3:發(fā)生中斷時寄存器上保存的值傳遞給regs,通常不使用本參數(shù)//在初始化時申請并初始化中斷set_external_irq(IRQ_EINT0,EXT_FALLING_EDGE,0);request_irq(IRQ_EINT0,handler,SA_INTERRUPT,"KEY",NULL);9驅(qū)動程序?qū)ι蠈犹峁┑膔ead/write方法并不直接完成硬件的數(shù)據(jù)操作中斷處理程序相對獨立read/write方法與中斷通過緩沖區(qū)交換數(shù)據(jù)帶有中斷的驅(qū)動結構10大綱Linux內(nèi)核中斷處理Linux內(nèi)核異步數(shù)據(jù)處理_kfifoLinux內(nèi)核并發(fā)與同步機制Linux下延時與內(nèi)核定時器11Kfifo的使用

在驅(qū)動編程中,經(jīng)常會遇到異步數(shù)據(jù)處理的情況,比如采用中斷或定時器處理數(shù)據(jù)輸入輸出等情況

此時數(shù)據(jù)的采集與處理往往不同步,于是驅(qū)動編程中數(shù)據(jù)采集方需要將采集的數(shù)據(jù)暫時放到一個緩沖區(qū)中,使用方在需要處理數(shù)據(jù)時從緩沖區(qū)中將數(shù)據(jù)讀出驅(qū)動編程中常采用隊列這種數(shù)據(jù)結構來實現(xiàn)整個過程,我們可以選擇自己編寫一個隊列,也可以利用內(nèi)核中現(xiàn)有隊列kfifo來實現(xiàn)12并發(fā)請求#include<linux/kfifo.h>//為防止多個程序同時訪問該隊列,需要定義一個自旋鎖,該鎖由kfifo維護,我們只需要定義它即可staticspinlock_tbuffer_lock=SPIN_LOCK_UNLOCKED;//定義一個kfifo指針staticstructkfifo*buffer;//使用kfifo_alloc創(chuàng)建一個BUFFER_SIZE大小的fifo,所有空間由kfifo自動分配#defineBUFFER_SIZE 256buffer=kfifo_alloc(BUFFER_SIZE,GFP_KERNEL,

&buffer_lock);13并發(fā)請求//使用kfifo_put將數(shù)據(jù)放入kfifo內(nèi)kfifo_put(buffer,&key,sizeof(key));//使用kfifo_len檢查fifo內(nèi)的可用數(shù)據(jù)//使用kfifo_get從fifo內(nèi)取出數(shù)據(jù)if(kfifo_len(buffer)>=sizeof(key))kfifo_get(buffer,&key,sizeof(key));//釋放創(chuàng)建的FIFOkfifo_free(buffer);14大綱Linux內(nèi)核中斷處理Linux內(nèi)核異步數(shù)據(jù)處理_kfifoLinux內(nèi)核并發(fā)與同步機制Linux下延時與內(nèi)核定時器15并發(fā)請求

中斷處理、多任務環(huán)境、多處理器(SMP)是現(xiàn)代操作系統(tǒng)的特征當多個進程、線程或中斷、正常用戶程序同時訪問同一個資源,可能導致錯誤

因此內(nèi)核需要提供并發(fā)控制機制,對公共資源的訪問進行同步控制,確保共享資源的安全訪問

linux中包含了眾多的同步機制,包括信號量、自旋鎖、原子操作、讀寫鎖等16并發(fā)請求

自旋鎖是一種輕量級的多處理器間的同步機制它是一種忙等待機制,它要求持有鎖的進程或應用程序所占用的時間盡可能短,因為此時別的進程或應用程序正在高速運轉(zhuǎn)并等待鎖的釋放,所以不能長時間占有

信號量是一種睡眠鎖,如果有一個任務試圖獲得一個已經(jīng)被占用的信號量時,信號量會將其推進一個等待隊列,然后讓其睡眠。當持有信號量的進程將信號量釋放后,處于等待隊列中的那個任務將被喚醒,并獲得該信號量。這就比自旋鎖提供更好的處理器利用率,因為把時間花費在忙等待上,但是,信號量比自旋鎖有更大的開銷。17并發(fā)請求<linux/spinlock.h>中。//定義自旋鎖,在編譯時對自旋鎖的初始化:spinlock_t

my_lock=SPIN_LOCK_UNLOCKED;//在使用中初始化自旋鎖void

spin_lock_init(spinlock_t*lock);//獲得自旋鎖,進入臨界區(qū),自旋鎖忙則自旋等待:spin_lock(&my_lock);//嘗試獲得自旋鎖,成功返回真,失敗則返回假int

spin_trylock(spinlock_t*lock);//釋放自旋鎖,退出臨界區(qū)spin_unlock(&my_lock);18并發(fā)請求//使用信號量控制并發(fā)請求#include

<asm/semaphore.h>//定義信號量變量structsemaphorebufflock;//初始化信號量voidsema_init(structsemaphore*sem,int);//獲?。ǖ却┬盘柫浚荒鼙淮驍?,會導致調(diào)用者睡眠voiddown(structsemaphore*sem);//獲取(等待)信號量(可被其它信號打斷)intdown_interruptible(structsemaphore*sem);//嘗試獲得信號量,如過可獲得,他就獲得信號量并返回0,否則返回非0,不會導致調(diào)用者睡眠intdown_trylock(structsemaphore*sem);//釋放信號量,即使信號量加1voidup(structsemaphore*sem);19大綱Linux內(nèi)核中斷處理Linux內(nèi)核異步數(shù)據(jù)處理_kfifoLinux內(nèi)核并發(fā)與同步機制Linux下延時與內(nèi)核定時器20周期性事件處理在驅(qū)動編程中經(jīng)常會用到一些延時函數(shù)或內(nèi)核定時器來處理周期性事件

內(nèi)核中的短延時常用以下函數(shù):

ndelay(n)//納秒級延時

udelay(n)//微秒級延時

mdelay(n)//毫秒級延時這三個延時函數(shù)輸入忙等待,一般不太長的時間可以用它21周期性事件處理內(nèi)核中有一個非常重要的全局變量:jiffies它是一個無符號32位整數(shù),用來記錄自內(nèi)核上一次啟動以來的時鐘滴答數(shù)

在不同的平臺中,此時鐘滴答不一樣,在ARM平臺,一般為1/100s

我們可以利用此函數(shù)做一些延時操作,例如系統(tǒng)中給出了以下幾個時間比較宏

#definetime_after(a,b)//a是否在b之后#definetime_before(a,b)//a是否在b之前#definetime_after_eq(a,b)//a是否在b之后或等于b#definetime_after_eq(a,b)//a是否在b之前或等于b22周期性事件處理//使用定時器處理周期性事件#include

<linux/timer.h>//定義定時器structtimer_lists//內(nèi)核原型{

structlist_headlist;

//用來形成鏈表,由內(nèi)核管理,申請一個定時器,自動加入鏈表

unsignedlongexpires;

//定時器到期時間(指定一個時刻,而不是時間周期):

jiffies,HZ

unsignedlongdata;

//作為參數(shù)被傳入定時器處理函數(shù)

void(*function)(unsignedlong);

//定時器處理函數(shù)};23周期性事件處理//初始化定時器把鏈表前后置空voidinit_timer(structtimer_list*timer);//添加定時器,加入鏈表。開始起作用voidadd_timer(structtimer_list*timer);//刪除定時器intdel_timer(structtimer_list*timer);voidtimerHandler(unsignedlongdata){//data:定時器參數(shù)}24周期性事件處理//定時器示例structtimer_listmyTimer;

init_timer(&myTimer);myTimer.expires=jiffies+3*HZ;myTimer.data=0L;myTimer.function=timerHandler;add_timer(&myTimer);//定時器處理函數(shù)voidtimerHandler(unsignedlongdata){//如需重復執(zhí)行,需要重新初始化并啟動定時器myTimer.expires=jiffies+3*HZ;add_timer(&myTimer);}25周期性事件處理//使用內(nèi)核線程處

溫馨提示

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

評論

0/150

提交評論