<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > linux UART串口驅(qū)動(dòng)開(kāi)發(fā)文檔

          linux UART串口驅(qū)動(dòng)開(kāi)發(fā)文檔

          作者: 時(shí)間:2012-09-06 來(lái)源:網(wǎng)絡(luò) 收藏

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

          在系統(tǒng)處理所有硬中斷信號(hào)時(shí),他們的入口是統(tǒng)一的,在這個(gè)入口函數(shù)當(dāng)中除了執(zhí)行do_IRQ()完成硬件中斷的處理之外,還會(huì)執(zhí)行do_softirq()來(lái)檢測(cè)是否有軟中斷須要執(zhí)行,所以軟中斷所依賴(lài)的是硬件中斷機(jī)制;

          另外還有一個(gè)專(zhuān)門(mén)處理軟中斷內(nèi)核線(xiàn)程ksoftirqd(),這個(gè)線(xiàn)程處理軟中斷級(jí)別是比較低的,他是一個(gè)無(wú)限LOOP不停的檢測(cè)是否有軟中斷須要處理,如果沒(méi)有則進(jìn)行任務(wù)調(diào)度.

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

          pending = softirq_pending(cpu);

          if (pending) {

          }

          ….

          do { //檢測(cè)32個(gè)軟中斷位標(biāo)志中是否有為1的…

          if (pending 1)

          h->action(h);

          h++;

          pending >>= 1;

          } while (pending);

          [4]. 軟中斷所依賴(lài)的執(zhí)行時(shí)期問(wèn)題.

          之所以將這個(gè)問(wèn)題單獨(dú)列開(kāi)來(lái)講,是因?yàn)樗貏e的重要,上面我已經(jīng)講過(guò)了軟中斷是依賴(lài)硬中斷觸發(fā)執(zhí)行的,但是產(chǎn)生如下疑問(wèn):

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

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

          會(huì)不會(huì)影響到硬中斷的處理效率?也就是說(shuō)會(huì)不會(huì)導(dǎo)致在處理軟中斷時(shí)而引起硬中斷無(wú)法及時(shí)響應(yīng)呢?

          再看do_softirq的代碼當(dāng)中有如下判斷:

          if (in_interrupt())

          return;

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

          /*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)--)

          看到這里,不得不再多注意一個(gè)結(jié)構(gòu),那就是irq_cpustat_t, 先前我們講是否有軟中斷產(chǎn)生的標(biāo)志位,但沒(méi)有提到__softirq_pending,這個(gè)變量就是記載32個(gè)軟中斷是否產(chǎn)生的標(biāo)志,每一個(gè)軟中斷對(duì)應(yīng)一個(gè)位; 在中斷執(zhí)行的do_softirq中有如下幾個(gè)重要的動(dòng)作,說(shuō)明如下:

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

          pending判斷是否有軟中斷須要處理, 每個(gè)位用作當(dāng)作一個(gè)軟中斷是否產(chǎn)生的標(biāo)志.

          清除所有軟中斷標(biāo)志位,因?yàn)橄旅婕磳⑻幚? 但清除之前先緩存起來(lái), 因?yàn)橄旅孢€要使用這個(gè)變量一次.

          在進(jìn)入軟中斷處理后,會(huì)關(guān)閉bh功能的執(zhí)行,執(zhí)行完后才打開(kāi),這樣在in_interrupt判斷當(dāng)中就會(huì)直接發(fā)現(xiàn)已經(jīng)有bh在執(zhí)行,不會(huì)再次進(jìn)入bh執(zhí)行了,這嚴(yán)格保證了bh執(zhí)行的串行化.

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

          處理完軟中斷后關(guān)閉硬中斷,再次檢測(cè)是否有新的軟中斷產(chǎn)生,如果有的話(huà),卻只須立即處理本次軟中斷過(guò)程未發(fā)生過(guò)的軟中斷向量. 之所以會(huì)有新的軟中斷產(chǎn)生,那是因?yàn)檐浿袛嗍窃陂_(kāi)硬件中斷的情況下執(zhí)行,硬件中斷處理是可能又產(chǎn)生了新的軟中斷. 之所以只處理本次軟中斷未發(fā)生的軟中斷向量,依據(jù)我自己的理解,其目的是為了不加重軟中斷處理的負(fù)擔(dān)而不馬上處理,只是相應(yīng)的喚醒一個(gè)wakeup_softirqd線(xiàn)程,這是專(zhuān)門(mén)處理軟中斷的,這樣雖然延誤了軟中斷的處理,但避免了在硬中斷服務(wù)程序中拖延太長(zhǎng)的時(shí)間.[關(guān)于軟中斷的處理在后緒版本變化也很大,可以進(jìn)一步學(xué)習(xí)研究,如何使軟中斷不至影響中斷處理效率]

          軟中斷處理這個(gè)函數(shù)雖然不長(zhǎng),但是相當(dāng)?shù)年P(guān)鍵,每一句代碼都很重要,結(jié)合上面所說(shuō)的幾點(diǎn),與源碼交互起來(lái)理解才能根本理解軟中斷的設(shè)計(jì)機(jī)制:

          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與的具體關(guān)聯(lián).

          設(shè)備可以當(dāng)作TTY終端來(lái)使用,這又使設(shè)備比一般的設(shè)備稍微復(fù)雜一些,因?yàn)樗€必須與終端關(guān)聯(lián)起來(lái),雖然這部分與TTY的關(guān)聯(lián)已經(jīng)是屬于公用部分的代碼,并不須要編寫(xiě)者特別做些什么來(lái)進(jìn)行支持,但對(duì)它與TTY的層次關(guān)聯(lián)的了解有助于理解整個(gè)串口的數(shù)據(jù)流向.

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

          linux相關(guān)文章:linux教程




          評(píng)論


          相關(guān)推薦

          技術(shù)專(zhuān)區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();