在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > linux UART串口驅動開發(fā)文檔

            linux UART串口驅動開發(fā)文檔

            作者: 時間:2012-09-06 來源:網絡 收藏

            講到最后還沒有指出軟中斷是如何觸發(fā)執(zhí)行的,其實很簡單:

            在系統(tǒng)處理所有硬中斷信號時,他們的入口是統(tǒng)一的,在這個入口函數當中除了執(zhí)行do_IRQ()完成硬件中斷的處理之外,還會執(zhí)行do_softirq()來檢測是否有軟中斷須要執(zhí)行,所以軟中斷所依賴的是硬件中斷機制;

            另外還有一個專門處理軟中斷內核線程ksoftirqd(),這個線程處理軟中斷級別是比較低的,他是一個無限LOOP不停的檢測是否有軟中斷須要處理,如果沒有則進行任務調度.

            在do_softirq()中有如下的判斷,以決定是否有軟中斷須要執(zhí)行,如果沒有就直接退出,在[3]中提到的激活軟中斷時,要將相應軟中斷位置1, 軟中斷有32個,因此一個整型數即可以表示32個軟中斷,即可判斷有什么樣的軟中斷須要處理,代碼如下:

            pending = softirq_pending(cpu);

            if (pending) {

            }

            ….

            do { //檢測32個軟中斷位標志中是否有為1的…

            if (pending 1)

            h->action(h);

            h++;

            pending >>= 1;

            } while (pending);

            [4]. 軟中斷所依賴的執(zhí)行時期問題.

            之所以將這個問題單獨列開來講,是因為他特別的重要,上面我已經講過了軟中斷是依賴硬中斷觸發(fā)執(zhí)行的,但是產生如下疑問:

            是不是一有硬中斷發(fā)生就會觸發(fā)軟中斷的執(zhí)行?

            軟中斷的執(zhí)行會不會影響到系統(tǒng)的性能?

            會不會影響到硬中斷的處理效率?也就是說會不會導致在處理軟中斷時而引起硬中斷無法及時響應呢?

            再看do_softirq的代碼當中有如下判斷:

            if (in_interrupt())

            return;

            這個條件就是能否進行軟中斷處理的關鍵條件,因此由此也可以了解到軟中斷是一種優(yōu)先級低于硬中斷的軟性機制,具體來看看這個判斷條件是什么:

            /*Are we in an interrupt context? Either doing bottom half

            * or hardware interrupt processing?*/

            #define in_interrupt() ({ const int __cpu = smp_processor_id();

            (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })

            /* softirq.h is sensitive to the offsets of these fields */

            typedef struct {

            unsigned int __softirq_pending;

            unsigned int __local_irq_count;

            unsigned int __local_bh_count;

            unsigned int __syscall_count;

            struct task_struct * __ksoftirqd_task; /* waitqueue is too large */

            } ____cacheline_aligned irq_cpustat_t;

            #define irq_enter(cpu,irq) (local_irq_count(cpu)++)

            #define irq_exit(cpu,irq) (local_irq_count(cpu)--)

            看到這里,不得不再多注意一個結構,那就是irq_cpustat_t, 先前我們講是否有軟中斷產生的標志位,但沒有提到__softirq_pending,這個變量就是記載32個軟中斷是否產生的標志,每一個軟中斷對應一個位; 在中斷執(zhí)行的do_softirq中有如下幾個重要的動作,說明如下:

            in_interrupt判斷是否可以進行軟中斷處理,判斷的條件就是沒有沒處在硬件中斷環(huán)境中,而且還沒有軟中斷正在執(zhí)行(即不允許軟中斷嵌套),軟中斷的嵌套避免是通過local_bh_disable()/local_bh_enable()實現,至于帶有bh,其意也即指softirq是中斷底半(bh), 在處理硬件中斷時,一進行即會調用irq_enter來表示已經進入硬件中斷處理程序,處理完硬件中斷后再調用irq_exit表示已經完成處理;

            pending判斷是否有軟中斷須要處理, 每個位用作當作一個軟中斷是否產生的標志.

            清除所有軟中斷標志位,因為下面即將處理; 但清除之前先緩存起來, 因為下面還要使用這個變量一次.

            在進入軟中斷處理后,會關閉bh功能的執(zhí)行,執(zhí)行完后才打開,這樣在in_interrupt判斷當中就會直接發(fā)現已經有bh在執(zhí)行,不會再次進入bh執(zhí)行了,這嚴格保證了bh執(zhí)行的串行化.

            打開硬件中斷,讓軟中斷在有硬件中斷的環(huán)境下執(zhí)行.

            處理完軟中斷后關閉硬中斷,再次檢測是否有新的軟中斷產生,如果有的話,卻只須立即處理本次軟中斷過程未發(fā)生過的軟中斷向量. 之所以會有新的軟中斷產生,那是因為軟中斷是在開硬件中斷的情況下執(zhí)行,硬件中斷處理是可能又產生了新的軟中斷. 之所以只處理本次軟中斷未發(fā)生的軟中斷向量,依據我自己的理解,其目的是為了不加重軟中斷處理的負擔而不馬上處理,只是相應的喚醒一個wakeup_softirqd線程,這是專門處理軟中斷的,這樣雖然延誤了軟中斷的處理,但避免了在硬中斷服務程序中拖延太長的時間.[關于軟中斷的處理在后緒版本變化也很大,可以進一步學習研究,如何使軟中斷不至影響中斷處理效率]

            軟中斷處理這個函數雖然不長,但是相當的關鍵,每一句代碼都很重要,結合上面所說的幾點,與源碼交互起來理解才能根本理解軟中斷的設計機制:

            asmlinkage void do_softirq()

            {

            int cpu = smp_processor_id();

            __u32 pending;

            unsigned long flags;

            __u32 mask;

            if (in_interrupt()) return;

            local_irq_save(flags);

            pending = softirq_pending(cpu);

            if (pending) {

            struct softirq_action *h;

            mask = ~pending;

            local_bh_disable();

            restart:

            /* Reset the pending bitmask before enabling irqs */

            softirq_pending(cpu) = 0;

            local_irq_enable();

            h = softirq_vec;

            do {

            if (pending 1)

            h->action(h);

            h++;

            pending >>= 1;

            } while (pending);

            local_irq_disable();

            pending = softirq_pending(cpu);

            if (pending mask) {

            mask = ~pending;

            goto restart;

            }

            __local_bh_enable();

            if (pending)

            wakeup_softirqd(cpu);

            }

            local_irq_restore(flags);

            }

            }

            四. TTY與的具體關聯.

            設備可以當作TTY終端來使用,這又使設備比一般的設備稍微復雜一些,因為他還必須與終端關聯起來,雖然這部分與TTY的關聯已經是屬于公用部分的代碼,并不須要編寫者特別做些什么來進行支持,但對它與TTY的層次關聯的了解有助于理解整個串口的數據流向.

            linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

            linux相關文章:linux教程




            評論


            相關推薦

            技術專區(qū)

            關閉