1.中斷響應時間
實時作業系統的意義就在於能夠在確定的時間內處理各種突發的事件,而中斷這些事件、系統搶佔排程的觸發點,因而衡量嵌入式實時作業系統的最主要、最具有代表性的效能指標引數無疑是中斷響應時間。
中斷延遲時間是指從接收到中斷訊號到作業系統做出響應,並完成進入中斷服務例程所需要的時間。中斷延遲時間=最大關中斷時間+硬體開始處理中斷到開始執行中斷服務例程第一條指令之間的時間。
通俗地說:中斷產生到核心執行中斷處理程式第一條指令的時間。
2. x86中斷處理和xenomai中斷管理機制
2.1.x86中斷機制
X86 系統中有256個vector,用來識別中斷或異常的型別,vector 0-31處理器保留,有固定的用途, 從32到255的vector編號被指定為使用者定義的中斷,不被處理器保留。 這些中斷通常分配給外部I / O裝置(部分固定為APIC中斷),以使這些裝置能夠將中斷髮送到處理器,每個vector的處理程式都儲存在一個特殊的位置--IDT(中斷描述符表),IDT的基地址儲存在暫存器IDTR,在64位x86下IDT是一個16位元組描述的陣列(32位系統為8位元組),當中斷髮生時CPU將vector乘以16(32位系統是乘以8)來找到IDT中的對應條目idt_data,然後根據條目資訊跳轉到處理入口執行中斷和異常處理。
2.2.xenomai中斷管理機制
(1)硬體中斷
Xenomai是一個RTOS,與linux共存,為了使Xenomai能夠保持可預測的延遲(硬實時),必須阻止Linux核心直接處理中斷,先將中斷重定給Xenomai處理,然後才是Linux核心。為此在底層增加一個微核心來實現。微核心充當虛擬可程式設計中斷控制器,分離Linux和Xenomai之間的中斷掩碼,該微核心稱為中斷管道(I-Pipe),中斷的分發和實時性由I-Pipe來保障,I-Pipe在系統中的位置如下所示。
Linux和xenomai在I-ipipe上稱為domain, I-Pipe將Linux和xenomai系統組織到兩個域中,其中xenomai域的優先順序高於Linux域。這兩個域共享一個地址空間,允許來自xenomai的執行緒呼叫 Linux 核心域中的服務。 I-Pipe 以 domain 優先順序順序排程中斷。 Xenomai 被設定為最高優先順序域,並將首先接收中斷。
如上圖所示,當cpu接收到一箇中斷後,通過IDT表中的中斷入口進入I-Pipe處理邏輯,I-Pipe會先判斷該中斷是否是實時系統的中斷(實時域中斷),如果是,直接執行其中斷服務函式。如果不是的話會將該中斷儲存到Linux域中斷管理中記錄,待xenomai 讓出cpu後,Linux域執行時逐一從log中取出按Linux的中斷入口去處理。
用於記錄中斷的log的是bitmap:
(2)虛擬中斷
ipipe為了 xenomai 與 linux 之間互動時,如域切換排程、實時與非實時通訊等,為保證xenomai的實時性,引入了虛擬中斷機制 。需要注意的是虛擬中斷和常規 softirq 本質上不同,不能混淆 , softirq 只存在 linux 中,ipipe虛擬中斷更近似於硬體中斷,但不是硬體觸發,由核心之間需要處理緊急任務時向另一個核心傳送,除產生源不同外,ipipe將虛擬中斷和硬體中斷同等對待,ipipe處理虛擬中斷與處理硬體中斷流程一致。
虛擬中斷註冊和其他中斷註冊是一樣的,只是這個中斷號是通過函式ipipe_alloc_virq()
來分配,由函式ipipe_free_virq()釋放。比如__ipipe_printk_virq
,當 xenomai 需要呼叫 linux 的列印輸出時,只需要在 xenomai 中執行ipipe_post_irq_root(__ipipe_printk_virq)
(給低優先順序的 Linux 傳送中斷),然後就會在 Linux 上下文中執行__ipipe_flush_printk()
,進行列印 xenomai 輸出的內容,進而避免列印影響xenomai實時性。
相反,Linux可以通過虛擬中斷觸發 xenomai 上的一些活動,只需要在 Linux上下文中執行ipipe_post_irq_head(virq_xxx)
(給 xenomai 傳送中斷),xenomai 就會很快執行相應操作。此外虛擬中斷還可以本核心觸發本核心虛擬中斷。不管是虛擬中斷還是硬體中斷, xenomai 優先順序都比 Linux 高。
4.中斷響應測試設計
4.I-pipe核心間虛擬中斷
註冊一個RTDM裝置,分配一個虛擬中斷,將這個虛擬中斷號(virq)與中斷處理函式(ISR) 通過RTDM介面註冊到xenomai域。
測試時傳送前讀取TSC的值,轉換為時間t0,使用ipipe_post_irq_head(virq)
傳送中斷,在中斷處理函式中讀取時間t1,時間T= t1- t0就是虛擬中斷響應時間,測試流程如下。
上述過程使用者任務定時測試K次,就可以得到K次中斷響應時間。
4.1.硬體中斷
(1)測試方法
由於硬體中斷的特殊性,測試方法有很多,常用的方式有:
- 使用外部裝置通過GPIO引腳觸發中斷,中斷服務程式中翻轉GPIO電平,外部通過示波器或者MCU來反映中斷響應時間。缺點:需要外部裝置、外設操作速度慢、x86平臺上Gpio子系統xenomai 支援不是很好(注:該文寫於2019年,目前xenomai3.2-rc+已對部分intel平臺支援實時GPIO驅動,xenomai也提供了GPIO測試程式)。
- 使用硬體定時器週期觸發中斷,中斷處理函式中讀取時間,讀取到的時間減去定時器觸發中斷的時間即中斷響應時間。
- SMP架構可通過可程式設計中斷控制器來產生中斷,記錄中斷髮送時時間t0,中斷處理函式中讀取時間t1,時間T= t1- t0就是硬體中斷響應時間。(本方案)
(2)測試設計
X86 SMP系統中,當外設向CPU發出中斷,中斷不會直接傳送到CPU,有一個高階可程式設計中斷控制器(APIC)負責順序處理來自對各裝置的多箇中斷請求,APIC由Local APIC和I/O APIC兩部分組成。
- Local APIC位於每個CPU核心上,負責本CPU特定的中斷配置,通常用來管理來自APIC-timer、熱感測器和其他此類連結本地I/O裝置的中斷。
- I/O APIC提供多處理器中斷管理,用於CPU核之間分配外部中斷,按一定規則將外部中斷處理成中斷訊息傳送到Local APIC。
根據LAPIC可程式設計產生中斷的特性,使用APIC來產生中斷,LAPIC的中斷命令暫存器(ICR)是一個64位暫存器(見圖),它允許處理器上執行的軟體指定處理器中斷(IPI)並將其傳送到系統中的其他處理器。要傳送IPI,軟體必須設定ICR以指示要傳送的IPI訊息的型別以及目標處理器。寫入ICR的動作會導致IPI被髮送。
根據以上資訊,我們利用寫ICR暫存器來向CPU產生一箇中斷代替外部硬體觸發來測是xenomai 中斷響應時間。
在每個CPU中,每個中斷和異常分配一個數來標識,稱為vector number,在X86體系中中斷向量範圍為0-255,最多表示256箇中斷,用一個8位的無符號整數來表示,前32個vector為系統保留,32-255可由使用者(OS)動態分配。
所以需要選出一個未使用的vector來作為本次測試的中斷號,
作為測試中斷號,對應的修改核心原始碼新增中斷號,以及中斷服務程式 ipipe_inttest_interrupt
,ipipe_inttest_interrupt
將中斷號壓棧後跳轉至ipipe層做分發,ipipe會根據中斷註冊資訊遞交給Linux或xenomai處理。
整個測試與虛擬中斷測試類似流程如下:
- 安裝測試RTDM驅動,將中斷處理函式
xnintr_test_handler()
註冊到xenomai域,中斷處理函式中讀取當前TSC時間t0。 - 應用程式發起一次中斷響應測試。
- 核心中,測試驅動讀取當前TSC時間t0,然後寫LAPIC ICR暫存器向目標CPU產生中斷。
- 目標CPU儲存當前上下後執行中斷服務程式ISR(ipipe_inttest_interrupt)。
- ISR(ipipe_inttest_interrupt)呼叫
__ipipe_handle_irq
讓ipipe分發中斷,ipipe根據中斷註冊資訊讓xenomai執行註冊的中斷處理程式xnintr_test_handler
。 xnintr_test_handler
中讀取當前TSC時間t1,後返回。- 測試驅動將本次測試資料t1、t0拷貝到使用者空間。
- 使用者程式計算時間測,統計測試結果輸出,跳轉到第2步繼續下一輪測試。
ctx-> handler = (ipipe_irq_handler_t)xnintr_test_handler;
err = ipipe_request_irq(&xnsched_realtime_domain, ctx->irq, (ipipe_irq_handler_t)ctx->handler, (void *)ctx, __ipipe_ack_apic);
測量中斷是從本CPU LAPIC傳送給本CPU處理;核間中斷響應時間為本CPU LAPIC傳送中斷給其他CPU。但是ipipe沒有實現本CPU給本CPU傳送中斷的介面,所以還需要實現這個介面ipipe_send_ipi_curr()
。
5.測試結果
CPU和GPU同時加壓如下
#CPU
stress -c 10
#GPU
While true; do glmark2-es2 -size 800x450 > /dev/null; done&
While true; do glmark2-es2 -size 800x450 > /dev/null; done&
While true; do glmark2-es2 -size 800x450 > /dev/null; done&
While true; do glmark2-es2 -size 800x450 > /dev/null; done&
每項測試中斷產生週期和測試總時間如下。
5.1.I-pipe核心間虛擬中斷
無負載測試情況(單位us):
中斷週期及測試時長 | 最小 | 平均 | 最大 |
---|---|---|---|
100us 23h18m | 0.120 | 0.194 | 0.360 |
高負載測試情況(單位us):
中斷週期及測試時長 | 最小 | 平均 | 最大 |
---|---|---|---|
100us 24h | 0.168 | 0.216 | 0.324 |
5.2.硬體中斷
無負載測試情況(單位us):
中斷週期及測試時長 | 最小 | 平均 | 最大 |
---|---|---|---|
100us 24h | 0.223 | 0.401 | 1.819 |
高負載測試情況(單位us):
中斷週期及測試時長 | 最小 | 平均 | 最大 |
---|---|---|---|
100us 24h | 0.026 | 0.394 | 7.192 |
5.3.核間中斷
無負載測試情況(單位us):
中斷週期及測試時長 | 最小 | 平均 | 最大 |
---|---|---|---|
100us 23h35m | -0.155 | 0.137 | 4.179 |
不清楚為什麼會有負值,初步猜測是不是每個CPU核的TSC不是同步的,若哪位讀者知道,還望不吝賜教。
高負載測試情況(單位us):
中斷週期及測試時長 | 最小 | 平均 | 最大 |
---|---|---|---|
100us 21h | 0.086 | 0.184 | 4.288 |
版權宣告:本文為本文為博主原創文章,轉載請註明出處。如有問題,歡迎指正。部落格地址:https://www.cnblogs.com/wsg1100/