目錄
前言
正文
1.中斷概念分析
1.1?中斷處理API
1.2?中斷級別
1.3?中斷向量表
1.4?二類中斷的嵌套
1.4.1概述
1.4.2激活
1.5一類中斷
1.5.1一類中斷的實現
1.5.2一類中斷的嵌套
1.5.3在StartOS之前的1類ISR
1.5.4使用1類中斷時的注意事項
1.6中斷源的初始化
1.7未處理的中斷
1.8未處理的系統調用
1.9零類中斷
1.9.1一類中斷的實現
1.9.2一類中斷的嵌套
1.9.3在StartOS之前的0類ISR
1.9.4零類isr被鎖定的位置
1.9.5使用0類中斷時的注意事項
2.中斷配置
前言
通過《【TC3xx芯片】TC3xx中斷路由IR模塊詳解》一文我們學習了TC3xx芯片中斷的硬件實現,通過《【OS】AUTOSAR架構下的中斷和異常向量表》一文中我們知道中斷向量表的起始地址標識符在Os生成的鏈接文件中定義,用戶需要在啟動代碼中初始化BIV寄存器,知道這兩點我們就能集成使用Os中斷功能,但是關于更多的Os中斷的細節知識還需要繼續學習,比如,你能回答以下的幾個問題嗎?
問題1:以下三組OS ISR相關的API有何區別,分別適合在什么場景下使用?
DisableAllInterrupts()
EnableAllInterrupts()
SuspendAllInterrupts()
ResumeAllInterrupts()
SuspendOSInterrupts()
ResumeOSInterrupts()
問題2:以下兩個OS ISR相關的API有何區別,分別適合在什么場景下使用?
Os_InitialEnableInterruptSources()
Os_EnableInterruptSource()
問題3:二類中斷完全由OS實現,那么該如何使用一類中斷了?
問題4:TC3xx芯片是如何處理中斷的?
問題5:詳細闡述一個中斷的配置及其處理過程,以CAN中斷為例。
問題6:OS是如何處理中斷優先級的?
縮略詞
簡寫 | 全稱 |
BTV | Base?Trap?Vector Table Pointer |
BIV | Base?Interrupt?Vector Table Pointer |
ISR | Interrupt?Service?Router |
SRC | Service?Request?Control Register |
IR | Interrupt?Router |
ICU | Interrupt?Control?Unit |
ICR | ICU?Interrupt Control |
AUTOSAR?BSW Tool:Vector
AUTOSAR MCAL Tool:EB
Hardware Platform: Infineon Tricore?TC387
Build Tool:?Tasking
Debug Tool: UDE
注:本文章引用了一些第三方工具和文檔,若有侵權,請聯系作者刪除!
正文
1.中斷概念分析
1.1?中斷處理API
AUTOSAR標準指定了幾個以下API來禁用/啟用中斷。
DisableAllInterrupts() EnableAllInterrupts() | 該功能將禁用所有類別1和類別2的中斷。 |
SuspendAllInterrupts() ResumeAllInterrupts() | |
SuspendOSInterrupts() ResumeOSInterrupts() | 該功能僅禁用類別2的中斷 |
1.2?中斷級別
l2類中斷的優先級必須低于1類中斷的優先級。
l1類中斷的優先級必須低于時間保護ISR(SC2 / SC4系統)。
l時間保護ISR的優先級必須低于0類ISR(第0類ISRs詳見第1.9小結)。
l用戶無法設置時間保護鎖(TP Lock)級別。每當OS內部在處理時間保護相關的任務時會使用到TP Lock,這個時候中斷時都是被禁用的(Disabled)。
l0類?ISRs在內部禁用很短的操作系統,例如在執行堆棧開關時(0類?ISRs被鎖定的位置在1.9小結中描述)。
1.3?中斷向量表
MICROSAR OS會根據用戶的配置、使用的MCU類型、使用的編譯器類型生成中斷向量表。
在一個多核系統中,可以生成多個向量表。
MICROSAR OS會為每一個可能的中斷源生成一個中斷向量。
1.4?二類中斷的嵌套
1.4.1概述
為了保持中斷延遲盡可能低,OS遵守以下中斷優先級規則:
l更高優先級的二類中斷可以中斷正在執行的低優先級的二類中斷。
l一類中斷的優先級始終高于二類中斷的優先級(一類中斷始終可以打斷二類中斷)。
1.4.2激活
設置“OsIsrEnableNesting”參數為TRUE后,2類ISR本身可以被更高優先級的ISR中斷。
1.5一類中斷
1.5.1一類中斷的實現
MICROSAR OS提供了一個宏,用于實現一類ISR。類似AUTOSAR標準定義的2類ISR的宏。MICROSAR OS抽象了所需的編譯器關鍵字。
Implement a category 1 ISR
OS_ISR1(<MyCategory1ISR>)
{
}
1.5.2一類中斷的嵌套
由于1類ISR是直接從中斷向量表調用的,沒有任何操作系統的支持,因此不支持第1類ISR的自動嵌套。
忽略1類ISR的“OsIsrEnableNesting”配置屬性。
然而,可以在1類?ISR期間啟用中斷以允許中斷嵌套,但OS API函數不能用于此目的。應用程序必須使用編譯器固有函數或內聯匯編語句。
Example
OS_ISR1(<MyCategory1ISR>)
{
__asm(EI); /* enable nesting of this ISR */
__asm(DI); /* disable nesting before leaving the function */
}
1.5.3在StartOS之前的1類ISR
在操作系統啟動之前,可能需要激活1類ISR。
以下動作序列需要被執行:
1.調用Os_InitMemory()
2.調用Call Os_Init(),?(在該函數中,基本的中斷控制器設置被初始化,例如中斷源的優先級))。
3.通過直接操作中斷控制器中的控制寄存器,來啟用1類ISR的中斷源。
4.通過直接操作全局中斷標志和/或當前中斷優先級來啟用中斷,以允許1類ISR.
1.5.4使用1類中斷時的注意事項
1.在不支持中斷請求時棧切換(中斷棧和用戶棧切換)的芯片平臺上,如果發生了1類中斷則不會發生棧切換。因此,1類中斷的堆棧消耗將應該被添加到所有可以被1類ISR消耗的堆棧中。
2.雖然中斷優先級是由MICROSAR OS初始化的,但是沒有API來啟用1類ISR,?必須直接訪問中斷控制寄存器來Enable 1類中斷。
3.AUTOSAR OS標準不允許在1類ISR中使用OS API(唯一的例外是中斷處理API)。如果在1類中斷處理函數中調用了不允許使用的OS API,MICROSAR OS就無法檢測到這一點,并且調用的API可能不能按預期工作。
4.一類中斷始終在Trusted權限或者Supervisor等級下被執行。
5.宏“OS_ISR1”抽象了用于實現中斷服務程序的適當編譯器關鍵字。因此,編譯器生成保護并恢復通用寄存器子集的代碼。在某些用例中,例如使用FPU或嵌套中斷,它可能需要應用程序保存和恢復更多的寄存器。
1.6中斷源的初始化
通過操作系統配置,MICROSAR操作系統知道中斷源的分配和ISR的優先級。在多核系統中,所有isr的核心分配也是已知的。基于這些配置信息,MICROSAR OS生成用于初始化中斷控制器的數據結構。它初始化中斷優先級及其核心分配。
使能中斷源:
操作系統只對操作系統生成的定時器ISR啟用中斷源。
只有當應用程序啟用了相應的中斷源時,才能為其他用戶ISR提供服務。
這應該通過使用中斷源API來完成(詳見Os_EnableInterruptSource()函數)。
1.7未處理的中斷
沒有分配給用戶定義ISR的中斷源被分配給一個默認的操作系統中斷處理程序,該處理程序收集這些中斷源。
因此,來自未分配中斷源的中斷請求由操作系統處理。在OS Hooks(例如ProtectionHook())中,應用程序可以通過OS API獲得未處理中斷請求的源編號。
如果一個未處理的中斷請求發生在操作系統代碼中,MICROSAR OS調用PanicHook(),因為一個不一致的內部狀態被識別出來,操作系統不知道如何正確地繼續執行。
如果一個未處理的中斷請求發生在關鍵用戶段,即StartupHook,?ErrorHook, PreTaskHook, PostTaskHook,?Alarm回調,IOC接收器回調,Timing Hooks,?ProtectionHook和ShutdownHook,?MICROSAR OS調用PanicHook(),因為一個不一致的內部狀態被識別,操作系統不知道如何正確地繼續執行。
在所有其他未處理中斷請求的情況下,MICROSAR OS調用帶有參數E_OS_SYS_PROTECTION_IRQ的ProtectionHook().
1.8未處理的系統調用
未分配給操作系統或用戶處理程序的系統調用源被分配給收集這些異常的默認操作系統系統調用處理程序。
因此,來自未分配的系統調用源的系統調用請求由操作系統處理。如果一個未處理的系統調用請求發生在操作系統代碼中,MICROSAR操作系統調用PanicHook(),因為一個不一致的內部狀態被識別,操作系統不知道如何正確地繼續執行。
如果一個未處理的系統調用請求發生在關鍵用戶部分,即StartupHook,?ErrorHook, PreTaskHook, PostTaskHook,?Alarm回調,IOC接收器回調,Timing Hooks,?ProtectionHook和ShutdownHook,?MICROSAR OS調用PanicHook(),因為一個不一致的內部狀態被識別,操作系統不知道如何正確地繼續執行。
在所有未處理的系統調用請求的其他情況下MICROSAR OS調用ProtectionHook()參數E_OS_SYS_PROTECTION_SYSCALL.
1.9零類中斷
MICROSAR OS實現了0類ISRs,以具有最小的中斷延遲時間,特別是在SC2或SC4系統中。這是對AUTOSAR操作系統標準的一個擴展。
1.9.1一類中斷的實現
MICROSAR OS提供了一個宏,用于實現一類ISR。類似AUTOSAR標準定義的2類ISR的宏。MICROSAR OS抽象了所需的編譯器關鍵字。
Implement a category?0?ISR
OS_ISR0(<MyCategory0ISR>)
{
}
1.9.2一類中斷的嵌套
由于0類ISR是直接從中斷向量表調用的,沒有任何操作系統的支持,因此不支持第0類ISR的自動嵌套。
忽略0類ISR的“OsIsrEnableNesting”配置屬性。
然而,可以在0類?ISR期間啟用中斷以允許中斷嵌套,但OS API函數不能用于此目的。應用程序必須使用編譯器固有函數或內聯匯編語句。
Example
OS_ISR0(<MyCategory0ISR>)
{
__asm(EI); /* enable nesting of this ISR */
__asm(DI); /* disable nesting before leaving the function */
}
1.9.3在StartOS之前的0類ISR
在操作系統啟動之前,可能需要激活0類ISR。
以下動作序列需要被執行:
1.調用Os_InitMemory()
2.調用Call Os_Init(),?(在該函數中,基本的中斷控制器設置被初始化,例如中斷源的優先級))。
3.通過直接操作中斷控制器中的控制寄存器,來啟用0類ISR的中斷源。
4.通過直接操作全局中斷標志和/或當前中斷優先級來啟用中斷,以允許0類ISR.
1.9.4零類isr被鎖定的位置
0類中斷只能在很短的時間內在操作系統內部禁用。
以下列表中的操作提到了這些鎖的位置(會禁用0類中斷):
l導致上下文切換的api內部,例如TerminateTask().
l由ProtectionHook處理的異常導致部分終止。
l中斷,異常和陷阱進入和返回。
lOs_Init()和StartOS()中的OS初始化。
1.9.5使用0類中斷時的注意事項
1.在不支持中斷請求時棧切換(中斷棧和用戶棧切換)的芯片平臺上,如果發生了0類中斷則不會發生棧切換。因此,0類中斷的堆棧消耗將應該被添加到所有可以被0類ISR消耗的堆棧中。
2.零類ISR正在消耗中斷任務或2類ISR的時間保護預算(執行預算和鎖定時間)。
3.雖然中斷優先級是由MICROSAR OS初始化的,但是沒有API來啟用0類ISR,?必須直接訪問中斷控制寄存器來Enable 0類中斷。
4.如果發生時間保護中斷,執行(時間保護violation handling/protection hook)延遲到0類ISR運行期間,則其0類ISR已經完成。
5.AUTOSAR OS標準不允許在0類ISR中使用OS API(唯一的例外是中斷處理API)。如果在0類中斷處理函數中調用了不允許使用的OS API,MICROSAR OS就無法檢測到這一點,并且調用的API可能不能按預期工作。
6.一類中斷始終在Trusted權限或者Supervisor等級下被執行。
7.零類ISR可能永遠不會降低CPU或中斷的中斷優先級。
8.在操作系統關閉的情況下,甚至在操作系統進入Panic Hook的情況下,仍然可能發生0類isr。
9.請注意,0類ISR能中斷2類ISR,即使2類ISR被配置為不可嵌套的。
10.如果0類ISR的owner application因任何原因被終止,分配的0類ISR也不會被禁用。
11.宏“OS_ISR0”抽象了用于實現中斷服務程序的適當編譯器關鍵字。因此,編譯器生成保護并恢復通用寄存器子集的代碼。在某些用例中,例如使用FPU或嵌套中斷,它可能需要應用程序保存和恢復更多的寄存器。
2.中斷配置
Short Name?: ISR的名字,如果該ISR所屬的模塊是Vector SIP包中的模塊,則ISR的名字和類別是固定的(不可修改的,比如CanIsr_xxx)。
Isr Category?: ISR的類別(0,1,2三種類別的中斷),2類中斷由OS接管,用戶只需要調用OS接口Enable二類中斷。0類和1類中斷需要用戶實現中斷處理函數,且需要用戶在StartOS之前啟用中斷。0類中斷的時間延遲最小。
Isr Enable Nesting:?中斷是否可以被嵌套,僅適用于2類中斷。如果2類中斷配置為TRUE,則該2類中斷可以被更高優先級的中斷打斷。
Isr Initial Enable Interrupt Source?:?配置中斷是否會被Os_InitalEnableInterruptSources()函數Enable.
Isr Interrupt Mapping?:?如果相關模塊的數據搬運交給DMA處理,這需要配置這個參數。
Isr Interrupt Priority?:?配置中斷優先級,這個地方的中斷優先級是個相對值,OS在生成代碼的時候會根據這些相對值生成優先級絕對值排序。
Isr Interrupt Source:?配置中斷號(中斷地址)。
每一個中斷請求都和一個SRN一一對應,比如:
對于CAN00,也就是CAN0INT0,對應SRC為SRC_CAN0INT0,對應的SRC地址為:
0x5B0 +0*0x40 +?0*4 = 0x5B0 = 1456
Isr Interrupt Type?:?配置ISR是外部中斷(External)還是異常(Exception)。注意:中斷和異常(.e.g. NMI)其實是兩個概念,但是Exception的產生和處理過程和ISR基本一樣,所以Davnici中將Exception放在了ISR中配置。
Isr Memory Protection Identifier?:?配置ISR所屬的內存保護集(MPU Set),如果沒有配置,則該ISR和ISR所屬的Application的MPU Set配置一樣。至于什么是MPU Set清參考《【TC3xx芯片】TC3xx芯片MPU介紹》一文。
Isr Special Function Name?:?中斷處理函數的名字默認由Short Name參數生成,但是用戶也可以通過Isr Special Function Name特別指定。
Isr Stack Size?:?指定中斷棧大小。Microsar OS的Task和ISR都有獨立的棧,
Isr Stack Fpu?:?指定ISR是否使用FPU。
由于TriCore Aurix平臺沒有需要在上下文切換中保存的專用FPU寄存器,因此不需要由于使用浮點數而擴展上下文。