嵌入式Linux驅動程式 基礎篇 前和後半部

2021-08-23 14:03:03 字數 1766 閱讀 3890

前和後半部

實際開發中,我們常常會面對乙個問題:中斷處理應當如何去處理乙個較長時間的任務。我們都知道,中斷處理不能被阻塞過長時間,不然就影響中斷的效率。既要保證工作量大,又要保證中斷速度快,確實是很難解決的難題。因此,核心開發者就通過前和後半部的方法來解決這難題。

核心開發者將中斷分為2部分處理,前半部分實際響應中斷的入口,即我們request_irq註冊時所傳遞的中斷處理函式。後半部則是前半部排程來延後執行的函式,後半部就可以執行大量的工作。在典型的場景中,前半部儲存裝置資料到乙個裝置特定的快取,排程它的後半部,並且退出:這個操作非常快速,後半部則接著進行任何其他需要的工作,例如喚醒經常,啟動另乙個i/o操作,等等。這種設定允許前半部來服務乙個新中斷而同時後半部仍然在工作。

幾乎每個認真的中斷處理都這樣劃分。例如,當乙個網路介面報告有新報文到達,處理者只是獲取資料並且上推給協議層,報文的實際處理在後半部進行。

linux核心有2個不同的機制可用來實現後半部處理:

tasklet常常是後半部處理的首選機制,它們非常快,但是所有的tasklet**必須是原子的。

1 tasklet實現

記住tasklet是乙個特殊的函式,可能被排程來執行,在軟中斷上下文,在乙個系統決定的安全時間中,它們可能被排程執行多次,但是tasklet排程不積累;tasklet只執行一次,但是tasklet可以與smp系統上的其他tasklet並行執行。因此,如果你的驅動有多個tasklet,它們必須採取某類加鎖機制避免衝突。

tasklet也保證作為函式執行在第乙個排程它們的同乙個cpu上。因此,乙個中斷處理可以確保乙個tasklet在處理者解除前不會開始執行。但是,另乙個中斷當然可能在tasklet執行時被遞交。

tasklet必須使用declare_tasklet巨集來宣告:

declare_tasklet(name, function, data);
name是給tasklet的名字,function是呼叫來執行tasklet(它帶乙個unsigned long引數並且返回void)的函式,以及data是乙個unsigned long值來傳遞給tasklet函式。

例子:

void test_do_tasklet(unsigned long);

declare_tasklet(test_tasklet, test_do_tasklet, 0);

函式tasklet_schedule用來排程乙個tasklet執行,例如排程test_tasklet,如下:

tasklet_schedult(&test_tasklet);
排程之後,test_do_tasklet將在系統fang方便時被執前面提過,這個函式進行處理中斷大量工作。乙個裝置能夠在短時間內產生大量中斷,因此在後半部執行前有幾個中斷到達就不是不尋常的。驅動必須一直準備這種可能並且必須能夠從前半部留下的資訊中決定有多少工作要做。

2 工作佇列

工作佇列在將來某個時候呼叫乙個函式,在乙個特殊工作者程序的上下文中,因為這個工作佇列函式在程序上下文執行,它需要時能夠睡眠。但是,你不能從乙個工作佇列拷貝資料到使用者空間, 工作者進行不訪問任何其他程序的位址空間。

宣告和初始化工作佇列如下所示:

static struct work_struct test_wq;

ini_work(&test_wq, (void * (void ()) test_do_tasklet, null);

工作佇列呼叫如下:

schedule_work(&test_wq);

嵌入式linux的驅動程式

摘至嵌入式linux裝置驅動開發詳解 1.4 嵌入式linux驅動程式 1.4.1 嵌入式linux的核心空間和使用者空間 目前,各種處理器都能防止資源的未經授權訪問,包括嵌入式處理器。一般都是給cpu劃分不同的操作模式。不同的模式有不同的作用,某些操作不允許在低級別模式使用。核心態和使用者態是在硬...

linux 嵌入式驅動程式測試例項

include include include include include include include int main fd open dev fs o rdwr if fd 0 else printf open ok nwrite write fd,buf,strlen buf if n...

嵌入式linux之按鍵驅動程式

1.寫出框架 2.硬體操作 操作虛擬位址ioremap 1.重要函式 trap init init irq asm do irq中斷總入口 分辨中斷,處理中斷,清中斷。讀一下wait event interruptible 的原始碼,不難發現這個函式先將 當前程序的狀態設定成task interru...