中斷中處理延時及一些函數的調用規則(中斷調i2c驅動有感)--中斷中的延遲delay與printk函數的沖突【轉】


轉自:http://blog.csdn.net/psvoldemort/article/details/8222371

1,中斷處理程序中不能使用有睡眠功能的函數,如ioremap,kmalloc,msleep等,理由是中斷程序並不是進程,沒有進程的概念,因此就沒有休眠的概念;

2,中斷處理程序中的延時可以用忙等待函數來代替,如ndelay,udelay,mdelay等,這些函數在實現上本質是根據CPU頻率進行一定次數的循環;最好不要使用mdelay,因為毫秒延時對內核來說已經是非常大了。但是在中斷處理程序中使用msleep卻不行。(見linux設備驅動開發詳解第二版p210頁)

3,printk函數在中斷處理函數中可以使用,但是會占用較多時間,降低效率。在調IIC驅動的時候,由於IIC讀取寫入處理時必須進行一定延時,在我沒有使用udelay的時候,竟然用printk就使IIC中斷正常運行,當時在調試的時候,發現有些printk加上程序就正常,去掉就不正常,當時真是匪夷所思,但現在明白了,因此printk占用時間比較大,正好充當了IIC延時的功能。最后我把printk全部去掉,在需要延時的地方加入udelay,才使程序正常運行。

4,使用for和while等的空循環在中斷處理函數中進行延時操作,在實際測試中發現並不能起到延時的功能,linux內核處理這種循環速度很快,並沒有延時的效果。這跟裸板程序使用循環來延時的用法不相同。

 

其他:

1、中斷是一種電信號,由硬件設備生成,並直接送入中斷控制器的輸入引腳上。然后再由中斷控制器向處理器發送相應的信號。處理器一經檢測到此信號,便中斷自己的當前工作轉而處理中斷。此后,處理器會通知操作系統已經產生中斷,這樣,操作系統就可以對這個中斷進行適當的處理了。

   

   2、不同的設備對應的中斷不同,而每個中斷都通過一個唯一的數字標識。中斷值通常被稱為中斷請求(IRQ)線。有些中斷值是指定的,有些是動態分配的。特定的中斷總與特定的設備相關聯。

 

   3、異常與中斷不同,它在產生時必須考慮與處理器時鍾同步。異常也常常稱為同步中斷。許多處理器體系結構處理異常與中斷的方式類似,因此內核對它們的處理也很類似。

  

   4、在響應一個特定中斷的時候,內核會執行一個函數,該函數叫做中斷處理程序或中斷服務例程。產生中斷的每個設備都有一個相應的中斷處理程序,如果一個設備可以產生多種不同的中斷,那么該設備就可以對應多個中斷處理程序。一個設備的中斷處理程序是它設備驅動程序的一部分。

   5、中斷處理程序與其他內核函數的真正區別在於:中斷處理程序是被內核調用來響應中斷的,而它們運行於我們稱之為中斷上下文的特殊上下文中。

 

   6、中斷處理一般分為兩個部分,中斷處理程序是上半部-接收到一個中斷就立即執行,但只做有嚴格時限的工作,這些工作都是在所有中斷被禁止的情況下完成的。能夠被允許稍后完成的工作被推遲到下半部去。通常情況下,下半部會在中斷處理程序返回時立即執行。

 

   7、Linux中的中斷處理程序是無需重入的。當一個給定的中斷處理程序正在執行時,相應的中斷線在所有處理器上都會被屏蔽掉,以防止在同一中斷線上接收另一個新的中斷。通常情況下,所有其他的中斷都是打開的,所以這些不同中斷線上的其它中斷都能被處理,但當前中斷線總是被禁止的。由此可以看出,同一個中斷處理程序絕對不會被同時調用以處理嵌套的中斷。

   8、共享的中斷處理程序與非共享的在注冊和運行方式上比較類似,但差異主要有以下三處:

 

  •    注冊中斷處理程序函數request_irq()的參數flags必須設置SA_SHIRQ標志。
  •    對每個注冊的中斷處理程序來說,dev_id參數必須唯一。不能給共享的處理程序傳遞NULL值。
  •    中斷處理程序必須能夠區分它的設備是否真的產生了中斷。否則它根本無法知道是它對應的設備發出了這個中斷還是共享這條中斷線的其它設備發出了這個中斷。

 

   9、當執行一個中斷處理程序或下半部時,內核處於中斷上下文中。中斷上下文和進程並沒有什么瓜葛。因為沒有進程的背景,所以中斷上下文不可以睡眠。因此,不能從中斷上下文中調用某些函數。如果一個函數睡眠,就不能在中斷處理函數中使用它。中斷上下文具有較為嚴格的時間限制,因為它打斷了其他代碼。中斷上下文中的代碼應當迅速簡潔,盡量不要使用循環去處理繁重的工作。盡量把工作從中斷處理程序中分離出來,放在下半部執行。中斷處理程序並不具有自己的棧。相反,它共享被中斷進程的內核棧。如果沒有正在運行的進程,就使用idle進程的棧。中斷處理程序共享別人的堆棧,所以它在棧中獲取空間時必須非常節省。內核棧本就很有限,所有的內核代碼都應該謹慎利用它。

   10、Linux內核提供了一組接口用於操作機器上的中斷狀態。這些接口為我們提供了能夠禁止當前處理器的中斷系統,或屏蔽掉整個機器的一條中斷線的能力,這些例程都是與體系結構相關的,可以在<asm/system.h>和<asm/irq.h>中找到。

   11、控制中斷系統的原因歸根結底是需要提供同步。通過禁止中斷,可以確保某個中斷處理程序不會搶占當前代碼,還可以禁止內核搶占。但它們都沒有提供任何保護機制來防止來自其他處理器的並發訪問。鎖提供保護機制來防止來自其他處理器的並發訪問。禁止中斷提供保護機制來防止來自其他中斷處理程序的並發訪問。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM