2019-02-22 10:00:28分類:嵌入式軟件開發(fā)設(shè)計7562
“嵌入式軟件”這個名詞很籠統(tǒng),但一般業(yè)內(nèi)的理解就是直接與硬件打交道的軟件。大部分嵌入式軟件工程師基本工作內(nèi)容如下:裸機(jī)——RTOS——Linux,以及一些新生的概念。
1、裸機(jī)開發(fā)
裸機(jī)開發(fā)看起來隨意性很大,因為沒有固定框架、固定接口,從驅(qū)動、算法、界面、頂層應(yīng)用都是自己做。但這往往就是初學(xué)者的心態(tài),或剛?cè)胄械母窬帧?/span>
裸機(jī)開發(fā)的平臺雖然不如隔壁互聯(lián)網(wǎng)那些千變?nèi)f化的框架多,但數(shù)量還是有很多:STM32、AVR(MicroChip)、瑞薩、飛思卡爾(NXP)、新唐電子……開發(fā)平臺大部分都由芯片廠規(guī)定。但這只是表面看起來豐富,對于嵌入式老司機(jī)而言,這些雜七雜八的所謂平臺都逃不出:編輯器、編譯器、鏈接器、燒寫調(diào)試器、芯片電路板。在STM32上配置寄存器,難道在RH850上就不會了嗎?并不是,嵌入式軟件的開發(fā)套路是比較固定的,開發(fā)工具大同小易。比互聯(lián)網(wǎng)跳框架難度應(yīng)該不會大,如果感覺很大,多看幾遍芯片的datasheet吧。這幾年隨著芯片越來越統(tǒng)一化(比如ARM Cortex生態(tài)系統(tǒng)),有些廠推出了圖形化配置的工具比如STM32CubeMX,其實不過是做了層封裝和調(diào)用而已,而且僅僅限于引腳、時鐘配置、驅(qū)動、加載協(xié)議棧,對于中間層、應(yīng)用層幫助不大。但至少配置沒那么繁瑣和容易出錯了,但產(chǎn)生的程序代碼可能并不符合很多公司的代碼規(guī)范和框架。我知道有些公司是自己開發(fā)這類配置軟件的,當(dāng)然要項目足夠大和穩(wěn)定才行。
裸機(jī)開發(fā)的第一個套路是框架。合理的框架有助于程序閱讀、修改、移植。裸機(jī)程序的框架一般只有三層:驅(qū)動、中間層、應(yīng)用層。中間層往往被忽略,其實它作為應(yīng)用和驅(qū)動的對接層,寫得好對于程序移植和理解好處多多。很多業(yè)內(nèi)的很喜歡把三個攪在一起,因為趕項目所以不太在乎。而且大部分做嵌入式的都是硬件出身,沒有軟件出身人的滿腦子框架束縛。設(shè)計可變模塊用#ifdef來靈活使用,在應(yīng)用模塊用回調(diào)函數(shù)控制被調(diào)用模塊改變。這些都是基本套路。嵌入式軟件本質(zhì)上還是軟件,軟件那套低耦合、強(qiáng)內(nèi)聚、模塊化等概念是要一脈相承的。這里不拓展講,業(yè)內(nèi)人士要多看看軟件相關(guān)書籍,雖然沒有幾本寫的好的。很難找到單純討論嵌入式軟件的書,那些掛名號的大都是結(jié)合硬件講的,且就講個驅(qū)動設(shè)計,連框架、語法、構(gòu)建都懶得說。這或許還是大家都出身硬件的緣故。如有朋友知道有這方面寫的好的書,請推薦。嵌入式軟件工程師也要所學(xué)學(xué)軟件的理論,那些封裝、面向?qū)ο蟮溶浖O(shè)計基本套路還是要掌握的。
裸機(jī)開發(fā)第二個套路是任務(wù)調(diào)度。因為沒有操作系統(tǒng)加持,任務(wù)調(diào)度要自主實現(xiàn)。嵌入式軟件任務(wù)調(diào)度要考慮硬件性能,放一個while(1)大循環(huán)、前后臺中斷,理想情況下看是所有任務(wù)都會即使執(zhí)行的,實際上芯片壓根性能沒那么強(qiáng)勁,中斷多了任務(wù)就不執(zhí)行了。一般這里有兩個分類,一類是基于(中斷)事件、一類是基于時間?;谑录径际抢硐胫髁x,認(rèn)為美好的事總會發(fā)生,而基于時間則是物理規(guī)律——任一時間芯片只做一件事,并且認(rèn)為外界的事件發(fā)生是有時間間隔的(瞬態(tài)無時間間隔的任務(wù),芯片只能說臣妾做不到啊!)。當(dāng)然一切都要基于需求,假設(shè)芯片就是只做一兩個任務(wù),那就是一個while(1)+前后臺有什么所謂。多任務(wù)程序框架就必須要考慮基于時間了。
裸機(jī)開發(fā)的第三個套路是狀態(tài)機(jī)。猶記得第一份工作時,面試官的第一個問題就是讓我談?wù)劆顟B(tài)機(jī)。狀態(tài)機(jī)在裸機(jī)程序設(shè)計里應(yīng)用非常廣,也是一種優(yōu)秀的設(shè)計模式。狀態(tài)機(jī)集合了任務(wù)調(diào)度、程序框架的概念。甚至業(yè)內(nèi)優(yōu)秀的狀態(tài)機(jī)框架被商業(yè)化了比如QT量子狀態(tài)機(jī)框架。狀態(tài)機(jī)不是程序流程圖,程序流程圖一般是基于用戶一步步操作的,狀態(tài)機(jī)是基于系統(tǒng)運(yùn)行狀態(tài)的,所以流程圖一般用于做需求,狀態(tài)機(jī)用于做開發(fā)。狀態(tài)機(jī)程序設(shè)計首先要用UML工具畫好程序狀態(tài)圖,要明確某一時刻系統(tǒng)智能處于某一狀態(tài),以及狀態(tài)跳轉(zhuǎn)的條件。把狀態(tài)機(jī)和任務(wù)調(diào)度結(jié)合,就是用時間輪詢不斷執(zhí)行一個個狀態(tài)機(jī)。狀態(tài)機(jī)內(nèi)部設(shè)計方法非常重要。當(dāng)熟稔后,狀態(tài)機(jī)就是愉悅的switch case,if else了。
業(yè)內(nèi)一直有一些偏見認(rèn)為做裸機(jī)程序的人軟件水平不行,甚至揚(yáng)言在目前硬件性能爆炸的年代不應(yīng)該在乎代碼量。這依舊是初出茅廬的人說的,任何開發(fā)都要基于明確的需求,那些能用少了幾塊錢的芯片、少了一兩個級別軟件復(fù)雜度做出產(chǎn)品的工程師才是公司需要的。一個發(fā)貨量十幾萬的產(chǎn)品,能提前一周上市,公司盈利很可觀了。工程師要做的是用最快的速度滿足需求,而不是比較什么技術(shù)比較高超,那是象牙塔的理論。
2、RTOS
RTOS本質(zhì)上僅僅是個任務(wù)內(nèi)核,對于硬件驅(qū)動僅僅涉及到RAM、時鐘等這些與任務(wù)調(diào)度直接相關(guān)的驅(qū)動。這不就是裸機(jī)任務(wù)調(diào)度那套玩意放大版么。但RTOS任務(wù)調(diào)度更加復(fù)雜,涉及到任務(wù)切換、任務(wù)通信、內(nèi)存管理等??雌饋鞷TOS好像內(nèi)容很多,但其實,其實也就只有這些內(nèi)容了。作為實時操作系統(tǒng),RTOS如果涉及太多會拖慢任務(wù)調(diào)度速度,因此實際上它僅僅扣出操作系統(tǒng)最基本的東西——任務(wù)管理和內(nèi)存管理來實現(xiàn)。如果能結(jié)合操作系統(tǒng)知識來學(xué)習(xí)RTOS收獲應(yīng)該更大,體會為了實現(xiàn)理論家口中的操作系統(tǒng),RTOS做了怎樣的妥協(xié)和靈活。RTOS本質(zhì)上僅僅是個中間模塊,把它拿掉,自己設(shè)計一個任務(wù)管理和內(nèi)存管理模塊,即使糙一點(diǎn)也還是能用的而且還能非常小心地把控硬件資源。但在經(jīng)過N多項目考驗的FreeRTOS、UC/OSII等優(yōu)異的RTOS面前,加上項目需求的多樣,恐怕很少工程師會抵制住誘惑。
正是因為RTOS僅僅實現(xiàn)了操作系統(tǒng)一部分功能,因此設(shè)計一個RTOS好像不是那么難。于是RTOS市場風(fēng)起云涌,專用的、通用的、內(nèi)部用的、開源的……但是其實用什么RTOS只要你不是技術(shù)總監(jiān),選擇跟你沒有關(guān)系。當(dāng)然DIY除外,筆主比較推崇FreeRTOS、UC/OSII、UcLinux,這些案例多,健壯的RTOS。
3、Linux
本來起個通用操作系統(tǒng)的標(biāo)題,但發(fā)現(xiàn)毫無意義,Windows不開源、Android內(nèi)核本來就是Linux,兜這么大個圈還不是只能講Linux,所以還是叫Linux好了。
Linux作為通用操作系統(tǒng),在業(yè)內(nèi)是為實現(xiàn)任務(wù)種類多、界面多、造價高這類項目準(zhǔn)備的。Linux完整實現(xiàn)了操作系統(tǒng)的所有理論,包括驅(qū)動管理、文件管理、任務(wù)管理、內(nèi)存管理、網(wǎng)絡(luò)協(xié)議、安全管理等等。雖然看起來好像內(nèi)容好多,但僅僅就內(nèi)核而已,除了開發(fā)驅(qū)動(還要去掉直接與CPU相關(guān)的驅(qū)動,這些內(nèi)核已經(jīng)適配了)、做做中間包、做做應(yīng)用程序,很多工程師無能為力。真正的內(nèi)核開發(fā)是Linus、intel公司那些大牛做的,我們只能用用。但就是這么少的一部分,已經(jīng)夠折騰人的了。
對于Linux標(biāo)準(zhǔn)的要求就是會移植、會開發(fā)驅(qū)動和拼湊進(jìn)Linux去、會shell C開發(fā)調(diào)用。做應(yīng)用層的多的就是QT 環(huán)境開發(fā)了,這玩意和Java JVM是差不多的邏輯,就是在shell上面再放一層解釋器或加入調(diào)用包一起編譯而已。
4、協(xié)議棧、中間包
這幾年嵌入式領(lǐng)域因為硬件性能提升和任務(wù)多樣化,涌現(xiàn)了很多專一功能的協(xié)議棧、中間包。比如藍(lán)牙協(xié)議棧包、WIFI協(xié)議棧包、STemwin GUI包、安全棧、神經(jīng)網(wǎng)絡(luò)加速包等等。很多棧和包實際上已經(jīng)超出了傳統(tǒng)的嵌入式軟件領(lǐng)域了。比如無人機(jī)姿態(tài)控制的PID包、手機(jī)人臉識別NPU加速包等,這些對數(shù)學(xué)的要求高于代碼,也不是一般工程師能做的,要有數(shù)學(xué)功底。當(dāng)然并不是高不可攀,再說誰不會調(diào)基本的PID呢。