上一篇博文的位址:
http://blog.csdn.net/morixinguan/article/details/65494239
這節,我們來看看函數指針與回調函數在Linux核心中的應用。
從上節我們了解到,函數指針和回調函數在開發者和使用者之間的一個例子,那麼這節,我将引用Linux核心中檔案操作結構體來詳細的說明。
我們首先來看到這個結構體,這段代碼位于linux核心的include/linux/fs.h中,由于代碼衆多,我隻截取幾個最基本的例子:
File_operations檔案操作結構體:

這段代碼中,利用結構體的封裝思想,将函數指針封裝在一個file_operations結構體裡,然後,在具體實作驅動的時候,實作具體的函數,再指派給結構體裡的函數指針做好初始化操作,我們來看看友善之臂的led驅動就明白了。
以下這段代碼截取友善之臂提供的linux核心中的tiny4412_leds.c
首先,先是定義了一個結構體變量,并對結構體變量進行初始化,在這個驅動中,隻實作了ioctl函數,對照着上面的結構體,ulocked_ioctl就是結構體中的這個函數指針。
long (*unlocked_ioctl) (struct file *,unsigned int, unsigned long);
再來看看友善實作的adc驅動裡,也是這麼來做,這裡看到 : 也是C語言結構體的一種初始化方式,也是合理的。
在核心中,有很多這樣的函數指針,是以,當我們了解了這樣的套路以後,再去學習linux核心,我們的思想就會清晰很多了。
再來看看回調函數在linux核心裡的基本應用。
接下來我們來看一個例子:
這段代碼摘自友善之臂的button驅動:
我們在tiny4412_buttons_open函數裡看到
err = request_irq(irq, button_interrupt, IRQ_TYPE_EDGE_BOTH,
buttons[i].name,(void *)&buttons[i]);
我們來看看request_irq這個函數:
這個函數的作用是請求中斷,我們來看看函數的第二個參數irq_handler_t handler是什麼?
到這裡我們就明白了,第二個參數是一個用typedef重新定義的一個新類型的函數指針。
那麼也就是說一旦執行了tiny4412的open函數,就會通過request_irq去通過回調函數去執行按鍵中斷,并傳回一個中斷句柄。這個回調函數,其實就是一個中斷服務函數。
回調函數在核心中就是這麼來使用的,當然,還有其它的,比如我們在tiny4412的open函數裡面還看到:
setup_timer(&buttons[i].timer,tiny4412_buttons_timer,
(unsignedlong)&buttons[i]);
這個函數的作用是注冊一個定時器,通過回調函數tiny4412_buttons_timer來進行觸發。
如果你不看它的定義,你可能以為它是一個普通函數,其實它是一個宏函數。
這個宏函數通過調用setup_timer_key這個函數來實作定時器的注冊:
通過這一節,我們了解到回調函數在Linux核心中的應用,為學習Linux核心,分析linux核心源代碼打下了基礎。