1. 概述
中斷是指出現需要時, CPU暫停執行當前程式,轉而執行新程式的過程。即在程式執行過程中,系統出現了一個必須由CPU立即處理的事務,此時, CPU暫時中止當前程式的執行轉而處理這個事務,這個過程就叫做中斷。
眾多周知, CPU的處理速度比外設的執行速度快很多,外設可以在沒有CPU介入的情況下完成一定的工作,但某些情況下需要CPU為其做一定的工作。
通過中斷機制,在外設不需要CPU介入時, CPU可以執行其它任務,而當外設需要CPU時通過產生中斷訊號使CPU立即中斷當前任務來響應中斷請求。這樣可以使CPU避免把大量時間耗費在等待,查詢外設狀態的操作上,因此將大大提高系統實時性以及執行效率。
Huawei LiteOS的中斷支援:
- 中斷初始化。
- 中斷建立。
- 開/關中斷。
- 恢復中斷。
- 中斷使能。
- 中斷遮蔽。
Huawei LiteOS的中斷機制支援中斷共享。
1.1 中斷的介紹
與中斷相關的硬體可以劃分為三類:裝置、中斷控制器、 CPU本身。
裝置:發起中斷的源,當裝置需要請求CPU時,產生一箇中斷訊號,該訊號連線至中斷控制器。
中斷控制器:中斷控制器是CPU眾多外設中的一個,它一方面接收其它外設中斷引腳的輸入,另一方面,它會發出中斷訊號給CPU。可以通過對中斷控制器程式設計實現對中斷源的優先順序、觸發方式、開啟和關閉源等設定操作。常用的中斷控制器有VIC(Vector Interrupt Controller)和GIC(General Interrupt Controller),在ARM Cortex-A7中使用的中斷控制器是GIC。
CPU: CPU會響應中斷源的請求,中斷當前正在執行的任務,轉而執行中斷處理程式。
1.2 和中斷相關的名詞解釋
中斷號:每個中斷請求訊號都會有特定的標誌,使得計算機能夠判斷是哪個裝置提出的中斷請求,這個標誌就是中斷號。
中斷請求:“緊急事件”需向CPU提出申請(發一個電脈衝訊號),要求中斷,及要求CPU暫停當前執行的任務,轉而處理該“緊急事件”,這一申請過程稱為中斷申
請。
中斷優先順序:為使系統能夠及時響應並處理所有中斷,系統根據中斷時間的重要性和緊迫程度,將中斷源分為若干個級別,稱作中斷優先順序。 Huawei LiteOS中所有的中斷源優先順序相同,不支援中斷巢狀或搶佔。
中斷處理程式:當外設產生中斷請求後, CPU暫停當前的任務,轉而響應中斷申請,即執行中斷處理程式。
中斷觸發:中斷源發出並送給CPU控制訊號,將介面卡上的中斷觸發器置“1”,表明該中斷源產生了中斷,要求CPU去響應該中斷,CPU暫停當前任務,執行相應的中斷處理程式。
中斷觸發型別:外部中斷申請通過一個物理訊號傳送到GIC,可以是電平觸發或邊沿觸發。
中斷向量:中斷服務程式的入口地址。
中斷向量表:儲存中斷向量的儲存區,中斷向量與中斷號對應,中斷向量在中斷向量表中按照中斷號順序儲存。
中斷共享:當外設較少時,可以實現一個外設對應一箇中斷號,但為了支援更多的硬體裝置,可以讓多個裝置共享一箇中斷號,共享同一個中斷的中斷處理程式形成一個連結串列,當外部裝置產生中斷申請時,系統會遍歷中斷號對應的中斷處理程式連結串列。
中斷底半部:中斷處理程式耗時應儘可能短,以滿足中斷的快速響應,為了平衡中斷處理程式的效能與工作量,將中斷處理程式分解為兩部分:頂半部和底半部。
頂半部完成儘可能少的比較緊急的任務,它往往只是簡單地讀取暫存器中的中斷狀態並清除中斷標誌位即進行“登記工作”,將耗時的底半部處理程式掛到系統的底半部執行佇列中去。
1.3 運作機制
Huawei LiteOS的中斷機制支援中斷共享:
中斷共享的實現依賴於連結串列,對應每一箇中斷號建立一個連結串列,連結串列節點中包含註冊的中斷處理函式和函式入參。當對同一中斷號多次建立中斷時,將中斷處理函式和函式入參新增到中斷號對應的連結串列中,因此當硬體產生中斷時,通過中斷號查詢到其對應的結構體連結串列,遍歷執行連結串列中的中斷處理函式。
Huawei LiteOS的中斷機制支援中斷底半部:
中斷底半部的實現基於workqueue,在中斷處理程式中將工作分為頂半部和底半部,底半部處理程式與work關聯,並掛載到合法workqueue上。系統空閒時執行workqueue中的work上的底半部程式。
2. 開發指導
2.1 使用場景
當有中斷請求產生時, CPU暫停當前的任務,轉而去響應外設請求。根據需要,使用者通過中斷申請,註冊中斷處理程式,可以指定CPU響應中斷請求時所執行的具體操作。
2.2 功能
Huawei LiteOS 系統中的中斷模組為使用者提供下面幾種功能。
介面名 | 描述 |
---|---|
LOS_HwiCreate | 硬中斷建立,註冊硬中斷處理程式 |
LOS_IntUnLock | 開中斷 |
LOS_IntRestore | 恢復到關中斷之前的狀態 |
LOS_IntLock | 關中斷 |
hal_interrupt_mask | 中斷遮蔽(通過設定暫存器,禁止CPU響應該中斷) |
hal_interrupt_unmask | 中斷使能(通過設定暫存器,允許CPU響應該中斷) |
2.3 HWI錯誤碼
對建立中斷存在失敗可能性的操作返回對應的錯誤碼,以便快速定位錯誤原因。
序 號 | 定義 | 實際數值 | 描述 | 參考解決方案 |
---|---|---|---|---|
1 | OS_ERRNO_HWI_NUM_INVALID | 0x02000900 | 無效中斷號 | 檢查中斷號,給定有效中斷號 |
2 | OS_ERRNO_HWI_PROC_FUNC_NULL | 0x02000901 | 中斷程式指標為空 | 傳入非空中斷處理程式指標 |
3 | OS_ERRNO_HWI_CB_UNAVAILABLE | 0x02000902 | 無可用中斷資源 | 通過配置,增大可用中斷最大數量 |
4 | OS_ERRNO_HWI_NO_MEMORY | 0x02000903 | 記憶體不足 | 增大記憶體空間 |
5 | OS_ERRNO_HWI_ALREADY_CREATED | 0x02000904 | 中斷處理程式已經建立 | 檢查傳入的中斷號對應的中斷處理程式是否已經被建立 |
6 | OS_ERRNO_HWI_PRIO_INVALID | 0x02000905 | 中斷優先順序無效 | 傳入有效中斷優先順序[0,31] |
7 | OS_ERRNO_HWI_MODE_INVALID | 0x02000906 | 中斷模式無效 | 傳入有效中斷模式[0,1] |
8 | OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED | 0x02000907 | 快速模式中斷已經建立 | 檢查傳入的中斷號對應的中斷處理程式是否已經被建立 |
9 | OS_ERRNO_HWI_INTERR | 0x02000908 | 介面在中斷中呼叫 中斷中禁止呼叫該介面 |
2.4 開發流程
- 修改配置項
- 開啟硬中斷裁剪開關: OS_INCLUDE_HWI定義為YES.
- 配置硬中斷使用最大數: OS_HWI_MAX_USED_NUM.
- 呼叫中斷初始化Los_HwiInit介面。
- 呼叫中斷建立介面LOS_HwiCreate建立中斷
- 呼叫hal_interrupt_unmask介面使能指定中斷。
- 呼叫hal_interrupt_mask介面遮蔽指定中斷。
3. 程式設計例項
3.1 例項描述
本例項實現如下功能。
- 關中斷
- 中斷建立
- 中斷使能
- 中斷恢復
- 中斷遮蔽
3.2 程式設計示例
前提條件:
- 在los_config.h中,將OS_INCLUDE_HWI定義為YES。
- 在los_config.h中,設定最大硬中斷個數OS_HWI_MAX_USED_NUM。
程式碼實現如下:
#include "los_hwi.h"
#include "los_typedef.h"
#define HWI_NUM_INT50 50
void uart_irqhandle(int irq,void *dev)
{
printf("\n int the func uart_irqhandle \n");
}
void hwi_test()
{
int a = 1;
UINTPTR uvIntSave;
uvIntSave = LOS_IntLock();
LOS_HwiCreate(HWI_NUM_INT50, 0,0,uart_irqhandle,NULL);//建立中斷
hal_interrupt_unmask(HWI_NUM_INT50);
LOS_IntRestore(uvIntSave);
hal_interrupt_mask(HWI_NUM_INT50);
}