學習嵌入式,我們到底該學些什麼?

嵌入式越來越複雜,一個SOC芯片上集成的模塊越來越多。以手機爲例,典型的嵌入式產品,我們看看上面集成了多少模塊:觸摸屏、LCD、USB、WiFi、4G等無線通信、音視頻編解碼IP、DDR、存儲控制器、3D/2D加速、GPS、指紋識別、NFC、DMA、G-sensor各種傳感器.......。可以說,現在一個手機的複雜度和硬件配置,已經超過我們的桌面PC了。除了不斷增加的硬件,軟件方面,比如Linux內核,光內核代碼就有1000多萬行,每天更新的速度超過你學習的進度,你能學得完嵌入式的所有知識和技能嗎?工業主板

嵌入式系統開發

早期PC時代,我們知道能做出X86 CPU量產的也沒有幾家,Intel、AMD和威盛。但是嵌入式時代不一樣了,ARM的IP授權模式導致不同的芯片廠商百家齊放,不同的SOC平臺和開發板眼花繚亂,針對不同行業需求定製的SOC平臺雨後春筍:手機芯片、平板芯片、視頻安防、物聯網、汽車電子、工業控制,甚至人工智能AI芯片....,你到Linux內核的ARCH下面可以看看有多少種CPU架構,再到arch/arm下面看看有多少種開發平臺,這還只是加入到內核mainline的平臺,算上沒有加入Linux內核主線的各種平臺,其實數量更多。

衆多的芯片架構、不同的開發板平臺,我們該如何去學習?

嵌入式和PC的概念也越來越模糊了,Intel已經推出X86架構的CPU和嵌入式產品了,比如平板。ARM也開始進軍服務器和筆記本領域了。無論什麼CPU架構,ARM、X86、MIPS、PowerPC,還有最近火熱的物聯網芯片,無論是做嵌入式產品,還是PC、服務器,他們的底層本質其實都沒有變,都是計算機原理和系統架構,都是馮諾依曼的計算機架構,圖靈原型機的各種實現。

不斷複雜的軟硬件系統,對嵌入式工程師或者學習者來說是一個挑戰。這對我們本身的知識和技能有一個更新的要求。早期51單片機時代,我們可以自己使用麪包板或者自己畫PCB,做一個開發板,然後在上面開發軟件。軟件、硬件自己全搞。現在不斷複雜的SOC平臺,再想一個人全搞,軟硬通吃,基本不可能,這也導致我們需要分工協作來完成。首先軟硬件的分工,各司其職,各自精通自己的領域,然後進行軟硬件整合,協作開發。再次,軟件方面,嵌入式軟件也越來越複雜,Linux內核1000多萬行,android源碼下載下來就佔幾個G的空間,自己想全搞,同樣不可能,同樣需要進行分工。比如android,需要分爲BSP工程師、Linux內核工程師、驅動工程師、android中間層開發工程師、APP開發工程師。對於一個Linux內核,也需要分工,各個模塊同樣進行分工:Linux內核的USB子系統、音頻子系統、視頻編解碼、文件系統......把其中一個模塊你搞精通了,工資絕對不是問題。

對於嵌入式學習者來說,我們該學習什麼,或者說如何學習?才能提高自己的職場競爭力,或者說對於一個新手來說,如何通過自學,達到公司的用人標準和技術要求,找到一份自己想要的工作?

首先,你要學會做減法,從現實出發,要有這樣一個意識:我不可能精通所有的嵌入式技術,學會堅持,制定合理現實的小目標。很多人喜歡那種不切實際的廣告轟炸營銷,擊中你心理上的某個軟肋,某個G點,一下子興奮起來。越熬越濃的心靈雞湯,並不能解決我們吃飯的生存現實問題。很多人,包括我,在學習的時候,都喜歡給自己樹立各種路線、計劃、日程表。制定計劃時激情滿滿,熱情高漲,激動得睡不着覺。計劃宏偉而飽滿,彷彿成功就在眼前。但是往往不切實際,往往在早期,遇到各種困難,各種坑,各種拖延導致沒有堅持下來,最後夭折。然後接着制定下一個宏偉的計劃,繼續夭折,生活周而復始,day after day。觀察我們生活周圍,真正做出成績的都是那些基於現實出發,能一路堅持下來的人,day by day。有時候你會發現,並不覺得他們有多聰明。

