我們討論了為嵌入式應用程序設置斷言通常需要的內容。我們還看到,根據(jù)所使用的工具鏈,它可能會略有不同。盡管存在這些較小的差異,但仍將斷言用于相同的目的:檢測開發(fā)人員對應用程序的假設何時在應用程序中的特定點不正確。
當適當使用時,斷言可以提高代碼質量。但是,存在一些關鍵情況,即斷言要么無效或可能引起意外問題。
在今天的帖子中,我們將研究主張可能失敗的地方以及為什么要失敗,我將分享一些在實時系統(tǒng)中安全實施斷言的實用技巧。
斷言會引起問題的地方
在您查看實時斷言之前,您需要了解主張可能使您失敗的地方。在三種情況下,您可能會發(fā)現(xiàn)標準斷言實現(xiàn)將使您失敗。
1。在系統(tǒng)初始化期間
當微控制器啟動時,它會執(zhí)行供應商供應的代碼,該代碼初始化系統(tǒng)時鐘,執(zhí)行內存設置并準備運行時環(huán)境。這似乎是斷言的邏輯場所,但事實并非如此。為什么:
· 振蕩器才剛剛啟動,外圍設備可能需要充分時鐘。
· 仍然需要映射諸如printf之類的函數(shù),因此即使斷言失敗,輸出也將無處可去。
· 如果您嘗試停止處理器或打印消息,則可能會觸發(fā)一個例外,以阻止系統(tǒng)啟動。
除非必要,否則避免在啟動代碼中斷言,并且僅使用直接I/O切換(例如LED )等低級機制進行診斷。
2。在微控制器驅動程序中
駕駛員是使用斷言的非常有用的地方,但是再次,我們需要小心我們使用哪些驅動程序??紤]一下我們通過啟動代碼獲得的情況。許多開發(fā)人員要做的第一件事是初始化GPIO引腳。我經常使用傳遞到gpio_init函數(shù)的配置表。例如,如果您有GPIO的配置表:
斷言(config!= null);
如果我有斷言檢查這種結構并且不正確的事物,我將發(fā)出斷言,但是該斷言的結果將無處可尋! GPIO引腳不僅沒有初始化,而且尚未映射printf和關聯(lián)的輸出。在這一點上,我將得到一個默默失敗的斷言。
沉默的斷言不一定是一件壞事。我們仍然獲得失敗的斷言的行號和有關原因的信息。問題是,我們沒有意識到,主張已經發(fā)射了,并且在我們的系統(tǒng)中看起來很混亂,以了解為什么它不運行。
正如我們上次討論的那樣,我們可以設置自動斷點或使用匯編指令使我們顯而易見。我最喜歡的技巧之一是將LED作為主張LED獻上,該主張在斷言開火時會鎖定。我們將很快談論更多。
3。實時硬件組件
這是可能變得危險的地方。想象一個嵌入式系統(tǒng)驅動電動機。如果斷言發(fā)射并停止電動機:
· 重載有效載荷可能會突然讓位,并造成身體傷害。
· 渦輪機,火箭發(fā)動機或其他實時機制可能會災難性地失效。
在這一點上,斷言不僅會導致軟件錯誤,還會損害安全性。在這些情況下,停止系統(tǒng)不是一個選擇。
我們不能允許這些類型的情況發(fā)生。對于可能處于實時或生產操作中間的系統(tǒng),我們的斷言需要具備更多的技巧,而不僅僅是停止執(zhí)行我們的代碼。斷言需要能夠記錄他們可以的任何數(shù)據(jù),然后通知應用程序代碼出現(xiàn)問題。然后,應用程序可以決定是否應安全地關閉系統(tǒng),或終止該系統(tǒng),或者該應用程序是否應繼續(xù)進行(甚至可能嘗試恢復)?,F(xiàn)在,讓我們看一下如何實施主張,以便可以在實時系統(tǒng)中使用它們的提示。
實時斷言的提示
實時斷言是旨在驗證具有實時限制的系統(tǒng)執(zhí)行過程中開發(fā)人員假設的程序檢查。與傳統(tǒng)的斷言在失敗時停止系統(tǒng),實時斷言對關鍵診斷信息進行記錄,向應用程序或開發(fā)人員發(fā)出信號,并允許系統(tǒng)執(zhí)行或過渡到安全狀態(tài),而不會破壞關鍵的實時操作。
以下是在使用實時斷言時需要考慮的一些技巧:
提示#1 - 使用視覺輔助
在不停止CPU的情況下通知開發(fā)人員失敗斷言的最簡單方法是使用視覺指示器。對于大多數(shù)系統(tǒng),這意味著要切換LED:
void __aeabi_assert(const char *expr,const char *file,int line){
//使用LED
dio_channelwrite信號故障(assert_led,low);
而(1); //停止執(zhí)行
}
LED閂鎖表明發(fā)生了斷言,終端上的消息告訴您確切的發(fā)生在哪里。
提示#2 - 創(chuàng)建斷言日志
正如我們在這些博客中所看到的那樣,斷言通常會停止CPU,但是如果我們有電動機旋轉或其他原因,為什么我們不想停止執(zhí)行代碼,我們可以改為將終端信息重定向到日志。日志可以用于開發(fā)中,但它們也是記錄沒有與之連接的終端的生產系統(tǒng)中的斷言信息的最佳方法之一。
我們可以將幾個不同的位置重定向到主張日志。我們應該考慮的第一個位置,無論將主張數(shù)據(jù)記錄到RAM是什么。我通常會使用一個可以容納最大長度的字符串然后將信息寫入緩沖區(qū)的圓形緩沖區(qū)。我通常會包含文件,行號,然后包括我認為可能很重要的任何其他信息。有時,我什至會修改斷言失敗的功能,以獲取一個自定義字符串,該字符串可以在發(fā)出斷言之前立即提供有關條件的更多信息。我們可能會記錄執(zhí)行以下操作的數(shù)據(jù):
void __aeabi_assert(const char *expr,const char *file,int line){
#if assert_uart == true
uart_printf(uart1,“ ostertion ostertion in lin s in line s in line%d \ n”,file,line);
#elif
log_append(assert,assert_string,file,line);
#endif
//視覺指示器
dio_channelwrite(assert_led,low);
}
圓形緩沖區(qū)可以在RAM中暫時固定斷言日志。然后,背景任務可以將這些日志沖洗到非易失性內存(例如,閃存或SD卡)。
提示#3 - 通知應用程序
主張并非被設計為故障處理程序,而是實時斷言不能僅僅阻止嵌入式系統(tǒng)。我們可能仍然想停止系統(tǒng),但是要這樣做,我們需要讓主應用程序知道已經檢測到缺陷,并且我們需要盡快進入安全模式。我們可以通過在主張庫和主要應用程序之間創(chuàng)建信號機制來做到這一點。
例如,我們可能會認為我們的實時系統(tǒng)中有三種不同類型的斷言:
1. 關鍵主張要求系統(tǒng)立即進入安全狀態(tài)。
2. 中等主張不需要系統(tǒng)停止,但是開發(fā)人員立即通知存在問題,以便開發(fā)人員可以決定如何進行。
3. 次要斷言不需要停止系統(tǒng),甚至可能不需要通知申請。
我們可能會將這些斷言的嚴重性水平添加到一個枚舉中,然后我們可以在代碼中使用。例如,枚舉可能是:
typedef enum
{
assert_severity_minor,
assert_severity_moderate,
assert_severity_critical,
assert_severity_max_count
} assertseertseverity_t
然后,我們斷言失敗的功能可能會成為完全自定義的實現(xiàn),不是來自C庫斷言。H模塊,而是來自myAssert.h或某種效果。一個示例可能看起來像以下內容:
void assert_failed(const char expr,const char *file,int line,assertSeverity_t嚴重性)
{
#if assert_uart == true
uart_printf(uart1,“斷言在line s in line s in line%d \ n”中失敗,file,file,line);
#elif
log_append(assert,assert_string,file,line);
#endif
#將I/O線拉低以打開LED并發(fā)出斷言。
dio_channelwrite(LED_ASSERT,低);
app_notify(嚴重性);
}
此示例只是將調用添加到app_notify,然后通過嚴重性,但是這種簡單性非常強大。 app_notify將使應用程序知道已經檢測到缺陷,然后可以決定該系統(tǒng)應放入哪種狀態(tài)。
提示#4 - 有條件配置斷言
斷言是檢測缺陷的簡單機制,但是開發(fā)人員可以在確定適合其應用的情況下以復雜的機制創(chuàng)建。如果您打算在開發(fā)和生產中使用斷言,則創(chuàng)建一系列條件來確定您的斷言的運作方式可能很有用。例如,您可能會創(chuàng)建允許輸出映射到的條件:
· uart
· 調試控制臺
· 日志
也可以有一些條件可以完全禁用斷言功能或將收集并提供給日志的信息。開發(fā)人員在開發(fā)過程中可能會有不同的功能,而他們在生產中想要的功能可能會有不同的功能。重要的是要從主張能力中獲得什么來思考,并設計最簡單的功能。您做的越復雜,出現(xiàn)問題的機會就越大。
采取您的下一步
斷言是捕獲錯誤的強大工具,但是在實時系統(tǒng)中,濫用它們可能會引起嚴重的問題。安全地使用斷言:
1. 避免將主張放在啟動代碼中。
2. 使用視覺指示燈(例如LED)向早期失敗發(fā)出信號。
3. log未能用于診斷或非易失性內存。
4. 通知申請,以便可以適當處理失敗。
5. 有條件地為開發(fā)與生產構建配置斷言。
通過這些提示,您可以實現(xiàn)實時斷言,以幫助您檢測缺陷,而不會損害系統(tǒng)的安全性或穩(wěn)定性。