電子產(chǎn)業(yè)一站式賦能平臺(tái)

PCB聯(lián)盟網(wǎng)

搜索
查看: 30|回復(fù): 0
收起左側(cè)

嵌入式軟件設(shè)計(jì),注意這兩點(diǎn),可以降低bug出現(xiàn)的概率。

[復(fù)制鏈接]

485

主題

485

帖子

1623

積分

三級(jí)會(huì)員

Rank: 3Rank: 3

積分
1623
跳轉(zhuǎn)到指定樓層
樓主
我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師% y# F$ Q+ u, i9 M7 C
關(guān)注我,一起變得更加優(yōu)秀!
, ~4 w* S& T: x在嵌入式開發(fā)軟件中查找和消除潛在的錯(cuò)誤是一項(xiàng)較為艱巨的任務(wù),通常需要比較復(fù)雜的調(diào)試工具,才能從觀察到的錯(cuò)誤現(xiàn)象,追溯到錯(cuò)誤發(fā)生的根本原因。1 |: J, G" z; G2 p0 w
在某些情況下,系統(tǒng)看起來仍然可以正常運(yùn)行,或至少在一段時(shí)間內(nèi)似乎仍能正常工作,潛在的錯(cuò)誤原因如果不處理,可能會(huì)破壞系統(tǒng)數(shù)據(jù)或者內(nèi)部的代碼鏡像。( S" [8 Q  E0 L. t; G4 h% w
工程師常常不主動(dòng)發(fā)現(xiàn)一些罕見的異常,這些異常在實(shí)驗(yàn)室中不易復(fù)現(xiàn),一般將其視為用戶錯(cuò)誤或“小故障”,然而,機(jī)器中的這些“鬼魂”仍然存在。這是難以重現(xiàn)錯(cuò)誤最常見的根本原因。
( v. ~8 F* c. G, [' _, W4 b每當(dāng)您閱讀固件源代碼時(shí),請(qǐng)注意以下兩點(diǎn),并遵循最佳的建議和做法,以防止它們?cè)俅伟l(fā)生在您身上。9 P1 Z9 P7 V& d6 Y
注意事項(xiàng)1:競(jìng)爭(zhēng)條件
0 T" i( ~+ s! }2 _) L0 ]競(jìng)爭(zhēng)條件是指兩個(gè)或多個(gè)執(zhí)行線程(可以是RTOS任務(wù)或main() 和中斷處理程序)的組合結(jié)果根據(jù)交織指令的精確順序而變化的任何情況,每個(gè)都在處理器上執(zhí)行。( r$ v9 r4 V/ w* o
例如,假設(shè)您有兩個(gè)執(zhí)行線程,其中一個(gè)規(guī)則地遞增一個(gè)全局變量(g_counter + = 1; ),而另一個(gè)偶然將其歸零(g_counter = 0; ),如果不能始終以原子方式(即,在單個(gè)指令周期內(nèi))執(zhí)行增量,則存在競(jìng)爭(zhēng)條件。
$ }' Q; Y) ^/ p( O如圖1所示,將任務(wù)視為汽車接近同一十字路口,計(jì)數(shù)器變量的兩次更新之間的沖突可能永遠(yuǎn)不會(huì)發(fā)生,或者很少會(huì)發(fā)生,但是,這樣做的時(shí)候,計(jì)數(shù)器實(shí)際上不會(huì)在內(nèi)存中清零。其值至少在下一個(gè)清零之前是損壞的。9 O& |3 m3 w+ H6 C' y2 e
這種影響可能會(huì)對(duì)系統(tǒng)造成嚴(yán)重后果,盡管可能要等到實(shí)際碰撞后很長(zhǎng)一段時(shí)間才會(huì)出現(xiàn)。
, u1 d5 R! l- N, L4 U1 S# T ; c' N# `; g, j' O2 N
最佳實(shí)踐:可以通過適當(dāng)?shù)膿屜认拗菩袨椋拥貓?zhí)行代碼的關(guān)鍵部分,來避免競(jìng)爭(zhēng)條件。為防止涉及ISR的爭(zhēng)用情況,必須在另一個(gè)代碼的關(guān)鍵部分持續(xù)時(shí)間內(nèi)至少禁止一個(gè)中斷信號(hào)。4 c! N/ k+ H, ]. C4 G2 i
對(duì)于RTOS任務(wù)之間的爭(zhēng)用,最佳實(shí)踐是創(chuàng)建特定于該共享庫的互斥體,每個(gè)互斥體在進(jìn)入關(guān)鍵部分之前必須獲取該互斥體,請(qǐng)注意,依靠特定CPU的功能來確保原子性不是一個(gè)好主意,
- Y; a: ^, N$ [$ E共享數(shù)據(jù)和搶占的隨機(jī)時(shí)間是造成競(jìng)爭(zhēng)狀況的元兇,但是錯(cuò)誤可能并不總是會(huì)發(fā)生,這使得從觀察到的癥狀到根本原因的種族狀況跟蹤變得異常困難。3 o; B0 B) g# @% @" C8 A
因此,保持警惕以保護(hù)所有共享對(duì)象非常重要。每個(gè)共享對(duì)象都是一個(gè)等待發(fā)生的事故。
' V! M3 q6 W  d# [最佳實(shí)踐:命名所有潛在共享的對(duì)象(包括全局變量,堆對(duì)象或外圍寄存器和指向該對(duì)象的指針),以使競(jìng)爭(zhēng)風(fēng)險(xiǎn)對(duì)于所有的代碼閱讀者而言都是顯而易見的,在Netrino嵌入式C編碼標(biāo)準(zhǔn)提倡使用 “g_xxx” 前綴。查找所有可能共享的對(duì)象將是爭(zhēng)用條件代碼審核的第一步。
- l6 ^; b& Y4 d& K  \$ X注意事項(xiàng)2:不可重入功能; b" t. n/ R  M2 G9 ?3 j
從技術(shù)上講,不可重入功能的問題是爭(zhēng)用狀況問題的特例,而且由于相關(guān)原因,由不可重入函數(shù)引起的運(yùn)行時(shí)錯(cuò)誤通常不會(huì)以可重現(xiàn)的方式發(fā)生-使它們同樣難以調(diào)試。
/ e, e( W) V4 s2 q/ W0 f不幸的是,非重入功能也比其他類型的競(jìng)爭(zhēng)條件更難在代碼審查中發(fā)現(xiàn),圖2 顯示了一個(gè)典型的場(chǎng)景,在這里,要搶占的軟件實(shí)體也是RTOS任務(wù),但是,它們不是通過直接調(diào)用共享對(duì)象而是通過函數(shù)調(diào)用間接操作。
# x0 B, d! q; X# B4 R1 S& [ ; L: O2 P8 K. h5 v5 n
例如,假設(shè)任務(wù)A調(diào)用套接字層協(xié)議功能,該套接字功能調(diào)用TCP層協(xié)議功能,調(diào)用IP層協(xié)議功能,該功能調(diào)用以太網(wǎng)驅(qū)動(dòng)程序,為了使系統(tǒng)可靠地運(yùn)行,所有這些功能都必須是可重入的。" y  `% [% j$ L2 _
但是,以太網(wǎng)驅(qū)動(dòng)程序的所有功能都以以太網(wǎng)控制器芯片的寄存器形式操作相同的全局對(duì)象。如果在這些寄存器操作期間允許搶占,則任務(wù)B可以在將數(shù)據(jù)包A排隊(duì)之后但在發(fā)送開始之前搶占任務(wù)A。
, w6 K* G1 ]+ `; m然后,任務(wù)B調(diào)用套接字層功能,該套接字層功能調(diào)用TCP層功能,再調(diào)用IP層功能,該功能調(diào)用以太網(wǎng)驅(qū)動(dòng)程序,該隊(duì)列將數(shù)據(jù)包B排隊(duì)并傳輸。
' g- o$ O  g! @" m+ v當(dāng)CPU的控制權(quán)返回到任務(wù)A時(shí),它將請(qǐng)求傳輸。根據(jù)以太網(wǎng)控制器芯片的設(shè)計(jì),這可能會(huì)重傳數(shù)據(jù)包B或產(chǎn)生錯(cuò)誤。數(shù)據(jù)包A丟失,并且不會(huì)發(fā)送到網(wǎng)絡(luò)上。
+ r: M% G) q8 g0 o為了可以同時(shí)從多個(gè)RTOS任務(wù)中調(diào)用此以太網(wǎng)驅(qū)動(dòng)程序的功能,必須使它們可重入。如果它們每個(gè)僅使用堆棧變量,則無事可做。6 h; D  Z9 L( D( {) u
因此,C 語言函數(shù)最常見的樣式是可重入的,但是除非經(jīng)過精心設(shè)計(jì),否則驅(qū)動(dòng)程序和某些其他功能將是不可重入的,
5 {/ W- [2 u# Z: t. r' `( n使函數(shù)可重入的關(guān)鍵是暫停對(duì)外圍設(shè)備寄存器,包括靜態(tài)局部變量,持久堆對(duì)象和共享內(nèi)存區(qū)域在內(nèi)的全局變量的所有訪問的搶占。
  J8 |* M7 ^0 Y這可以通過禁用一個(gè)或多個(gè)中斷或獲取并釋放互斥鎖來完成。問題的細(xì)節(jié)決定了最佳解決方案。: ~+ @0 T. \" J# I7 e8 Q
最佳實(shí)踐:在每個(gè)庫或驅(qū)動(dòng)程序模塊中創(chuàng)建和隱藏一個(gè)互斥量,這些互斥量不是本質(zhì)上可重入的。使獲取此互斥鎖成為操作整個(gè)模塊中使用的任何持久數(shù)據(jù)或共享寄存器的前提。
+ F  f- [7 d- S例如,相同的互斥鎖可用于防止涉及以太網(wǎng)控制器寄存器和全局或靜態(tài)本地?cái)?shù)據(jù)包計(jì)數(shù)器的競(jìng)爭(zhēng)情況,在訪問這些數(shù)據(jù)之前,模塊中訪問此數(shù)據(jù)的所有功能必須遵循協(xié)議以獲取互斥量。/ h( f+ ]- q0 p0 b( ?
注意非重入功能可能會(huì)作為第三方中間件,舊版代碼或設(shè)備驅(qū)動(dòng)程序的一部分進(jìn)入您的代碼庫,令人不安的是,不可重入函數(shù)甚至可能是編譯器隨附的標(biāo)準(zhǔn)C或C ++庫的一部分。( V4 V7 _7 D5 P' W3 R
如果您使用GNU編譯器來構(gòu)建基于RTOS的應(yīng)用程序,請(qǐng)注意您應(yīng)該使用可重入的“ newlib”標(biāo)準(zhǔn)C庫,而不是默認(rèn)庫。. ?" d! H4 G( s9 Z2 C' _+ y; [# b
原文:https://blog.csdn.net/weixin_44059661/article/details/107839764! y: a( _8 k$ l+ V2 W7 B

/ g& _/ A8 s$ B5 \( D- N* ^9 Y6 E; V. H$ _* w5 g( q

+ Q4 v2 v6 o# p0 d5 x-END-" E4 X1 b2 e& v: M7 R6 `9 g
往期推薦:點(diǎn)擊圖片即可跳轉(zhuǎn)閱讀# o  V! ?. n$ S# e3 {! Y/ @
% F) K9 j0 `4 r
                                                        , B$ r0 _" |! i  Y' b# X" U* {
                                                               
" G5 q+ e) B( k- R+ Z; G2 K                                                                       
# [$ ]) [* r7 f, s4 q9 A                                                                                2 O' K* Y% F/ W# s2 i

+ `0 X; I, B, v6 ?4 s' D                                                                                4 _" p* D8 b+ {- u! d
                                                                                        讓嵌入式工程師,回歸創(chuàng)造力!
$ N8 G" _) q1 `( N% ~                                                                                ( L" F0 ~* b1 A
                                                                        2 o; {. y. r' m9 u* a1 s* \- y
                                                                7 Q: j- l6 G9 A
                                                       
7 c$ B; H: Z9 r1 C6 h                                                # h1 F( l0 u1 g1 W3 h

' ^' w0 ^! `$ [                                                       
2 f$ T0 Y, A" S$ ?                                                               
; O% I) C  ?/ k                                                                       
6 ]7 J( H& c! K( w                                                                               
% t$ S9 o8 y8 [( p/ u
$ a% |( S6 P  y& M5 H3 U                                                                                6 M+ f; v) O. j! Q9 |& s) l8 }
                                                                                        嵌入式軟件使用狀態(tài)機(jī)架構(gòu),一般有什么優(yōu)點(diǎn)?+ R' N6 s$ D  P$ M
                                                                                + k# F  j$ n$ @
                                                                       
6 r2 J0 w% ~( Q                                                                4 P5 H  t% W- M& [
                                                       
2 o, F  K5 X& `5 _* q                                               
8 Z7 k/ {7 L' s- s2 N$ P" a  u2 ]+ ]% w4 _! W/ Z
                                                        " ?- K0 E4 C% z5 x: i0 q0 y
                                                               
- U3 k3 u9 D6 S( [3 Q0 i                                                                        * v. c8 i& v9 Z" ?% Q+ t+ ?  H8 @
                                                                               
2 m: Z; V! [- f& H: t% g
& }1 l! P" A: J4 p  K: y                                                                               
% [/ ^& K" m* _# W' N7 _, s' |                                                                                        嵌入式編程,一些常見的計(jì)算機(jī)術(shù)語。# X! t) N8 z: M4 e3 c
                                                                               
, O9 s/ g" v  U3 b) [                                                                       
' l. T% S0 v& T/ x7 M6 E  h                                                                . p0 e1 S% D$ v
                                                        : y# m8 Z# G3 T+ j; x
                                               
5 A0 y, N; x0 J$ j5 V7 a! b+ V- s; b我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師
. h9 C2 x8 H% G0 j關(guān)注我,一起變得更加優(yōu)秀!

發(fā)表回復(fù)

本版積分規(guī)則


聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表