Linux設備驅動之中斷處理

来源:http://www.cnblogs.com/archiexie/archive/2016/12/09/6126736.html
-Advertisement-
Play Games

中斷(interrupt)是指CPU在執行程式的過程中,出現了某些突發事件急待處理,CPU必須暫停執行當前的程式,轉去處理突發事件,處理完畢後CPU又返回原程式被中斷的位置並繼續執行。中斷服務程式的執行並不存在於進程上下文,因此,要求中斷服務程式的時間儘可能地短。因此,Linux在中斷處理中引入了頂... ...


中斷(interrupt)是指CPU在執行程式的過程中,出現了某些突發事件急待處理,CPU必須暫停執行當前的程式,轉去處理突發事件,處理完畢後CPU又返回原程式被中斷的位置並繼續執行。
中斷服務程式的執行並不存在於進程上下文,因此,要求中斷服務程式的時間儘可能地短。因此,Linux在中斷處理中引入了頂半部和底半部分離的機制。頂半部處理緊急的硬體操作,底半部處理不緊急的耗時操作。
tasklet和工作隊列都是調度中斷底半部的良好機制,tasklet基於軟中斷實現,原子操作,速度快,常用,但不可阻塞或睡眠。


中斷分類

  • 根據中斷的來源,可分為內部中斷和外部中斷

            內部中斷的中斷源來自CPU內部(軟體中斷指令、溢出、除法錯誤等,例如,操作系統從用戶態切換到內核態需藉助CPU內部的軟體中斷),外部中斷的中斷源來自CPU外部,由外設提出請求。
  • 根據中斷是否可以屏蔽分為可屏蔽中斷與不屏蔽中斷(NMI)

            可屏蔽中斷可以通過屏蔽字(MASK)被屏蔽,屏蔽後,該中斷不再得到響應,而不屏蔽中斷不能被屏蔽。
  • 根據中斷入口跳轉方法的不同,分為向量中斷和非向量中斷

            採用向量中斷的CPU通常為不同的中斷分配不同的中斷號,當檢測到某中斷號的中斷到來後,就自動跳轉到與該中斷號對應的地址執行。不同中斷號的中斷有不同的入口地址。非向量中斷的多個中斷共用一個入口地址,進入該入口地址後再通過軟體判斷中斷標誌來識別具體是哪個中斷。也就是說,向量中斷由硬體提供中斷服務程式入口地址,非向量中斷由軟體提供中斷服務程式入口地址。

Linux中斷處理(Interrupt Handling)架構

設備的中斷會打斷內核中進程的正常調度和運行,系統對更高吞吐率的追求勢必要求中斷服務程式儘可能的短小精悍。為了在中斷執行時間儘可能短和中斷處理需完成大量工作之間找到一個平衡點, Linux 將中斷處理程式分解為兩個半部:頂半部(top half)和底半部(bottom half)。

  • top half

            頂半部完成儘可能少的比較緊急的功能,它往往只是簡單地讀取寄存器中的中斷狀態並清除中斷標誌後就進行“登記中斷”的工作。“登記中斷”意味著將底半部處理程式掛到該設備的底半部執行隊列中去。這樣,頂半部執行的速度就會很快,可以服務更多的中斷請求。軟體上一般採用handler中斷響應程式實現。
  • bottom half

            底半部由頂半部調度而來進行延後處理,幾乎做了中斷處理程式所有的事情,而且可以被新的中斷打斷,這也是底半部和頂半部的最大不同,因為頂半部往往被設計成不可中斷。底半部則相對來說並不是非常緊急的,而且相對比較耗時,不在硬體中斷服務程式中執行。軟體上一般採用tasklet或工作隊列機制。

Tip:儘管頂半部、底半部的結合能夠改善系統的響應能力,但是,僵化地認為 Linux 設備驅動中的中斷處理一定要分兩個半部則是不對的。如果中斷要處理的工作本身很少,則完全可以直接在頂半部全部完成。


Linux中斷編程

申請和釋放(Installing an Interrupt Handler)

    #include <linux/interrupt.h>

    int /* 返回 0 -- OK, -EINVAL -- irq/handler invalid, -EBUSY -- 中斷被占用不能共用 */
    request_irq(
            unsigned int irq,       /* 要申請的硬體中斷號 */
            irq_handler_t handler,  /* 向系統登記的中斷處理函數(頂半部)*/
            unsigned long flags,    /* 中斷處理的屬性,可以指定中斷的觸發方式以及處理方式等 */
            const char *devname,    /* used in /proc/interrupts */   
            void *dev_id            /* 傳遞給handler的參數 */
            );

    void free_irq(unsigned int irq,void *dev_id);

