|
我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師
9 T! s ^6 X3 T) L) {% I8 L; i4 E1 I關(guān)注我,一起變得更加優(yōu)秀!7 V4 M. M; e+ U' o8 y1 ~
在嵌入式開發(fā)軟件中查找和消除潛在的錯(cuò)誤是一項(xiàng)較為艱巨的任務(wù),通常需要比較復(fù)雜的調(diào)試工具,才能從觀察到的錯(cuò)誤現(xiàn)象,追溯到錯(cuò)誤發(fā)生的根本原因。
! H1 g: J/ p* }) S" L3 l在某些情況下,系統(tǒng)看起來仍然可以正常運(yùn)行,或至少在一段時(shí)間內(nèi)似乎仍能正常工作,潛在的錯(cuò)誤原因如果不處理,可能會破壞系統(tǒng)數(shù)據(jù)或者內(nèi)部的代碼鏡像。) o; A7 T% k' j5 s2 |% H
工程師常常不主動發(fā)現(xiàn)一些罕見的異常,這些異常在實(shí)驗(yàn)室中不易復(fù)現(xiàn),一般將其視為用戶錯(cuò)誤或“小故障”,然而,機(jī)器中的這些“鬼魂”仍然存在。這是難以重現(xiàn)錯(cuò)誤最常見的根本原因。
! V" [. m. l6 t" V8 H每當(dāng)您閱讀固件源代碼時(shí),請注意以下兩點(diǎn),并遵循最佳的建議和做法,以防止它們再次發(fā)生在您身上。
2 x. i( L1 I: }8 b# `注意事項(xiàng)1:競爭條件' W. F, M6 T/ B) x8 B' }# C
競爭條件是指兩個(gè)或多個(gè)執(zhí)行線程(可以是RTOS任務(wù)或main() 和中斷處理程序)的組合結(jié)果根據(jù)交織指令的精確順序而變化的任何情況,每個(gè)都在處理器上執(zhí)行。
0 b5 y: @$ H& ^/ u& [( l v5 r2 v- n例如,假設(shè)您有兩個(gè)執(zhí)行線程,其中一個(gè)規(guī)則地遞增一個(gè)全局變量(g_counter + = 1; ),而另一個(gè)偶然將其歸零(g_counter = 0; ),如果不能始終以原子方式(即,在單個(gè)指令周期內(nèi))執(zhí)行增量,則存在競爭條件。 N! P6 }1 e" ?$ \; Q; u, K
如圖1所示,將任務(wù)視為汽車接近同一十字路口,計(jì)數(shù)器變量的兩次更新之間的沖突可能永遠(yuǎn)不會發(fā)生,或者很少會發(fā)生,但是,這樣做的時(shí)候,計(jì)數(shù)器實(shí)際上不會在內(nèi)存中清零。其值至少在下一個(gè)清零之前是損壞的。; ~7 p( \4 }: \
這種影響可能會對系統(tǒng)造成嚴(yán)重后果,盡管可能要等到實(shí)際碰撞后很長一段時(shí)間才會出現(xiàn)。
" X1 K( @3 k: y9 G' [( l8 o
fspfposm3ds640718605.png (103.23 KB, 下載次數(shù): 4)
下載附件
保存到相冊
fspfposm3ds640718605.png
前天 23:19 上傳
1 a1 P! X7 ?3 N. @; [3 ^最佳實(shí)踐:可以通過適當(dāng)?shù)膿屜认拗菩袨,原子地?zhí)行代碼的關(guān)鍵部分,來避免競爭條件。為防止涉及ISR的爭用情況,必須在另一個(gè)代碼的關(guān)鍵部分持續(xù)時(shí)間內(nèi)至少禁止一個(gè)中斷信號。, n/ K) ^+ b+ O8 E
對于RTOS任務(wù)之間的爭用,最佳實(shí)踐是創(chuàng)建特定于該共享庫的互斥體,每個(gè)互斥體在進(jìn)入關(guān)鍵部分之前必須獲取該互斥體,請注意,依靠特定CPU的功能來確保原子性不是一個(gè)好主意,
" s& k- N M4 @/ d \共享數(shù)據(jù)和搶占的隨機(jī)時(shí)間是造成競爭狀況的元兇,但是錯(cuò)誤可能并不總是會發(fā)生,這使得從觀察到的癥狀到根本原因的種族狀況跟蹤變得異常困難。
9 v2 W! m+ {& {( q8 N9 |. j$ c! [因此,保持警惕以保護(hù)所有共享對象非常重要。每個(gè)共享對象都是一個(gè)等待發(fā)生的事故。
# S; U: ~0 N/ q( Z+ I最佳實(shí)踐:命名所有潛在共享的對象(包括全局變量,堆對象或外圍寄存器和指向該對象的指針),以使競爭風(fēng)險(xiǎn)對于所有的代碼閱讀者而言都是顯而易見的,在Netrino嵌入式C編碼標(biāo)準(zhǔn)提倡使用 “g_xxx” 前綴。查找所有可能共享的對象將是爭用條件代碼審核的第一步。6 ]6 Z% n+ n, q1 a
注意事項(xiàng)2:不可重入功能4 g+ l; d |: t; J' r
從技術(shù)上講,不可重入功能的問題是爭用狀況問題的特例,而且由于相關(guān)原因,由不可重入函數(shù)引起的運(yùn)行時(shí)錯(cuò)誤通常不會以可重現(xiàn)的方式發(fā)生-使它們同樣難以調(diào)試。: w. |& M g L8 U @3 |1 \( T
不幸的是,非重入功能也比其他類型的競爭條件更難在代碼審查中發(fā)現(xiàn),圖2 顯示了一個(gè)典型的場景,在這里,要搶占的軟件實(shí)體也是RTOS任務(wù),但是,它們不是通過直接調(diào)用共享對象而是通過函數(shù)調(diào)用間接操作。
9 g, O. w% @6 C9 N" c2 K
jk1ku4yfece640718705.png (87.46 KB, 下載次數(shù): 4)
下載附件
保存到相冊
jk1ku4yfece640718705.png
前天 23:19 上傳
: J: D( X3 \( d例如,假設(shè)任務(wù)A調(diào)用套接字層協(xié)議功能,該套接字功能調(diào)用TCP層協(xié)議功能,調(diào)用IP層協(xié)議功能,該功能調(diào)用以太網(wǎng)驅(qū)動程序,為了使系統(tǒng)可靠地運(yùn)行,所有這些功能都必須是可重入的。
5 N9 g# R/ r- X+ b0 H8 }但是,以太網(wǎng)驅(qū)動程序的所有功能都以以太網(wǎng)控制器芯片的寄存器形式操作相同的全局對象。如果在這些寄存器操作期間允許搶占,則任務(wù)B可以在將數(shù)據(jù)包A排隊(duì)之后但在發(fā)送開始之前搶占任務(wù)A。
. v4 p( P( s8 q( q; G然后,任務(wù)B調(diào)用套接字層功能,該套接字層功能調(diào)用TCP層功能,再調(diào)用IP層功能,該功能調(diào)用以太網(wǎng)驅(qū)動程序,該隊(duì)列將數(shù)據(jù)包B排隊(duì)并傳輸。
; \. b; \. S. B( X當(dāng)CPU的控制權(quán)返回到任務(wù)A時(shí),它將請求傳輸。根據(jù)以太網(wǎng)控制器芯片的設(shè)計(jì),這可能會重傳數(shù)據(jù)包B或產(chǎn)生錯(cuò)誤。數(shù)據(jù)包A丟失,并且不會發(fā)送到網(wǎng)絡(luò)上。
+ K# s5 l/ n* }+ K為了可以同時(shí)從多個(gè)RTOS任務(wù)中調(diào)用此以太網(wǎng)驅(qū)動程序的功能,必須使它們可重入。如果它們每個(gè)僅使用堆棧變量,則無事可做。5 L; L1 J7 N! \, X% W0 e' @
因此,C 語言函數(shù)最常見的樣式是可重入的,但是除非經(jīng)過精心設(shè)計(jì),否則驅(qū)動程序和某些其他功能將是不可重入的,4 |) u6 b+ y3 i9 k7 u
使函數(shù)可重入的關(guān)鍵是暫停對外圍設(shè)備寄存器,包括靜態(tài)局部變量,持久堆對象和共享內(nèi)存區(qū)域在內(nèi)的全局變量的所有訪問的搶占。
) r7 h Z6 ?$ M/ u& F這可以通過禁用一個(gè)或多個(gè)中斷或獲取并釋放互斥鎖來完成。問題的細(xì)節(jié)決定了最佳解決方案。
/ a2 d6 x4 [! d" m最佳實(shí)踐:在每個(gè)庫或驅(qū)動程序模塊中創(chuàng)建和隱藏一個(gè)互斥量,這些互斥量不是本質(zhì)上可重入的。使獲取此互斥鎖成為操作整個(gè)模塊中使用的任何持久數(shù)據(jù)或共享寄存器的前提。2 B2 @* v" D9 y' m) J
例如,相同的互斥鎖可用于防止涉及以太網(wǎng)控制器寄存器和全局或靜態(tài)本地?cái)?shù)據(jù)包計(jì)數(shù)器的競爭情況,在訪問這些數(shù)據(jù)之前,模塊中訪問此數(shù)據(jù)的所有功能必須遵循協(xié)議以獲取互斥量。
# s! h$ z5 a9 }: }( W! \/ d& S% y注意非重入功能可能會作為第三方中間件,舊版代碼或設(shè)備驅(qū)動程序的一部分進(jìn)入您的代碼庫,令人不安的是,不可重入函數(shù)甚至可能是編譯器隨附的標(biāo)準(zhǔn)C或C ++庫的一部分。3 X# V' c4 G; E( ]3 X% E8 S
如果您使用GNU編譯器來構(gòu)建基于RTOS的應(yīng)用程序,請注意您應(yīng)該使用可重入的“ newlib”標(biāo)準(zhǔn)C庫,而不是默認(rèn)庫。
" j9 E9 n6 G0 C6 y( r0 F' t原文:https://blog.csdn.net/weixin_44059661/article/details/107839764, G6 ?; e, ~$ I* t: M
j3sivagut1v640718806.png (665.93 KB, 下載次數(shù): 3)
下載附件
保存到相冊
j3sivagut1v640718806.png
前天 23:19 上傳
" v p! E4 g- q2 b; f9 \; }0 N9 M, w7 S; q1 N
* }+ j& I% d! t' o( i4 U5 g. a-END-4 H/ i- t' ^+ {
往期推薦:點(diǎn)擊圖片即可跳轉(zhuǎn)閱讀
6 \3 S; G# i& j+ _* f6 B7 n' @! i8 u3 q/ s
, g4 i# T* j1 W. G
; P. i! k O4 J0 ]& N$ C# X0 k7 f8 r# Q
" `& a" K6 i; p" j 8 K# B+ W8 L8 H" @% X, b2 \
givoffjdvuc640718906.jpg (226.88 KB, 下載次數(shù): 5)
下載附件
保存到相冊
givoffjdvuc640718906.jpg
前天 23:19 上傳
7 a5 I3 ^1 S# `6 a
$ Y. x: _) V1 e) E& |: F 讓嵌入式工程師,回歸創(chuàng)造力!& _6 N' ]( Z; @0 d
1 ^. o) S% M, L
+ k) S& D% K) ~0 R/ W
, U; W2 p* X% W& G5 J5 W
5 C; o5 d, d3 N0 N1 E . `# P* k0 W8 V# I# s+ v
0 D/ m7 p' D& s. q+ e
; Q( h% u4 k, R9 b
6 @8 Q6 F$ @4 r: e
$ F! j/ J4 K; m4 Y* ~ # s( S8 c* o5 b" m. @1 N; L
xrbw1gulolg640719006.jpg (115.39 KB, 下載次數(shù): 5)
下載附件
保存到相冊
xrbw1gulolg640719006.jpg
前天 23:19 上傳
4 L3 _8 U/ f" V$ Y) x ! ]. Z& ~( X! g4 v
嵌入式軟件使用狀態(tài)機(jī)架構(gòu),一般有什么優(yōu)點(diǎn)?3 c/ F; P4 K, ~7 p7 q( ^& ~1 T
& l- u1 T- Y0 _% m0 v
; z# y. D) c* k6 F
5 C0 o6 X' ]/ B, d3 t; J
1 g" ?* X9 ?# i u0 K! d0 q D8 l7 q2 P; n) C6 r4 S& N8 T
" y) p$ n/ K! j$ F
! B3 h+ T i! M1 r
! `% u) u7 F' k# T& J, r
$ `/ d& e2 Y9 ~; _1 ?$ B K + e) F5 P: G% @& c$ V, y
tpkip3niupv640719106.jpg (109.8 KB, 下載次數(shù): 5)
下載附件
保存到相冊
tpkip3niupv640719106.jpg
前天 23:19 上傳
{1 f m# ~3 l' C. P$ l* }( A0 h 9 L4 i" H5 }$ K- w B( r* V
嵌入式編程,一些常見的計(jì)算機(jī)術(shù)語。) J: X: u" ~1 [! o2 ~
, B, L+ M' O# q9 Q6 \, c
/ B- d, o+ b+ p ! V+ w9 W' F" \ C" _
& K& j: V% f4 f; } 2 E( c' \% _# e% g. {' `; T' a; {, h5 P& ~
我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師5 z9 {* H# M2 D0 u) F
關(guān)注我,一起變得更加優(yōu)秀! |
|