本著授人以漁的原則,既提供我一直在用的程序架構(gòu),也講程序架構(gòu)的設(shè)計思路。
如果本文內(nèi)容,你都能領(lǐng)悟并做到,不管項目多復(fù)雜,都將游刃有余。
我研發(fā)的那幾年,接觸大多數(shù)工程師,都沒有程序架構(gòu)的概念,基本一個while死循環(huán)干到底。
模塊之間也沒有封裝好,導(dǎo)致代碼寫好以后,擴展性和維護性太差,類似的功能代碼,也很難移植到新項目去復(fù)用。
早期我也是這樣寫的,反正實現(xiàn)功能就行了,代碼好不好,功能上又看不出區(qū)別。
不過,等你接觸到復(fù)雜的項目時,這招就行不通了,沒設(shè)計好程序架構(gòu),根本做不穩(wěn)定。
我意識到這個問題,是碰到兩種需求的時候:
1.是做一個基于STM32的網(wǎng)關(guān)項目,項目做完以后,客戶老是要改功能,客戶不懂技術(shù),在客戶眼里,覺得改一個LED閃爍效果很簡單,但對于程序架構(gòu)沒設(shè)計好的工程師來說,就是一個噩夢,比如每隔5秒快閃2次這種惡心的需求,搞不好很多代碼都要重新組織。
我經(jīng)常會被這種問題搞到頭痛,特別是客戶又催得急的時候,經(jīng)常加班加到焦頭爛耳,越急又越搞不出來。
2.我做過的很多項目,其實很多功能都有重復(fù)的,比如很多產(chǎn)品都有LED、都有按鍵、都有掉電參數(shù)存儲、都有串口協(xié)議解析等等。
但是程序架構(gòu)沒寫好,導(dǎo)致想移植代碼,過來新項目復(fù)用時,不太好改,比如老項目才1個LED,新項目有6個LED,類似的還有按鍵等等。
后面為了有更多的時間摸魚,我開始思考,怎么把程序?qū)懙?,改起功能來很方便,代碼復(fù)用性又很強那種,當(dāng)時還不知道這個叫程序架構(gòu)設(shè)計。
程序架構(gòu),我覺得是一個系統(tǒng)的學(xué)問,貫穿著整個項目,而不是具體某些細節(jié)。
就是各種功能模塊,比如LED特效功能,按鍵檢測功能,菜單功能,系統(tǒng)參數(shù)存儲功能、語音功能、OTA升級功能等等。
這些功能模塊的設(shè)計,我通常是采用硬件驅(qū)動代碼和功能邏輯代碼分離的方式,用大白話來說,就是一個功能模塊,我可能會分2個.c文件來寫,硬件驅(qū)動代碼我以hal_xxx.c命名,功能邏輯代碼我以mt_xxx.c命名。
硬件驅(qū)動代碼主要是和單片機外設(shè)的配置代碼,比如設(shè)置GPIO、Timer、串口、SPI這些,然后提供硬件接口給mt_xxx.c調(diào)用。
拿無際項目特訓(xùn)營的項目6來舉例,這個項目可以實現(xiàn)遠程控制,因為加了WiFi和4G模塊。
如果你接觸過類似項目,單片機和云平臺之間,其實還有個串口通訊協(xié)議的,類似于下圖這種。
按照我的思維,我會這樣去設(shè)計程序:
單片機外設(shè)驅(qū)動的配置、串口發(fā)送數(shù)據(jù)、接收數(shù)據(jù)代碼,我都放在hal_uart.c里。
串口協(xié)議數(shù)據(jù)發(fā)送和解析的代碼,我會放在mt_protocol.c文件里。
這樣就能實現(xiàn)硬件驅(qū)動代碼和功能邏輯代碼徹底分離。
那這樣的好處是什么?
1.萬一要換單片機了,如果通訊協(xié)議不變的情況下,mt_protocol.c文件代碼可以不用改,只要改hal_uart.c硬件驅(qū)動程序,就能對接起來。
2.如果通訊協(xié)議格式變了,單片機不變,那只需要改mt_protocol.c文件代碼就可以了。
3.調(diào)試方便,比如mt_protocol.c的功能,可以在PC上搭建一個開發(fā)環(huán)境先調(diào)試好,再對接硬件驅(qū)動接口,對于復(fù)雜的功能,這招還是很有用的,畢竟keil仿真調(diào)試沒那么方便靈活。
這種設(shè)計,就是一種架構(gòu)思維,解決了代碼擴展性和移植性的問題。
如果每個功能模塊都采用這種思維去設(shè)計,最終從整體看,你的程序架構(gòu)就非常好了,就像組裝汽車一樣靈活了。
所以,要設(shè)計好程序架構(gòu),真的不是靠一個課程能搞定的,需要完整地做幾個復(fù)雜的項目,并且有資深工程師的思路和代碼,可以參考和借鑒,這樣才能高效,系統(tǒng)地掌握。
每個功能模塊都設(shè)計好以后,最后還需要有一個協(xié)調(diào)者。
類似于人的大腦,去協(xié)調(diào)手、腳、眼睛、耳朵、嘴巴。
這個大腦,一般就是程序的"地基",類似于RTOS,就是"協(xié)調(diào)者"身份,負責(zé)調(diào)度協(xié)調(diào)整個項目的各個功能模塊。
RTOS本質(zhì)也是一種程序架構(gòu),但是我很少用,因為它的處境,其實很尷尬。
沒那么復(fù)雜的項目,上RTOS并沒有優(yōu)勢,反而為后期調(diào)試帶來不必要的麻煩,如果對系統(tǒng)不熟悉,就像埋了一個定時炸彈,可能會跑一段時間后死機的現(xiàn)象。
復(fù)雜的項目,有些直接上Linux了,現(xiàn)在很多***,成本也能做得很低。
所以,現(xiàn)在rtos的應(yīng)用,我覺得主要集中在中等復(fù)雜的項目,要求實時性很高,同時工程師,又不具備設(shè)計程序架構(gòu)的能力時。
不過,至今為止,我基本是用自己設(shè)計的架構(gòu)去替代RTOS,目前大多數(shù)產(chǎn)品都夠用。
這個架構(gòu),我也錄了套系統(tǒng)的教程,粉絲可以找我拿去參考學(xué)習(xí)。
寫了3個多小時,腦子和手都麻了(我的意思是,可以開始點贊了^ ^)
編輯:黃飛
?
評論