Zephyr中斷系統一覽
首先我們來看下Zephyr中的中斷系統有什么特別之處:
1. 內核為所有未使用的中斷提供了默認的中斷服務程序,如果一個未定義中斷被觸發會產生一個系統錯誤
2. 支持中斷的嵌套
3. 中斷服務程序執行在內核中斷上下文
擁有自己的棧空間
要注意,棧的容量要足夠大,以支持中斷的嵌套
4. 軟中斷服務程序
常規中斷一般都通過一個叫做軟中斷的服務程序進行管理
通過查找軟中斷向量表,能夠獲取實際要執行的中斷服務程序(下文統稱ISR)入口以及參數
從ISR返回時,決定是否進行線程的切換
5. 多數內核API只能在線程中使用,不能在ISR中使用,那些可以在ISR中使用的內核API往往都有一個isr_ok的屬性。
Zephyr的ISR
再來看下,Zephyr中的ISR類型,Zephyr中的中斷服務類型大致分為3類:
1. 常規ISR:
由軟中斷服務程序所調用,不能直接運行
簡單,使用方便
2. 直接ISR:
不使用軟中斷服務程序,直接注冊進硬件中斷向量表中
低延時,但是有很多限制,比如不能傳入參數
3. 零延時ISR:顧名思義就是延時最低的
擁有最高的中斷優先級,不受中斷鎖影響
既可以是常規ISR也可以是直接ISR
Zephyr的中斷向量表
說完中斷類型,介紹一下Zephyr中的中斷向量表的概念,除了硬件中斷向量表,Zephyr中還有一個較為新的概念,我們在上文中也有所提及,叫做軟件中斷向量表,那么他們都各自負責什么呢?我們來一一介紹。
1. 硬件中斷向量表:前16個位置固定給了內核服務,其他位置,如果沒有被注冊的話,填入的是通用的中斷服務程序_isr_wrapper()
2. 軟件中斷向量表:內部存儲的是所注冊的中斷服務程序,以及想要傳入的參數,所有所有未添加中斷服務程序的地方,都會被寫入z_irq_spurious()
3. 通用中斷服務程序_isr_wrapper()作用:
中斷函數第一入口,他是軟件中斷向量表的使用者
負責取出真正的中斷服務程序入口以及參數
4. 直接中斷:直接被裝配到硬件中斷向量表,當中斷到來時,直接被執行
下圖是完整的中斷服務注冊邏輯:
如何定義一個中斷
了解了中斷實現以及執行邏輯,我們來看看如何實際定義一個中斷,首先是常規中斷,只需要兩個步驟:
1. 使用宏IRQ_CONNECT進行中斷定義,需要注意的是,所有參數的數值必須是編譯期確定的,其原型是IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p),各參數說明如下:
irq_p: 中斷號
priority_p: 中斷優先級
isr_p: 中斷服務函數
fags_p: 中斷標志
2. 使用irq_enable()使能中斷
當然,上述方式是在編譯期進行中斷的注冊,Zephyr也同時支持運行期間通過調用函數irq_connect_dynamic()注冊,但是需要配置CONFIG_DYNAMIC_INTERRUPTS
下面是一段參考事例:
接下來是直接中斷,實現方式略有不同,需要用戶調用IRQ_DIRECT_CONNECT:
Zephyr的零延時中斷
最后聊聊零延時中斷,上文說過,零延時中斷的類型可以是直接中斷也可以是常規中斷,換句話說,他的實現方式與上述兩種大致相同,唯一不同的是,中斷標志位需要傳入IRQ_ZERO_LATENCY以指示這是一個零延時中斷。
那么為什么要設計零延時中斷呢?
最主要的原因是,在程序設計時,我們往往會在程序中加入irq lock,保證代碼運行不會被中斷打斷,但是這樣一來,就可能提高系統的延時,對于一些時間敏感的應用案例,高延時往往是不可接受的。
那么此時,零延時中斷的作用就體現了,他自身運行在一個不會被lock的優先級,當然需要通過CONFIG_ZERO_LATENCY_IRQS使能。這樣一來,一旦中斷被觸發,其對應的中斷處理函數能夠馬上被執行,大大降低中斷延時。
結語
本期文章,主要給大家分享了Zephyr中的中斷系統的一些基礎概念,最特殊的地方在于,Zephyr引入了一個軟件中斷向量表的概念,使得我們的中斷服務程序可以接收參數,但是弊端就在于會引入一點中斷延時,這樣在實際使用中,我們就要權衡利弊,各取所好了。
審核編輯:郭婷
-
中斷系統
+關注
關注
1文章
96瀏覽量
61067
原文標題:清風徐來——Zephyr實戰篇(6)之中斷
文章出處:【微信號:NXP_SMART_HARDWARE,微信公眾號:恩智浦MCU加油站】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論