正文
1. OS錯誤處理介紹
1.1 錯誤類型
OS的Error類型分為三類,Application Errors, Protection Errors, Kernel Errors, 每種Errors產生的原因及產生Error后OS執行的動作都不相同,詳見下表:
Error Types | Feature |
Application Errors |
1.如果操作系統無法正確執行應用程序請求的操作系統提供的API服務,則引發Application Erros。典型情況就是操作系統API使用錯誤(例如對象ID無效)。 2.Application Error不會損壞操作系統內部數據。 3.如果配置了Error Hook,則OS會調用ErrorHook(),ErrorHook()是一個Callout函數,需要用戶自定義錯誤處理機制。 4.不會造成OS調用Shutdown/terminate。應用程序可以通過簡單地從ErrorHooks返回來繼續執行。 |
Protection Errors |
1.如果應用程序違反其配置的邊界則會觸發Protection Errors, 典型的就是配置了內存保護或者時間保護后發生內存非法訪問或超時。 2.Protection Errors不會損壞操作系統內部數據。 3.在發生未處理的異常和中斷時會觸發Protection Error。 4.將導致ProtectionHook()的調用,在該調用中可以選擇引發Shutdown或Terminatehanding(ProtectionHook返回值將覺得OS接下來的執行流,無論是否重新啟動)。 5.如果配置了Shutdownhook,則會調用ShutdownHook(). 6.如果配置了ProtectionHook,則會調用ProtectionHook(). |
Kernel Errors |
1.如果操作系統無法再確保其內部數據的正確性,則引發Kernel Errors(例如,ProtectionHook()期間內存訪問違規)。 2.發生Kernel Errors后OS會關閉所有中斷且調用Os_PannicHook()通知應用程序。 3. 最后操作系統進入無限循環。 |
1.2 錯誤碼
發生Application Errors后OS會調用ErrorHook(),ErrorHook()函數是callout函數,函數原型:
(void) ErrorHook(StatusType Error);
參數Error標識具體的錯誤碼
發生Protection Errors后OS會調用ProtectionHook(), ProtectionHook函數是callout函數,函數原型:
ProtectionReturnType ProtectionHook(StatusType Fatalerror);
參數Fatalerror標識具體的錯誤碼
返回值類型ProtectionReturnType是一個枚舉類型:
typedef enum ProtectionReturnType_e { PRO_IGNORE, PRO_TERMINATETASKISR, PRO_TERMINATEAPPL, PRO_TERMINATEAPPL_RESTART, PRO_SHUTDOWN, PRO_NOTCONFIGURED } ProtectionReturnType;
也就是,我們可以通過自定義ProtectionHook()的返回值來控制發送ProtectionHook后Os的執行流。
每個廠商(Vector, Etas…)Os實現的Os_Types.h文件中都具體定義了每一種ErrorCode,這里以Vector的代碼實現為例說明每種Error Type包含的常見的Error Code:
ErrorTypes | 包含的Error Codes |
Application Errors |
E_OS_ACCESS: Illegal access E_OS_CALLEVEL:Invalid calling context. E_OS_ID:Invalid OS object ID. E_OS_LIMIT: Maximum task activations reached. E_OS_NOFUNC: OS object is currently not in use. E_OS_RESOURCE:Scheduling requested with occupied resource. E_OS_STATE: OS object is not in correct state to perform the requested operation. E_OS_VALUE:Given value is out of the configured range. E_OS_SERVICEID: Service cannot be called. |
Protection Errors |
E_OS_PROTECTION_MEMORY:A memory access violation occurred. E_OS_PROTECTION_EXCEPTION: A trap occurred. E_OS_SYS_PROTECTION_SYSCALL: An unhandled syscall occurred. E_OS_STACKFAULT: A stack fault detected via stack monitoring by the OS. E_OS_SYS_API_ERROR: Wrong API usage. |
1.3 Davinci中配置OsHooks
三個Error相關的Hook函數可以在Davinci中配置,如果配置后就需要用戶自定義實現。
2. 自定義錯誤處理
通過第一節,我們知道了Error的類型及其包含的具體的Error Code,同時,如果我們配置Error發生后Hook函數,那么在Error發生時我們就能被通知到。那么現在,我們在Error發生后應該考慮如何存儲錯誤相關的信息,同時能在事后通過存儲的Error相關信息定位和分析Error。
2.1 錯誤信息存儲
背景知識1:RAMRetention。RAMretention是一種技術,用于在斷電后保持隨機存取存儲器(RAM)中的數據。在計算機系統中,RAM是一種易失性存儲器,這意味著在斷電情況下,其中的數據會被清除。這對于一些應用程序來說是不可接受的,因為它們需要在斷電后仍然能夠保持數據。這就是RAMretention技術的用武之地。
背景知識2:斷電系統和深度休眠系統。ECU在設計時根據具體需求可以在硬件上添加SBC或無SBC。如果ECU有SBC,ECU就是一個斷電系統。那么ECU在系統下電(Shutdown)流程的最后一步會調用SBC的服務接口斷掉MCU的電,整個MCU在休眠中是處于斷電狀態的。在外部信號(Can Transceiver/Lin Transceiver的INH引腳,Dio喚醒引腳 )喚醒MCU時,SBC重新給MCU供電,MCU重新冷啟動。
如果ECU無SBC,ECU就是一個深度休眠系統。那么ECU在系統下電(Shutdown)流程的最后一步會調用MCU的服務進入到Deep Sleep深度休眠狀態(MCU陷入深度休眠狀態,程序不在運行,但是MCU還有電存在)。在外部信號(Can Transceiver/Lin Transceiver的INH引腳,Dio喚醒引腳 )通過中斷喚醒MCU,MCU被喚醒后,程序可以選擇軟件復位,整個軟件重新運行,也可以選擇從上次停止的地方接著運行。
Aurix芯片進入深度休眠后后SCR會接管芯片控制,在進入SCR前可以配置PMS模塊的PMSWCR0.STBYRAMSEL位域,選擇給哪快RAM進行供電。只有休眠后改被供電的RAM才有RAMRetentions的功能。
問題1:為什么要考慮錯誤信息的存儲了?
答:因為Error發生時如果時Protection Error的話,一般就會在OS調用ProtectionHook()后執行Shutdown,在ShutdownHook()中一般執行ECU復位了,如果我們不存儲Error發生時的上下文信息的話,一旦系統復位的話我們就無法再分析Error發生的原因了。
問題2:錯誤信息存儲在那里了,是不是可以存儲在NvM?
答:錯誤信息可以存儲在NvM中,但是因為ProtectionHook()后一般馬上就要進行MCU復位了,來不及調用異步的NvM接口來存儲錯誤信息了,所以只能把錯誤信息存儲到Retention RAM中。復位起來后,錯誤信息處理SWC讀取Retention RAM中的異常信息,此時可選擇是否再次寫入到NvM當中。
Note:
1.如果系統是斷電系統,那么一定要注意OS ShutdownHook()中調用Mcu_PerformReset()進行軟件復位而不是調用SBC的接口給MCU斷電,因為MCU斷電后是冷啟動,Retention RAM中的數據也沒了。
2.如果系統是深度休眠系統且使用Aurix芯片的SCR功能,那么Retention RAM一定要配置在PMSWCR0.STBYRAMSEL配置供電的RAM塊中。
3.無論是深度休眠系統還是斷點系統,MCU復位后在Main函數之前的Startup階段都不能把Retention RAM給清零了(需要修改啟動代碼和連接器腳本)。
2.2 關鍵上下文信息獲取
問題1:通過2.1小結我們知道錯誤信息應該存放在Retention RAM當中,那么我們應該存儲哪些異常時的上下文信息了?
答:我們通過一個表格來舉例給出答案。
Error Types | Error Contex |
Application Errors |
如果在使用Spinlock是發生Application Error,可以獲取以下信息: 1.通過Os_GetDetailedError()獲取服務ID及Error Code等信息。 2.通過OSError_GetSpinlock_SpinlockId()返回錯誤的GetSpinlock調用的參數SpinlockId. 使用其他OS服務,比如Alarm, Resource等發生錯誤時同樣可以調用OsError_xxx_xxx()獲取相關錯誤現場信息。 |
Protection Errors |
1.ProtectionHook()的參數Fataerror. 2.通過GetTaskID獲取Error發生時的正在處理的Task. 3.通過GetISRID()獲取當前執行ISR的標識符。 4.通過Os_GetExceptionAddress()獲取引發最新異常的指令的地址。 5.讀取DEADD寄存器獲取發生trap時的地址信息。 6.通過Os_GetExceptionContext()獲取異常上下文信息,異常結構體為:struct Os_ExceptionContextType_Tag; 通過結構體成員Ra和ExceptionSource對應的TIN和Class信息,可以輕松定位MPU保護產生的Error. |
Kernel Errors | 通過GetTaskID獲取Error發生時的正在處理的Task. |
/*!Setofhardwareregisterstobeabletoresumefromanexception.*/ structOs_ExceptionContextType_Tag { /*StoredAddressregistersofthethread(a2-a7,a12-a15)*/ uint32AddressRegisters[16]; /*StoredDataregistersofthethread(d0-d15)*/ uint32DataRegisters[16]; /*!Storedreturnaddressofthethread*/ uint32Ra; /*!StoredPswofthethread*/ uint32Psw; /*!StoredExceptionsource(Exceptionclassandtinnumber)ofthethread*/ uint32ExceptionSource; /*!StoredPcpn(PreviousCPUPrioritynumber)fromthePcxiofthethread*/ uint32Pcpn; /*!StoredPie(PreviousInterruptEnable)fromthePcxiofthethread*/ uint32Pie; /*!TheloweraddressoftheMPUregionforstack.*/ uint32MpuRegionForStackLow; /*!TheupperaddressoftheMPUregionforstack.*/ uint32MpuRegionForStackUpper; /*!TherawPCXIvaluefromtheuppercontext;maybeusedtolookupinCSAspriortotheexception*/ uint32RawPCXI; };
2.3 錯誤定位
對于Application Error一般都是錯誤使用OSAPI導致的,只要我們記錄好錯誤發生時的ServiceID等就能輕松定位。
對于Kernel Error由于OS內部數據可能被異常打亂了,數據不在可信,可獲取的上下文信息不多,這類錯誤就只能根據具體硬件平臺和OS代碼積累經驗了(開發階段可以通過故障注入提前獲知Kernel Error產生后的表現)。
實際項目中最可能出問題的就是Protection Error了,而這里面也以MPU保護Error為最常見。出現內存保護Error后,通過Ra(A11程序返回寄存器)查找Map文件可以大概知道那塊代碼(指令所在的地址)發生異常;通過DEADD寄存器可以得知大概是訪問了哪塊Data數據(訪問的數據的地址)發生了異常,比如異常改寫了調用棧內容。
3.總結
最后通過回答開頭的三個問題來結束本文。
問題1:有哪里常見的OS錯誤 ?
答:大類有Application Errors, Protection Errors, Kernel Errors三種,每種大類包含的具體ErrorCode可以參考1.1章節。
問題2:如何進行OS錯誤處理?
答:通過Retention RAM來存儲OS錯誤信息,通過OS給出的一系列API獲取Error發生時的上下文信息。
審核編輯:劉清
-
RAM
+關注
關注
8文章
1340瀏覽量
114090 -
SCR
+關注
關注
2文章
149瀏覽量
43949 -
AUTOSAR
+關注
關注
10文章
336瀏覽量
21329 -
SBC
+關注
關注
0文章
68瀏覽量
19084 -
易失性存儲器
+關注
關注
0文章
14瀏覽量
6699
原文標題:AUTOSAR架構下的OS錯誤處理
文章出處:【微信號:汽車電子嵌入式,微信公眾號:汽車電子嵌入式】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論