正文
1. OS錯(cuò)誤處理介紹
1.1 錯(cuò)誤類型
OS的Error類型分為三類,Application Errors, Protection Errors, Kernel Errors, 每種Errors產(chǎn)生的原因及產(chǎn)生Error后OS執(zhí)行的動(dòng)作都不相同,詳見(jiàn)下表:
Error Types | Feature |
Application Errors |
1.如果操作系統(tǒng)無(wú)法正確執(zhí)行應(yīng)用程序請(qǐng)求的操作系統(tǒng)提供的API服務(wù),則引發(fā)Application Erros。典型情況就是操作系統(tǒng)API使用錯(cuò)誤(例如對(duì)象ID無(wú)效)。 2.Application Error不會(huì)損壞操作系統(tǒng)內(nèi)部數(shù)據(jù)。 3.如果配置了Error Hook,則OS會(huì)調(diào)用ErrorHook(),ErrorHook()是一個(gè)Callout函數(shù),需要用戶自定義錯(cuò)誤處理機(jī)制。 4.不會(huì)造成OS調(diào)用Shutdown/terminate。應(yīng)用程序可以通過(guò)簡(jiǎn)單地從ErrorHooks返回來(lái)繼續(xù)執(zhí)行。 |
Protection Errors |
1.如果應(yīng)用程序違反其配置的邊界則會(huì)觸發(fā)Protection Errors, 典型的就是配置了內(nèi)存保護(hù)或者時(shí)間保護(hù)后發(fā)生內(nèi)存非法訪問(wèn)或超時(shí)。 2.Protection Errors不會(huì)損壞操作系統(tǒng)內(nèi)部數(shù)據(jù)。 3.在發(fā)生未處理的異常和中斷時(shí)會(huì)觸發(fā)Protection Error。 4.將導(dǎo)致ProtectionHook()的調(diào)用,在該調(diào)用中可以選擇引發(fā)Shutdown或Terminatehanding(ProtectionHook返回值將覺(jué)得OS接下來(lái)的執(zhí)行流,無(wú)論是否重新啟動(dòng))。 5.如果配置了Shutdownhook,則會(huì)調(diào)用ShutdownHook(). 6.如果配置了ProtectionHook,則會(huì)調(diào)用ProtectionHook(). |
Kernel Errors |
1.如果操作系統(tǒng)無(wú)法再確保其內(nèi)部數(shù)據(jù)的正確性,則引發(fā)Kernel Errors(例如,ProtectionHook()期間內(nèi)存訪問(wèn)違規(guī))。 2.發(fā)生Kernel Errors后OS會(huì)關(guān)閉所有中斷且調(diào)用Os_PannicHook()通知應(yīng)用程序。 3. 最后操作系統(tǒng)進(jìn)入無(wú)限循環(huán)。 |
1.2 錯(cuò)誤碼
發(fā)生Application Errors后OS會(huì)調(diào)用ErrorHook(),ErrorHook()函數(shù)是callout函數(shù),函數(shù)原型:
(void) ErrorHook(StatusType Error);
參數(shù)Error標(biāo)識(shí)具體的錯(cuò)誤碼
發(fā)生Protection Errors后OS會(huì)調(diào)用ProtectionHook(), ProtectionHook函數(shù)是callout函數(shù),函數(shù)原型:
ProtectionReturnType ProtectionHook(StatusType Fatalerror);
參數(shù)Fatalerror標(biāo)識(shí)具體的錯(cuò)誤碼
返回值類型ProtectionReturnType是一個(gè)枚舉類型:
typedef enum ProtectionReturnType_e { PRO_IGNORE, PRO_TERMINATETASKISR, PRO_TERMINATEAPPL, PRO_TERMINATEAPPL_RESTART, PRO_SHUTDOWN, PRO_NOTCONFIGURED } ProtectionReturnType;
也就是,我們可以通過(guò)自定義ProtectionHook()的返回值來(lái)控制發(fā)送ProtectionHook后Os的執(zhí)行流。
每個(gè)廠商(Vector, Etas…)Os實(shí)現(xiàn)的Os_Types.h文件中都具體定義了每一種ErrorCode,這里以Vector的代碼實(shí)現(xiàn)為例說(shuō)明每種Error Type包含的常見(jiàn)的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
三個(gè)Error相關(guān)的Hook函數(shù)可以在Davinci中配置,如果配置后就需要用戶自定義實(shí)現(xiàn)。
2. 自定義錯(cuò)誤處理
通過(guò)第一節(jié),我們知道了Error的類型及其包含的具體的Error Code,同時(shí),如果我們配置Error發(fā)生后Hook函數(shù),那么在Error發(fā)生時(shí)我們就能被通知到。那么現(xiàn)在,我們?cè)贓rror發(fā)生后應(yīng)該考慮如何存儲(chǔ)錯(cuò)誤相關(guān)的信息,同時(shí)能在事后通過(guò)存儲(chǔ)的Error相關(guān)信息定位和分析Error。
2.1 錯(cuò)誤信息存儲(chǔ)
背景知識(shí)1:RAMRetention。RAMretention是一種技術(shù),用于在斷電后保持隨機(jī)存取存儲(chǔ)器(RAM)中的數(shù)據(jù)。在計(jì)算機(jī)系統(tǒng)中,RAM是一種易失性存儲(chǔ)器,這意味著在斷電情況下,其中的數(shù)據(jù)會(huì)被清除。這對(duì)于一些應(yīng)用程序來(lái)說(shuō)是不可接受的,因?yàn)樗鼈冃枰跀嚯姾笕匀荒軌虮3謹(jǐn)?shù)據(jù)。這就是RAMretention技術(shù)的用武之地。
背景知識(shí)2:斷電系統(tǒng)和深度休眠系統(tǒng)。ECU在設(shè)計(jì)時(shí)根據(jù)具體需求可以在硬件上添加SBC或無(wú)SBC。如果ECU有SBC,ECU就是一個(gè)斷電系統(tǒng)。那么ECU在系統(tǒng)下電(Shutdown)流程的最后一步會(huì)調(diào)用SBC的服務(wù)接口斷掉MCU的電,整個(gè)MCU在休眠中是處于斷電狀態(tài)的。在外部信號(hào)(Can Transceiver/Lin Transceiver的INH引腳,Dio喚醒引腳 )喚醒MCU時(shí),SBC重新給MCU供電,MCU重新冷啟動(dòng)。
如果ECU無(wú)SBC,ECU就是一個(gè)深度休眠系統(tǒng)。那么ECU在系統(tǒng)下電(Shutdown)流程的最后一步會(huì)調(diào)用MCU的服務(wù)進(jìn)入到Deep Sleep深度休眠狀態(tài)(MCU陷入深度休眠狀態(tài),程序不在運(yùn)行,但是MCU還有電存在)。在外部信號(hào)(Can Transceiver/Lin Transceiver的INH引腳,Dio喚醒引腳 )通過(guò)中斷喚醒MCU,MCU被喚醒后,程序可以選擇軟件復(fù)位,整個(gè)軟件重新運(yùn)行,也可以選擇從上次停止的地方接著運(yùn)行。
Aurix芯片進(jìn)入深度休眠后后SCR會(huì)接管芯片控制,在進(jìn)入SCR前可以配置PMS模塊的PMSWCR0.STBYRAMSEL位域,選擇給哪快RAM進(jìn)行供電。只有休眠后改被供電的RAM才有RAMRetentions的功能。
問(wèn)題1:為什么要考慮錯(cuò)誤信息的存儲(chǔ)了?
答:因?yàn)镋rror發(fā)生時(shí)如果時(shí)Protection Error的話,一般就會(huì)在OS調(diào)用ProtectionHook()后執(zhí)行Shutdown,在ShutdownHook()中一般執(zhí)行ECU復(fù)位了,如果我們不存儲(chǔ)Error發(fā)生時(shí)的上下文信息的話,一旦系統(tǒng)復(fù)位的話我們就無(wú)法再分析Error發(fā)生的原因了。
問(wèn)題2:錯(cuò)誤信息存儲(chǔ)在那里了,是不是可以存儲(chǔ)在NvM?
答:錯(cuò)誤信息可以存儲(chǔ)在NvM中,但是因?yàn)镻rotectionHook()后一般馬上就要進(jìn)行MCU復(fù)位了,來(lái)不及調(diào)用異步的NvM接口來(lái)存儲(chǔ)錯(cuò)誤信息了,所以只能把錯(cuò)誤信息存儲(chǔ)到Retention RAM中。復(fù)位起來(lái)后,錯(cuò)誤信息處理SWC讀取Retention RAM中的異常信息,此時(shí)可選擇是否再次寫入到NvM當(dāng)中。
Note:
1.如果系統(tǒng)是斷電系統(tǒng),那么一定要注意OS ShutdownHook()中調(diào)用Mcu_PerformReset()進(jìn)行軟件復(fù)位而不是調(diào)用SBC的接口給MCU斷電,因?yàn)镸CU斷電后是冷啟動(dòng),Retention RAM中的數(shù)據(jù)也沒(méi)了。
2.如果系統(tǒng)是深度休眠系統(tǒng)且使用Aurix芯片的SCR功能,那么Retention RAM一定要配置在PMSWCR0.STBYRAMSEL配置供電的RAM塊中。
3.無(wú)論是深度休眠系統(tǒng)還是斷點(diǎn)系統(tǒng),MCU復(fù)位后在Main函數(shù)之前的Startup階段都不能把Retention RAM給清零了(需要修改啟動(dòng)代碼和連接器腳本)。
2.2 關(guān)鍵上下文信息獲取
問(wèn)題1:通過(guò)2.1小結(jié)我們知道錯(cuò)誤信息應(yīng)該存放在Retention RAM當(dāng)中,那么我們應(yīng)該存儲(chǔ)哪些異常時(shí)的上下文信息了?
答:我們通過(guò)一個(gè)表格來(lái)舉例給出答案。
Error Types | Error Contex |
Application Errors |
如果在使用Spinlock是發(fā)生Application Error,可以獲取以下信息: 1.通過(guò)Os_GetDetailedError()獲取服務(wù)ID及Error Code等信息。 2.通過(guò)OSError_GetSpinlock_SpinlockId()返回錯(cuò)誤的GetSpinlock調(diào)用的參數(shù)SpinlockId. 使用其他OS服務(wù),比如Alarm, Resource等發(fā)生錯(cuò)誤時(shí)同樣可以調(diào)用OsError_xxx_xxx()獲取相關(guān)錯(cuò)誤現(xiàn)場(chǎng)信息。 |
Protection Errors |
1.ProtectionHook()的參數(shù)Fataerror. 2.通過(guò)GetTaskID獲取Error發(fā)生時(shí)的正在處理的Task. 3.通過(guò)GetISRID()獲取當(dāng)前執(zhí)行ISR的標(biāo)識(shí)符。 4.通過(guò)Os_GetExceptionAddress()獲取引發(fā)最新異常的指令的地址。 5.讀取DEADD寄存器獲取發(fā)生trap時(shí)的地址信息。 6.通過(guò)Os_GetExceptionContext()獲取異常上下文信息,異常結(jié)構(gòu)體為:struct Os_ExceptionContextType_Tag; 通過(guò)結(jié)構(gòu)體成員Ra和ExceptionSource對(duì)應(yīng)的TIN和Class信息,可以輕松定位MPU保護(hù)產(chǎn)生的Error. |
Kernel Errors | 通過(guò)GetTaskID獲取Error發(fā)生時(shí)的正在處理的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 錯(cuò)誤定位
對(duì)于Application Error一般都是錯(cuò)誤使用OSAPI導(dǎo)致的,只要我們記錄好錯(cuò)誤發(fā)生時(shí)的ServiceID等就能輕松定位。
對(duì)于Kernel Error由于OS內(nèi)部數(shù)據(jù)可能被異常打亂了,數(shù)據(jù)不在可信,可獲取的上下文信息不多,這類錯(cuò)誤就只能根據(jù)具體硬件平臺(tái)和OS代碼積累經(jīng)驗(yàn)了(開(kāi)發(fā)階段可以通過(guò)故障注入提前獲知Kernel Error產(chǎn)生后的表現(xiàn))。
實(shí)際項(xiàng)目中最可能出問(wèn)題的就是Protection Error了,而這里面也以MPU保護(hù)Error為最常見(jiàn)。出現(xiàn)內(nèi)存保護(hù)Error后,通過(guò)Ra(A11程序返回寄存器)查找Map文件可以大概知道那塊代碼(指令所在的地址)發(fā)生異常;通過(guò)DEADD寄存器可以得知大概是訪問(wèn)了哪塊Data數(shù)據(jù)(訪問(wèn)的數(shù)據(jù)的地址)發(fā)生了異常,比如異常改寫了調(diào)用棧內(nèi)容。
3.總結(jié)
最后通過(guò)回答開(kāi)頭的三個(gè)問(wèn)題來(lái)結(jié)束本文。
問(wèn)題1:有哪里常見(jiàn)的OS錯(cuò)誤 ?
答:大類有Application Errors, Protection Errors, Kernel Errors三種,每種大類包含的具體ErrorCode可以參考1.1章節(jié)。
問(wèn)題2:如何進(jìn)行OS錯(cuò)誤處理?
答:通過(guò)Retention RAM來(lái)存儲(chǔ)OS錯(cuò)誤信息,通過(guò)OS給出的一系列API獲取Error發(fā)生時(shí)的上下文信息。
審核編輯:劉清
-
RAM
+關(guān)注
關(guān)注
8文章
1369瀏覽量
115025 -
SCR
+關(guān)注
關(guān)注
2文章
150瀏覽量
44313 -
AUTOSAR
+關(guān)注
關(guān)注
10文章
363瀏覽量
21783 -
SBC
+關(guān)注
關(guān)注
0文章
78瀏覽量
19259 -
易失性存儲(chǔ)器
+關(guān)注
關(guān)注
0文章
14瀏覽量
6739
原文標(biāo)題:AUTOSAR架構(gòu)下的OS錯(cuò)誤處理
文章出處:【微信號(hào):汽車電子嵌入式,微信公眾號(hào):汽車電子嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
嵌入式編程錯(cuò)誤處理機(jī)制設(shè)計(jì)
![嵌入式編程<b class='flag-5'>錯(cuò)誤處理</b>機(jī)制設(shè)計(jì)](https://file1.elecfans.com/web2/M00/82/5E/wKgZomRLKQCARag_AAB9eEmSo-A990.jpg)
嵌入式系統(tǒng)C語(yǔ)言編程中主要的錯(cuò)誤處理方式
![嵌入式系統(tǒng)C語(yǔ)言編程中主要的<b class='flag-5'>錯(cuò)誤處理</b>方式](https://file1.elecfans.com/web2/M00/8D/A2/wKgaomS-OTiAJjCzAAAYQuji3IY661.png)
Rust語(yǔ)言中錯(cuò)誤處理的機(jī)制
AUTOSAR架構(gòu)下的多核通信介紹
![<b class='flag-5'>AUTOSAR</b><b class='flag-5'>架構(gòu)</b><b class='flag-5'>下</b>的多核通信介紹](https://file1.elecfans.com/web2/M00/AD/DD/wKgaomVRez-AJrwlAAAPlJ4aV0w849.jpg)
labviEW錯(cuò)誤處理的問(wèn)題
LabVIEW錯(cuò)誤處理問(wèn)題
AF錯(cuò)誤處理
LabVIEW中的錯(cuò)誤處理
Spring Boot框架錯(cuò)誤處理
一文入門AUTOSAR OS
![一文入門<b class='flag-5'>AUTOSAR</b> <b class='flag-5'>OS</b>](https://file1.elecfans.com/web2/M00/8B/A8/wKgZomSc7o6AZicRAAApFlTl7YM679.png)
基于Tricore芯片的AUTOSAR架構(gòu)下的多核啟動(dòng)
![基于Tricore芯片的<b class='flag-5'>AUTOSAR</b><b class='flag-5'>架構(gòu)</b><b class='flag-5'>下</b>的多核啟動(dòng)](https://file1.elecfans.com/web2/M00/A9/CC/wKgaomU115iAPiLsAABH-HbqmZo299.png)
評(píng)論