Tip: 如果中斷確定不被共用可將其安裝在初始化中,否則應安裝在打開函數中。interrupt.h有irq_handler_t的定義及flags的詳細註釋

使能和屏蔽 (Enabling and Disabling Interrupts)

  • Disabling a single interrupt

    #include <asm/irq.h>
    
    /* disable並等待指定的中斷被處理完,如果調用線程占有interrupt handler需要的資源如spinlock那麼就會死鎖 */
    void disable_irq(int irq); 
    
    /* disable並立即返回,有可能產生競態 */
    void disable_irq_nosync(int irq);
    
    void enable_irq(int irq);
  • Disabling all interrupts

    #include <asm/system.h>
    
    void local_irq_save(unsigned long flags); /* save flags then disable local all */
    void local_irq_disable(void); /* disable local all directly */
    
    void local_irq_restore(unsigned long flags);
    void local_irq_enable(void);

底半部機制

  • tasklet

    void my_tasklet_func(unsigned long); /*定義一個處理函數*/
    
    /* 定義一個tasklet結構my_tasklet,並與my_tasklet_func(data)處理函數相關聯 */
    DECLARE_TASKLET(my_tasklet, my_tasklet_func, data);
    
    /* 在需要調度tasklet的時候引用一個tasklet_schedule()函數就能使系統在適當的時候進行調度運行 
       一般在top half即中斷響應函數中調用 */
    tasklet_schedule(&my_tasklet);
  • 工作隊列(workqueues)
    與tasklet類似:

    void my_wq_func(unsigned long); /*定義一個處理函數*/
    
    struct work_struct my_wq; /*定義一個工作隊列*/
    /* 初始化工作隊列並將其與處理函數綁定 */
    INIT_WORK(&my_wq, (void (*)(void *)) my_wq_func, NULL);
    
    schedule_work(&my_wq);/*調度工作隊列執行*/

Tip: tasklet在中斷上下文中執行,不可阻塞或睡眠;而workqueues由內核線程去執行,屬進程上下文,可阻塞和睡眠。


References

1. Linux Device Drivers
2. Linux設備驅動開發詳解(宋寶華第二版)


Copyright (C) 2016 archiexie@cnblogs. All Rights Reserved.



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 介紹 forfiles是windows自帶的一個批量刪除命令,對於時間的判斷是通過文件自身的修改日期屬性進行判斷,使用它來對歷史文件進行判斷刪除是個不錯的選擇。 語法 forfiles [/p Path ] [/m SearchMask ] [/s ] [/c Command ] [/d [{+ | ...
  • 從網路上下載到的源碼包, 最常見的是 .tar.gz 包, 還有一部分是 .tar.bz2包要解壓很簡單 :.tar.gz 格式解壓命令為 tar -zxvpf xx.tar.gz.tar.bz2 格式解壓命令為 tar -jxvpf xx.tar.bz2 //p參數可以保留原文件許可權(很重要) ...
  • 本文地址 分享提綱: 1. svn 不常見單有用的命令 2. svn查看切換用戶 1. svn自己總結的一些不常見,但有用的命令 1)【導出svn不帶版本代碼】導出不帶svn版本控制的代碼到本地的 localdir下: svn export https://github.com/wozhuzaisi ...
  • 更改SSH服務端遠程登錄的配置 windows服務端的預設遠程管理埠是3389,管理員用戶是administrator,普通用戶是guest。Linux的管理用戶是root,普通用戶預設有很多個,遠程連接預設埠是22。 修改配置文件/etc/ssh/sshd_config,13行Port 22(... ...
  • 一、NFS概念: 透過網路,讓不同的主機能“共用”文件。通過NFS,用戶和程式可以像訪問本地文件一樣訪問遠端系統上的文件。 二、版本: 共三個版本,NFSv2,NFSv3,NFSv4(包含4.0和4.1)。其中NFSv2和NFSv3由Sun公司起草。NFS4.0主要由NetApp。 三、版本特點 V ...
  • [joy@localhost ~]$ java -version openjdk version "1.8.0_91" OpenJDK Runtime Environment (build 1.8.0_91-b14)OpenJDK 64-Bit Server VM (build 25.91-b14, ...
  • Linux通過系統硬體定時器以規律的間隔(由HZ度量)產生定時器中斷,每次中斷使得一個內核計數器的值jiffies累加,因此這個jiffies就記錄了系統啟動開始的時間流逝,然後內核據此實現軟體定時器和延時。 ...
  • 參考:https://wiki.archlinux.org/index.php/Installation_guide_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87) 安裝準備 連接到網際網路 守護進程 dhcpcd 已被預設啟用來探測有線設備, 並會嘗試連接。如需驗證網路... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...