其次,保持自己的興趣,說白了就是爲了堅持下去。見過很多人想學習嵌入式,花了很多米買一塊開發板,激情滿滿,過一段是過去再看,已經不折騰了。嵌入式開發難,難在哪裏呢?主要在於開發環境的搭建,軟件調試上,不像在Windows上使用VC開發程序,集成開發環境都幫你弄好了,各種斷點、單步、查看堆棧、寄存器、內存窗口。而嵌入式不一樣,硬件環境搭建會遇到各種各樣的問題,各種電腦的兼容問題,各種莫名其妙的問題,有時候着實讓人抓狂,時間久了,慢慢地學習的激情殆盡,也就不想學習了。這還不算什麼,更嚴重的是,很多人學習嵌入式遇到挫折,往往會打擊人的自信,覺得自己能力不行,智商不夠,不適合幹這行,在心理留下了陰影。對於個人學習者來說,買了開發板,你不買配套的萬用表、示波器等調試設備,遇到硬件問題也是一籌莫展,無法解決。其實我們可以完全使用其它的平臺去開展我們的研究和學習,比如QEMU,一款可以仿真開發板的開源軟件,使用這款開源軟件,我們可以在電腦上虛擬一個世面上流行的開發板,然後再在這個仿真的開發板上跑u-boot、Linux內核、掛載根文件系統,使用和開發板一樣的源碼,運行效果和真實的開發板是一樣的。而且,使用QEMU的好處就是,「硬件」永遠不會出問題,可以讓我們避過硬件的各種坑,騰出更多的精力去研究嵌入式軟件的各種架構、編程技能、內核驅動....,這些纔是嵌入式工程師的核心競爭力,需要花大量的時間不斷地去積累,去磨合,去提高的。把大量的時間耗在一個本該不屬於學習範疇的硬件bug上或者硬件環境不兼容上,不划算,因爲你以後進公司後,遇到同樣的問題,找硬件工程師,半分鐘幫你搞定。所以說,選擇一個理想的嵌入式學習平臺,尤其對於初學者來說,很重要。

最後,要保持學習的深度,刻意練習。不要讓自己永遠待在學習的舒適區,要學會挑戰自己,不斷去擴展自己知識的邊界,完善自己的知識體系和技能。很多人買了開飯,按照教程,「移植」了u-boot,Linux內核,製作了根文件系統,然後就陷入了迷茫:接着要幹什麼?要學習什麼?想學習又感覺深入不下去,東一耙子,西一耙子,看看這,看看那,時間不知不覺就過去了。其實,學習嵌入式,基本的嵌入式知識和理論學習還是必要的,很多人推崇邊做邊學,到項目中學習,實踐出真知。當然這也是一個方法,但是也有弊端,那就是學習的不繫統,很多有心人到後來還是得回來補課,完善自己的知識體系和技能。很多人玩開發板,燒寫鏡像,玩得賊溜,但是你知道這裏面的原理嗎?知道JTAG怎麼下載的嗎?Jlink和JTAG有什麼區別?爲什麼PC上要裝個JTAG軟件而Jlink不用?程序的編譯和鏈接是怎麼樣的?爲什麼內核鏡像要下載內存的某個地址?換個地址行不行?爲什麼我們編寫的程序要在有OS的環境下運行,在ARM開發板裸機環境下,你能寫一個跑起來的程序嗎?只有對這些問題深入思考,你纔會對嵌入式有一個更深的認識,超越了平臺,一通百通。