久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

linux驅(qū)動程序?qū)W習(xí)4

 LongAnla 2015-10-19
對于驅(qū)動程序設(shè)計來說,,核心問題之一就是如何完成調(diào)試。當(dāng)前常用的驅(qū)動調(diào)試技術(shù)可分為:
1,,打印調(diào)試
2,,調(diào)試器調(diào)試
3,查詢調(diào)試
打印調(diào)試:在調(diào)試應(yīng)用程序時,,最常用的調(diào)試技術(shù)是打印,,就是在應(yīng)用程序中合適的點調(diào)用printf。當(dāng)調(diào)試內(nèi)核代碼的時候,,可以用printk完成類似任務(wù),。
在驅(qū)動開發(fā)時,printk非常有助于調(diào)試,。但當(dāng)正式發(fā)行驅(qū)動程序時,,應(yīng)該去掉這些打印語句,但你可能很快又發(fā)現(xiàn),,你又需要在驅(qū)動程序中實現(xiàn)一個新功能(或者修復(fù)一個bug),,這時你又要用到那些被刪除的打印語句。這里介紹一種使用printk的合理方法,,可以全局地打開或關(guān)閉它們,,而不是簡單地刪除。
#ifdef PDEBUG
#define PLOG(fmt,args...) printk(KERN_DEBUG "scull:"fmt,##args)
#else
#define PLOG(fmt,args...)  /*do nothing*/
#endif
在 Makefile 中作如下修改:
DEBUG=y
ifeq ($(DEBUG),y)
DEBFLAGS = -o2 -g -DPDEBUG
else
DEBFLAGS = -o2
endif
CFLAGS +=$(DEBFLAGS)
并發(fā)控制:
并發(fā):多個執(zhí)行單元同時被執(zhí)行
競態(tài):并發(fā)的執(zhí)行單元對共享資源(硬件資源和軟件上的全局變量等)的訪問導(dǎo)致的競爭狀態(tài)
例:
if (copy_from_user(&(dev->data[pos]),buf,count))
ret = -EFAULT;
goto out;
假設(shè)有2個進(jìn)程試圖同時向一個設(shè)備的相同位置寫入數(shù)據(jù),,就會造成數(shù)據(jù)混亂。
處理并發(fā)的常用技術(shù)是加鎖或者互斥,,即確保在任何時間只有一個執(zhí)行單元可以操作共享資源,。在linux內(nèi)核中主要通過semaphore機制和spin_lock機制實現(xiàn)。
linux內(nèi)核的信號量在概念和原理上與用戶態(tài)的信號量是一樣的,,但是它不能在內(nèi)核之外使用,,它是一種睡眠鎖。如果有一個任務(wù)想要獲得已經(jīng)被占用的信號量時,信號量會將這個進(jìn)程放入一個等待隊列,,然后讓其睡眠,。當(dāng)持有信號量的進(jìn)程將信號釋放后,處于等待隊列中的任務(wù)將被喚醒,,并讓其獲得信號量,。
信號量在創(chuàng)建時需要設(shè)置一個初始值,表示允許有幾個任務(wù)同時訪問該信號量保護(hù)的共享資源,,初始值為1就變成互斥鎖(Mutex),,即同時只能有一個任務(wù)可以訪問信號量保護(hù)的共享資源。
當(dāng)任務(wù)訪問完被信號量保護(hù)的共享資源后,,必須釋放信號量,,釋放信號量通過把信號量的值加1實現(xiàn),如果釋放后信號量的值為非正數(shù),,表明有任務(wù)等待當(dāng)前信號量,,因此要喚醒等待該信號量的任務(wù)。
信號量的實現(xiàn)也是與體系結(jié)構(gòu)相關(guān)的,,定義在中,, struct semaphore類型用來表示信號量。
1,,定義信號量
struct semaphore sem;
2,,初始化信號量
void sema_init(struct semaphore *sem,int val)
該函數(shù)用于初始化設(shè)置信號量的初值,它設(shè)置信號量sem的值為val
void init_MUTEX(struct semaphore *sem)
該函數(shù)用于初始化一個互斥鎖,,即它把信號量sem的值設(shè)置為1.
void init_MUTEX_LOCKED(struct semaphore *sem)
該函數(shù)也用于初始化一個互斥鎖,,但它把信號量sem的值設(shè)置為0,即一開始就處在已鎖狀態(tài).
定義與初始化的工作可由如下宏一步完成:
DECLARE_MUTEX(name)
定義一個信號量name,并初始化它的值為1
DECLARE_MUTEX_LOCKED(name)
定義一個信號量name,但把它的初始值設(shè)置為0,,即鎖在創(chuàng)建時就處在已鎖狀態(tài),。
3,獲取信號量
void down(struct semaphore *sem)
獲取信號量sem,可能會導(dǎo)致進(jìn)程睡眠,,因此不能在中斷上下文使用該函數(shù),。該函數(shù)將把sem的值減1,如果信號量sem的值非負(fù),,就直接返回,,否則調(diào)用者將被掛起,直到別的任務(wù)釋放該信號量才能繼續(xù)運行,。
int down_interruptible(struct semaphore *sem)
獲取信號量sem,,如果信號量不可用,進(jìn)程將被置為TASK_INTERRUPTIBLE類型的睡眠狀態(tài),。該函數(shù)由返回值來區(qū)分是正常返回還是被信號中斷返回,,如果返回0,,表示獲得信號量正常返回,如果被信號打斷,,返回-EINTR,。
down_killable(struct semaphore *sem)
獲取信號量sem.如果信號量不可用,進(jìn)程將被置為TASK_KILLABLE類型的睡眠狀態(tài),。
注:
down()函數(shù)現(xiàn)已不建議繼續(xù)使用,,建議使用down_killable()或down_interruptible()函數(shù)。
4.釋放信號量
void up(struct semaphore *sem)
該函數(shù)釋放信號量sem,,即把sem的值加1,,如果sem的值為非正數(shù),表明有任務(wù)等待該信號量,,因此喚醒這些等待者,。
自旋鎖:
自旋鎖最多只能被一個可執(zhí)行單元持有。自旋鎖不會引起調(diào)用者睡眠,,如果一個執(zhí)行線程試圖獲得一個已經(jīng)被持有的自旋鎖,,那么線程就會一直進(jìn)行忙循環(huán),一直等待下去,,在那里看是否該自旋鎖的保持者已經(jīng)釋放了鎖,,“自旋”就是這個意思。
spin_lock_init(x)
該宏用于初始化自旋鎖x,自旋鎖在使用前必須先初始化,。
spin_lock(lock)
獲取自旋鎖lock,,如果成功,立即獲得鎖,,并馬上返回,,否則它將一直自旋在那里,直到該自旋鎖的保持者釋放,。
spin_trylock(lock)
試圖獲取自旋鎖lock,,如果能立即獲得鎖,并返回真,,否則立即返回假,。它不會一直等待被釋放。
spin_unlock(lock)
釋放自旋鎖lock,,它與spin_trylock或spin_lock配對使用,。
信號量可能允許有多個持有者,而自旋鎖在任何時候只能允許一個持有者,。當(dāng)然也有信號量叫互斥信號量(只能一個持有者),,允許有多個持有者的信號量叫計數(shù)信號量。
信號量適合于保持時間較長的情況,;而自旋鎖適合于保持時間非常短的情況,,在實際應(yīng)用中自旋鎖控制的代碼只有幾行,而持有自旋鎖的時間也一般不會超過兩次上下文切換的時間,,因為線程一旦要進(jìn)行切換,,就至少花費切出切入兩次,自旋鎖的占用時間如果遠(yuǎn)遠(yuǎn)長于兩次上下文切換,,我們就應(yīng)該選擇信號量,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多