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);
}