RTOS诊断和错误检查
RTOS診斷和錯誤檢查
RTOS diagnostics and error checking
查看RTOS顯示系列
錯誤處理不太可能是任何用于嵌入式系統應用程序的操作系統的主要功能。這是資源限制的必然結果,而且所有嵌入式系統都有某種限制。這也是合乎邏輯的,因為只有有限數量的嵌入式系統才有機會像桌面系統一樣工作,即為用戶提供一個機會,以便在發生異常事件時決定下一步要做什么。
在Nucleus SE中,大致有三種類型的錯誤檢查:
對所選配置進行“健全性檢查”的功能-只是為了確保所選選項的一致性
可選地包含用于檢查運行時行為的代碼
有助于設計更健壯代碼的特定API函數
這些都將在本文中討論,并提供一些關于用戶實現診斷的想法。
配置檢查
Nucleus SE的設計非常便于用戶配置,因此可以對其進行定制,以充分利用可用資源。這種可配置性是一個挑戰,因為選項的數量以及它們之間的相互依賴性非常大。正如前面的許多文章中所描述的,Nucleus SE的大多數用戶配置都是通過在nuse_config.h文件中設置#define常量來執行的。
為了幫助識別配置錯誤,包含了一個文件–nuse_config_check.h–即通過一個#include into nuse_config.c),該文件對#define符號執行多項一致性檢查。以下是此文件的摘錄:
/*** Tasks and task control ***/
#if NUSE_TASK_NUMBER < 1 || NUSE_TASK_NUMBER > 16
#error NUSE: invalid number of tasks – must be 1-16
#endif
#if NUSE_TASK_RELINQUISH && (NUSE_SCHEDULER_TYPE ==
NUSE_PRIORITY_SCHEDULER)
#error NUSE: NUSE_Task_Relinquish() selected – not valid with
priority scheduler
#endif
#if NUSE_TASK_RESUME && !NUSE_SUSPEND_ENABLE
#error NUSE: NUSE_Task_Resume() selected – task
suspend not
enabled
#endif
#if NUSE_TASK_SUSPEND && !NUSE_SUSPEND_ENABLE
#error NUSE: NUSE_Task_Suspend() selected – task
suspend not
enabled
#endif
#if NUSE_INITIAL_TASK_STATE_SUPPORT && !NUSE_SUSPEND_ENABLE
#error NUSE: Initial task state enabled – task suspend not
enabled
#endif
/*** Partition pools ***/
#if NUSE_PARTITION_POOL_NUMBER > 16
#error NUSE: invalid number of partition pools – must be 0-16
#endif
#if NUSE_PARTITION_POOL_NUMBER == 0
#if NUSE_PARTITION_ALLOCATE#error NUSE: NUSE_Partition_Allocate()
enabled – no
partition pools configured#endif#if NUSE_PARTITION_DEALLOCATE#error NUSE:
NUSE_Partition_Deallocate() enabled – no
partition pools configured
#endif#if NUSE_PARTITION_POOL_INFORMATION#error NUSE:
NUSE_Partition_Pool_Information() enabled –
no partition pools configured
#endif
#endif
執行的檢查包括:
驗證是否至少配置了一個但不超過16個任務
確認所選API函數與所選調度程序或其他選項不一致
驗證是否指定了不超過16個其他內核對象的實例
確認沒有為根本沒有實例化的對象選擇API函數
確保在未啟用信號和系統時間的API函數時未選擇這些功能
驗證選定的計劃程序類型和相關選項
在所有情況下,檢測到錯誤都會導致編譯錯誤語句。這通常會導致編譯被指定的消息終止。
此文件不會使創建不合邏輯的配置成為不可能,但會使其變得極不可能。
API參數檢查
與Nucleus RTOS一樣,Nucleus SE還可以選擇包含代碼,以便在運行時驗證API函數調用參數。通常這只會在最初的調試和測試中使用,因為在生產代碼中內存和運行時開銷是不需要的。
通過將NUSE_config.h中的NUSE_API_Parameter_checking設置為TRUE來啟用參數檢查。這樣就可以編譯所需的附加代碼。下面是一個API函數的參數檢查示例:
STATUS NUSE_Mailbox_Send(NUSE_MAILBOX
mailbox, ADDR *message, suspend)
{
STATUS return_value;#if NUSE_API_PARAMETER_CHECKINGif (mailbox >= NUSE_MAILBOX_NUMBER){
return NUSE_INVALID_MAILBOX;
}if (message == NULL){
return NUSE_INVALID_POINTER;
}#if NUSE_BLOCKING_ENABLEif ((suspend
!= NUSE_NO_SUSPEND) &&
(suspend != NUSE_SUSPEND))
{return NUSE_INVALID_SUSPEND;}#else
if (suspend != NUSE_NO_SUSPEND)
{
return NUSE_INVALID_SUSPEND;
}#endif#endif
此參數檢查可能導致從API函數調用返回錯誤代碼。這些都是NUSE_INVALID_xxx形式的負值(例如NUSE_INVALID_POINTER)–NUSE_codes.h中包含一整套定義。
可以包含額外的應用程序代碼(可能是有條件地編譯)來處理這些錯誤值,但是最好使用現代嵌入式調試器的數據監視工具來檢測它們。
參數檢查會導致內存開銷(額外的代碼)和運行時性能,因此它的使用有一定的侵入性。由于開發人員可以使用Nucleus SE的完整源代碼,如果需要絕對精度,則可以在生產代碼上“手動”進行檢查和調試。
任務堆棧檢查
只要Run-to-Completion調度器不在使用,Nucleus SE就有一個可用的任務堆棧檢查工具,它與Nucleus RTOS中提供的類似,并提供剩余堆棧空間的指示。這個API調用–NUSE_Task_Check_Stack()–在上一篇文章中有詳細描述。本文后面的“用戶診斷”部分將討論堆棧錯誤檢查的一些想法。
版本信息
Nucleus RTOS和Nucleus SE有一個API函數,它只返回關于內核的版本/版本信息。
Nucleus
RTOS API Call
Service call prototype:
CHAR *NU_Release_Information(VOID);
Parameters:
None
Returns:
Pointer to NULL-terminated version string
Nucleus
SE API Call
This API call supports the key functionality of the Nucleus RTOS
API.
Service call prototype:
char *NUSE_Release_Information(void);
Parameters:
None
Returns:
Pointer to NULL-terminated version string
發布信息的Nucleus SE實現
這個API調用的實現幾乎是微不足道的。返回一個指向字符串常量NUSE_Release_Info的指針,該常量在NUSE_globals.c中聲明并初始化。
該字符串的形式為Nucleus SE–Xyymmdd,其中:
X是釋放狀態:A=α;B=β;R=釋放
yy是發布的年份
mm是釋放月份
dd是釋放日
與Nucleus RTOS的兼容性
Nucleus RTOS包括一個用于維護歷史日志的可選工具。內核記錄各種系統活動的細節。提供API函數使應用程序能夠:
啟用/禁用歷史保存
做歷史記錄
檢索歷史記錄條目
Nucleus SE不支持此功能。
Nucleus RTOS還包括一些錯誤管理宏,這些宏執行斷言,并提供一種調用用戶定義致命錯誤函數的方法。這些是有條件地包含在OS構建中的。Nucleus SE不支持此類設施。
用戶診斷
到目前為止,在本文中,我們已經了解了Nucleus SE本身提供的診斷和錯誤檢查工具。現在是一個很好的機會來考慮如何使用內核提供的工具和/或應用我們對其內部結構和實現的知識來實現用戶定義或面向應用程序的診斷。
特定于應用程序的診斷
幾乎任何應用程序都可以添加額外的代碼來在運行時檢查其自身的完整性。使用多任務內核,讓一個特定的任務來完成這項工作是非常方便和直接的。顯然,對于應用程序非常特殊的診斷不在本系列文章的范圍內,但是我們可以考慮一些廣泛的想法。
內存檢查
內存的正確操作顯然對任何基于處理器的系統的完整性至關重要。同樣明顯的是,災難性的故障會阻止任何軟件的運行,更不用說診斷了。但是有些情況下會發生一定程度的失敗,這是一個主要的問題,但并不能完全阻止代碼的執行。測試內存是一個相當復雜的主題,這遠遠超出了本文的范圍,所以我只能給出一些一般性的想法。
在RAM中,最常見的兩種故障是:“卡住的位”—一個位的值為零或一,無法更改;另一個是“串擾”,相鄰的位相互干擾。它們都可以通過依次向每個RAM位置寫入和讀回適當的測試模式來進行測試。有些測試實際上只能在啟動時執行,甚至在建立堆棧之前;例如,“移動1”測試,即內存中的每個位都設置為1,并且每隔一位進行檢查以確保其為零。其他逐字節模式測試可以動態執行,只要確保在RAM位置損壞時不會發生上下文切換。使用Nucleus SE critical部分來定義NUSE_CS_Enter()和NUSE_CS_Exit()宏,這兩個宏是在NUSE_types.h中定義的,使用這些宏是直接和可移植的。
各種類型的ROM也會偶爾出現故障,但軟件所能做的檢查是有限的。生成代碼時生成的校驗和將很有用。這可以在啟動時檢查,也可以在運行時檢查。
內存尋址邏輯故障會影響ROM和RAM。可以設計一個專門針對這一點的測試,但它最有可能出現在上述其他測試中。
外圍設備檢查
在CPU之外,外圍電路可能會出現故障。當然,這將有很大的不同,從一個系統到另一個,但這是非常常見的設備有一些手段來驗證其完整性與診斷軟件。例如,一條通信線路可能具有回送模式,由此寫入的任何數據都會立即返回。
看門狗服務
嵌入式系統設計者通常包括一個“看門狗”電路。這是一種外圍設備,它可以中斷CPU并期望得到迅速的響應,或者(更好)需要由軟件啟動的周期性訪問。在這兩種情況下,看門狗“咬人”的常見結果是系統重置。
在多任務環境中有效地使用看門狗是一項挑戰。只需從一個任務中對其進行維護,就可以確認此特定任務正在運行。解決這一問題的一種方法是實現一個“主管任務”—本文后面將介紹這方面的一個示例。
堆棧溢出檢查
除非您選擇Run to Completion scheduler,否則Nucleus SE應用程序將為每個任務包含一個堆棧。這些堆棧的完整性是至關重要的,但是RAM可能是有限的,因此獲得最佳大小是至關重要的。靜態地預測每個任務的堆棧需求是可能的,但非常困難,它需要有足夠的容量來滿足最嵌套的函數調用和最需要堆棧的中斷服務例程的需求。一種更簡單的方法是執行詳盡的運行時測試。
堆棧驗證大致有兩種方法。如果使用了一個復雜的嵌入式軟件調試器,則可以監視堆棧邊界,并檢測到任何越界行為。Nucleus SE堆棧的位置和大小可以通過ROM中的全局數據結構輕松訪問:NUSE_Task_Stack_Base[]和NUSE_Task_Stack_size[]。
另一種方法是執行運行時測試。通常的方法是在每個堆棧的末尾添加“保護字”–通常這些是每個堆棧數據區域中的第一個位置。這些字被初始化為可識別的非零值。然后,診斷例行程序/任務檢查它們是否已更改并采取適當的措施。保護字的過度寫入并不意味著堆棧實際上已經溢出,而是表示堆棧即將溢出;因此,軟件可能會繼續執行足夠長的時間來采取糾正措施或警告用戶。
監督任務
盡管Nucleus SE不保留16個任務中的任何一個供自己使用,但是用戶可以選擇將一個任務專用于診斷。這可能是一個低優先級的任務,它只利用任何“空閑”的CPU時間;也可能是一個高優先級的任務,偶爾會運行很短的時間,從而確保總是定期執行診斷。
下面是一個示例的功能:
主管任務的信號標志用于監視系統中六個關鍵任務的運行。這些任務都使用一個特定的標志(位0到位5),并且需要定期設置它。主管任務清除所有標志,然后將自身掛起一段時間。當它恢復時,它希望通過設置適當的標志來“簽入”所有六個任務;它尋找與值b00111111(來自nuse_binary.h)的完全匹配。如果滿足此條件,它將清除標志并再次掛起。如果沒有,它將調用關鍵錯誤處理例程,例如,該例程可能執行系統重置。
另一種實現可能使用了事件標志組。如果在應用程序的其他地方沒有使用信號(因為所有任務都會產生RAM開銷),如果將事件標志用于其他目的,則更是如此。
跟蹤和分析
盡管許多現代嵌入式軟件調試器都是可定制的,并且可以使其具有“實時操作系統意識”,但調試多線程應用程序仍然具有挑戰性。一種廣泛使用的方法是執行后分析(post-execution profiling),其中(RTOS)代碼被檢測,以便對其操作的詳細審計進行回顧性分析。通常,實施此類設施涉及兩個部分:
附加代碼被添加到RTOS(即,它被“檢測”)以記錄活動。通常,這將被包含在預處理器指令中,以便于條件編譯。當發生重要事件(如API調用或上下文切換)時,此代碼將存儲一些字節的信息。這些信息應該是:
–當前地址(PC)。
–當前任務ID(索引)。
任何其他相關對象的索引。
–指示所執行操作的代碼。
專門用于將配置文件信息的緩沖區清空到外部存儲器(通常是主機)的任務。
分析這些捕獲的數據也需要一些工作,但這可能與使用Excel電子表格一樣簡單。
總結
以上是生活随笔為你收集整理的RTOS诊断和错误检查的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nucleus SE RTOS初始化和启
- 下一篇: Nucleus-SE迁移:未实现的设施和