良好記錄的源代碼可以通過提供對軟件的深入了解來減少設(shè)計成本和上市時間,否則需要時間和實驗來喚起嵌入式開發(fā)人員對代碼行為的內(nèi)容和原因的記憶。如果失去了這些洞察力,還會增加成本,并通過將錯誤引入代碼庫來推遲上市時間。
在繁忙的開發(fā)周期中,注釋C代碼落到優(yōu)先級列表的底部并不罕見。在將產(chǎn)品發(fā)布出去的壓力下,紀(jì)律通常會失效,捷徑會導(dǎo)致糟糕的代碼庫。這里有10個簡單的技巧,你可以遵循它們來確保軟件不僅被文檔化,而且還包含有用的信息。
1、解釋為什么,而不是如何
在開發(fā)軟件時,人們似乎傾向于解釋一行代碼在做什么,而不是首先解釋代碼為什么會在那里。一個最受歡迎的例子是將文字移位x位。代碼和注釋通??雌饋硐襁@樣
// Shift bit by 8 and store in PortB
*Gpio_PortB |= (1UL<<8);
這個評論本身就有很多不盡人意的地方。任何對C語言有基本了解的人通過觀察都知道代碼行在做什么,但是為什么我們要移動 8 位呢? 為什么我們要將移位的位模式存儲到 PortB 中? 如果嵌入式開發(fā)人員在編寫這行代碼六個月或一年后閱讀這行代碼,如果不調(diào)查這一行代碼到底在做什么,他將會一無所知。
更合適的情況可能如下所示:
// Port B bit 8 controls the motor relay that needs to be turned off during the
// emergency stop procedure. Setting bit 8 high will disengage the motor through a relay.
*Gpio_PortB |= (1UL<<8);
這個評論可能并不完美,但它解釋了為什么開發(fā)人員將移位和按位或運(yùn)算到PortB中。哪個評論更受歡迎?
2、編碼前注釋
注釋代碼的常識總是建議在編寫代碼的同時編寫注釋。這種見解很有道理;當(dāng)編寫軟件時為什么開發(fā)人員對此記憶猶新。開發(fā)人員可以等到軟件寫完之后,但是推向市場的壓力和其他優(yōu)先考慮的事情通常使得注釋很可能無法傳達(dá)最初的意思。
在代碼期間或之后編寫注釋的另一種方法是在編寫軟件之前編寫注釋,這有一個獨(dú)特的優(yōu)勢,允許嵌入式開發(fā)人員在編寫一行代碼之前考慮他們將要編碼的內(nèi)容和原因,它可以被認(rèn)為是將軟件架構(gòu)和開發(fā)的設(shè)計階段轉(zhuǎn)化為源代碼,這種方法將軟件設(shè)計放在開發(fā)人員的首要位置,并允許他們清楚地思考他們將要編寫的代碼是為了什么。
3、使用Doxygen標(biāo)簽
網(wǎng)上有許多不同的免費(fèi)工具可以將代碼注釋轉(zhuǎn)換成有用的文檔格式。能夠掃描源代碼并生成html、rtf和/或pdf的工具應(yīng)該是開發(fā)人員的夢想。為什么?許多開發(fā)團(tuán)隊不僅要維護(hù)他們的源代碼,還要維護(hù)各種描述代碼實際工作的設(shè)計文檔。這些文檔經(jīng)常追蹤程序中實際發(fā)生的事情。
使用工具,例如Doxygen可以自動將代碼注釋翻譯成符合這些設(shè)計文檔清單的文檔。最終結(jié)果是,開發(fā)人員現(xiàn)在只需要維護(hù)一個源代碼和文檔鏈,這將減少他們創(chuàng)建“漂亮”文檔所需的時間。(也希望確保文檔和源代碼彼此保持同步)。
Doxygen已經(jīng)被廣泛接受,以至于編譯器和芯片供應(yīng)商在其自動生成的代碼中包含了Doxygen標(biāo)簽。他們將Doxygen構(gòu)建到工具鏈中,以使開發(fā)人員更容易生成文檔。作為開發(fā)人員,難道我們不應(yīng)該接受這個讓文檔變得如此簡單的免費(fèi)工具嗎?
4、采用代碼風(fēng)格指南
編碼風(fēng)格指南包含了開發(fā)人員正確創(chuàng)建標(biāo)識符所需的所有信息,以及如何記錄軟件。風(fēng)格指南有助于為嵌入式開發(fā)人員或開發(fā)團(tuán)隊提供以統(tǒng)一方式開發(fā)軟件的方法。這種一致性有助于開發(fā)人員消除由于風(fēng)格差異而可能存在的對軟件的干擾。結(jié)果是代碼評審更容易,因為代碼的風(fēng)格是統(tǒng)一的,評審可以集中在實際的代碼上,而不是注釋位置的表面細(xì)節(jié)。
5、使用文件頭
強(qiáng)烈推薦使用版本控制系統(tǒng),但是在代碼庫發(fā)生變化時總是參考版本控制系統(tǒng)會變得很乏味。有時可能會令人困惑或不清楚特定模塊的目的是什么。基于這些原因,建議頭文件和源文件包含一個注釋頭,描述模塊的功能和用途。
標(biāo)題中可以包含許多信息,但至少應(yīng)包括:
文件名
作者
起始日期
模塊版本號
用于編譯代碼的編譯器版本
預(yù)期目標(biāo)
版權(quán)信息
雜項說明
修訂信息
……
6、創(chuàng)建評論模板
確保代碼注釋一致并遵守Doxygen語法的最佳方法之一是創(chuàng)建一個注釋模板。嵌入式開發(fā)人員需要兩個模板:一個用于頭文件,另一個用于源文件。編碼模板將包含遵循編碼風(fēng)格所需的所有標(biāo)準(zhǔn)注釋塊。
注釋模板將包含一個文件頭以及注釋標(biāo)簽和注釋塊,用于結(jié)構(gòu)、枚舉,類型定義、和函數(shù)。
7、一致的評論位置
減少與軟件項目相關(guān)的錯誤和成本的最有效的方法之一是執(zhí)行代碼評審。開發(fā)人員通常執(zhí)行代碼評審,但是如果注釋結(jié)構(gòu)不一致,這個過程會變得更加困難。使用不同格式并放在不同位置的注釋會分散注意力,降低代碼評審的效率。
推薦使用編碼風(fēng)格指南,因為它不僅規(guī)定了應(yīng)該使用的注釋格式,還規(guī)定了注釋應(yīng)該出現(xiàn)在哪里,這將有助于保持注釋結(jié)構(gòu)的統(tǒng)一,并允許代碼審查者關(guān)注代碼及其行為,而不是被注釋中包含的位置或信息分散注意力。
8、不要注釋每一行
老實說,開發(fā)者真的不想評論他們的軟件。這既費(fèi)時又不令人愉快。旋轉(zhuǎn)位、控制硬件以及幾乎做任何其他事情要有趣得多。然而,通常認(rèn)為是文檔記錄良好的每一行代碼都要有一個注釋,這可能太多了。
注釋代碼的目的是為未來的嵌入式開發(fā)人員或維護(hù)人員提供關(guān)于軟件是什么和為什么的洞察力。冗長的文章既不需要也不想要。創(chuàng)建一個注釋塊來描述這個塊在做什么通常就足夠了。對塊進(jìn)行注釋的一個很大的好處是,如果代碼需要更改,但是塊描述仍然適用,那么描述可以保持不變,從而節(jié)省了開發(fā)時間,否則這些時間將會花費(fèi)在更新注釋上。
9、以類型開始數(shù)學(xué)類型標(biāo)識符
當(dāng)開發(fā)執(zhí)行數(shù)學(xué)運(yùn)算的軟件時,以標(biāo)識符的類型開始非常有用。例如,創(chuàng)建一個名為ui8_Velocity或si32_Acceleration的變量可以讓開發(fā)人員立即了解變量的類型。
以這種方式命名標(biāo)識符有很多優(yōu)點。首先,不需要引用變量聲明來獲取類型。這可以節(jié)省時間,因為開發(fā)人員不必不斷刷新變量的類型和大小,以及是否需要在計算中進(jìn)行強(qiáng)制轉(zhuǎn)換。第二,這種命名方式更容易發(fā)現(xiàn)轉(zhuǎn)換錯誤,比如兩個8位數(shù)字相乘而不進(jìn)行轉(zhuǎn)換。
10、進(jìn)行代碼更新時更新注釋
如果使用得當(dāng),將模板與Doxygen結(jié)合使用會是一個非常強(qiáng)大的工具。這些模板和工具的正確使用部分來自于軟件的更新和維護(hù)。只有當(dāng)嵌入式開發(fā)人員足夠自律,能夠隨著軟件的變化更新他們的注釋時,這些工具才有效。
在開發(fā)過程中,需求、設(shè)計和實現(xiàn)無疑會發(fā)生變化。作為這些變更的一部分,開發(fā)人員需要確保注釋總是隨著軟件的實現(xiàn)而更新。即使事實并非如此感覺就像有足夠的時間來實現(xiàn)代碼更改和更新注釋一樣,開發(fā)人員仍然應(yīng)該花時間來更新注釋。一個原因是,在產(chǎn)品的整個生命周期中,它的成本將受到開發(fā)人員保持紀(jì)律的極大影響,盡管他們可能面臨時間壓力。
結(jié)論
評論軟件通常被認(rèn)為是開發(fā)周期中優(yōu)先級最低的任務(wù)之一。快速實施和部署嵌入式軟件的壓力讓工程師們不得不忙于設(shè)計、實施和部署他們的固件。但事實是,注釋代碼并闡明代碼的原因可以使未來的維護(hù)工作甚至最初的開發(fā)工作花費(fèi)更少。在適當(dāng)?shù)那闆r下甚至?xí)p少上市時間。
這些技巧只是改進(jìn)嵌入式軟件設(shè)計周期的幾個簡單例子,通過使用模板、標(biāo)準(zhǔn)和自動化工具,并花時間解釋軟件的原因,減輕嵌入式開發(fā)人員的負(fù)擔(dān)。