1. 程式人生 > >關於嵌入式軟體開發的一些思考

關於嵌入式軟體開發的一些思考

    今天是第一次開始寫技術部落格, a dear dairy moment. 首先感謝這個論壇上那些已經進入計算機軟體開發自由王國的前輩高手們,正是他們在網路上不求回報地留下一篇篇精闢文章,如一盞盞指路明燈,真正為後來者照亮前進的方向;同時也想鼓勵那些仍然身處迷霧苦苦掙扎的摸索者,只要堅定信心不動搖,終有一天能夠登堂入室,苦盡甘來,從此終身享受嵌入式軟體開發這個超級好玩的遊戲。不必擔心,不要沮喪,雖然程式設計被某些人拔高得跟相對論一樣,其實只是一門技術或者手藝而已。“(技者),無它,但手熟耳”,加油!

 It will be my pleasure if I can help.

   為什麼要學嵌入式

初次接觸計算機與軟體程式設計的人都憧憬那種“藝高人膽大,瀟灑走天下”的境界,然而由於方法不當或目標不明確,很多人熱情不能持久,碰壁若干次後就中途放棄,空留遺憾和感慨:"軟體程式設計太難!"  或許電影中的天才黑客表現得很輕鬆,但實際他們只會敲空格和回車。世上本沒有什麼事可以一蹴而就。畢竟總體說碼農還是高技術活,而嵌入式比一般軟體更難,它牽涉到軟體語言、硬體電路、作業系統、通訊協議等多方面,對知識面和實踐經驗都有要求。

    有人說哪裡需要學那麼多, 只要會用IDE工具就行了。的確,windows上各種整合開發工具層出不窮,這些傻瓜式工具遮蔽了大量底層概念,表面上降低了“程式設計師”門檻,但同時導致越來越多的從業者基礎不牢,處於空中樓閣狀態,只能充當軟體開發流水線中一個機械的裝配工。傻瓜式工具整體固然有助於提高開發效率,減少重複勞動,但如果個人想為今後的提高開闢更廣闊的空間,就必須打破這個牢籠,對整個系統底層原理做深入挖掘,否則只能永遠跟在不斷變化的工具和介面後面亦步亦趨,直到退休還是一個“只會呼叫API的程式設計師”,悲哀!

    同樣是程式設計,位於不同層次,價值也大不相同。古代刀槍耍得好的是大俠,火器時代槍法準的可以縱橫天下,而現在能夠研發和操縱導彈原子彈才是國寶。任何一種技能的價值都依賴於時代背景,隨著社會發展而興衰起伏,我們應該選擇可見時間段內有生命力的技術,或者說要審時度勢地在技術潮流的不斷變化中找準有利位置。目前的軟體行業,桌面和嵌入式系統開發者之間,對於基本原理的理解以及技巧方面的差距越來越大,很多人經過短期培訓就可以在PC上用工具熟練地堆砌軟體,但由於上手快,難度低,這類程式設計師勢必逐漸平庸大眾化,價值也會隨之降低。物以稀為貴,只有門檻更高的嵌入式開發才是面向未來的選擇,具有更長遠的價值。

    目前的嵌入式熱潮為那些半路出家的程式設計師提供了難得的加固基礎,回爐改造的轉化捷徑。嵌入式開發常把人逼到一種境地:原來可以迴避,工具自動完成的過程如果不能手動完成,工作就沒法繼續。其實這是難得的突破機會,當碰到無法迴避的問題時,離跨越它也就為時不遠。將來嵌入式軟體也會變得越來越複雜,逐步接近桌面系統,那時切入的機會就越來越少了,現在學習嵌入式正是好時機。

    怎樣學習

      1. 理論結合實踐

    人們常說,讀萬卷書,行萬里路。於是我們每個人的成長基本都是先讀萬卷書,再行萬里路。傳統教育被認為只需要純粹讀萬卷書,行萬里路是畢業後的事。然而幾千年前子曾曰:學而“”習之,不亦樂乎。學與習從來都不能分割,否則只會事倍功半。缺少實踐的教育使很多學生嘴高手低,企業面試時聽到最多的話或許就是“這個聽說過,那個也知道,只是沒實際做過”,這就是有學無習的教育方式導致的必然結果,教學遠離實踐原因很多,比如:

    a)教育者自身知識多來自書本,沒有實際工作經驗,缺乏對外交流的能力和信心,而教學體制也沒有這種要求,照本宣科自然就成為常態。學校所學與社會所需嚴重脫節,使教和學很大程度上成了老師和學生的自娛自樂。

    b)重視各種基金背景的縱向課題,輕視面向企業實際問題的橫向課題。縱向課題容易發論文,評職稱,而橫向課題沒有唬人的標題和元素,總結不出“理論成果”。基金課題只要提個想法,發幾篇論文很容易交差,而與企業合作拿錢就要擔責,壓力大,風險高。換言之,“科學允許失敗”,企業投了錢卻不允許失敗。最終名目繁多的基金變相發了補貼,大量資金投入帶來了高產量的垃圾論文和所謂科研成果(永遠不可能轉化成生產力)。而聽話的好學生們在參與這種空對空課題後得到了什麼?大概只有捏造資料和拼湊論文的技巧吧。至於那些得自書本而缺乏實踐淬火的知識,其價值基本為零。畢業時,毫無技能地被拋向社會,表面“一肚子墨水”實際兩手空空,戰戰兢兢,還要由企業承擔再教育的成本。

    個人不能改變制度,但卻可以審時度勢修正自己。目前社會越來越看重人的技能而不是紙面知識,只有學以致用,才能贏在進入社會的起跑線上。我的一位“另類”導師曾說:大學裡每門都考高分的學生既愚蠢又可憐,他們還把大學當高中讀。分數保證畢業就足夠,為多餘分數付出時間和精力,不如參與實踐、錘鍊技能來得實惠。買個開發板,移植一些開源程式;做做專業相關的兼職;選擇一些有企業應用背景的課題。只有這樣“學&習”結合,知識與經驗才能同步積累。當今時代,知識逐漸為大眾所共享,經驗才真正屬於個人

    工作後相反,很多人沉浸在瑣碎的工作細節中,滿足於經驗帶來的成就感和職位穩定的安全感,每天努力工作,自豪於可以在公司佔據穩定位置養家餬口。然而一段時間後,不少整天埋頭苦幹的人卻逐漸被邊緣化,為什麼?

    現代企業分工越來越細,如果安心做流水線上的裝配工,一旦技術更新換代,就會立刻落伍,所以這種表面的勤奮工作其實是不思進取,不愛學習的懶惰表現,背後隱藏著危機。所謂能低頭做事還要會擡頭看路,只有跳出對狹隘經驗的滿足,不斷跟蹤新技術,補充新知識,提升自身層次,才能始終站立在潮頭。換句話說,如果大家都有應付眼前工作的能力和經驗,那麼眼界開闊,掌握更多新知識又重新顯得分外重要。

    總之,任何階段都要均衡安排學習與實踐。兩者的關係就象吃飯和消化,人必須通過實踐消化已有知識,才能騰出空間,不可能把所有的飯一次吃完;反之沒有外部營養的攝取,靠消化老本維持不了多久。學習實踐不均衡,就象一條腿走路,再怎麼努力,也走不遠。

2.讀好書

    寫本好書,傳道他人,原本是一件很神聖的事情,可惜現在已經逐漸變味。很多人寫書(姑且稱之為寫吧)主要為了炫耀自己,撈取或名或利的各種資本,而不是真心幫助他人。看看下面某教材的擷取(做反面典型,不給出處了,不會被告侵權吧,很多書上都這樣寫,抄來抄去實際上也找不到源頭)

嵌入式系統的定義:

1)定義:以應用為中心,以計算機技術基礎,軟硬體可裁剪,適應應用系統對功能、可靠性、成本、體積、功耗嚴格要求的專用計算機系統。

    2)嵌入式系統發展的4個階段:無作業系統階段、簡單作業系統階段、實時作業系統階段、面向Internet階段。

    3知識產權核(IP核):具有智慧財產權的、功能具體、介面規範、可在多個積體電路設計中重複使用的功能模組,是實現系統晶片(SOC)的基本構件。

    4)IP核模組有行為、結構和物理3級不同程度的設計,對應描述功能行為的不同可以分為三類:軟核、固核、硬核。

    點評動機決定行為方式,編教科書的人只求用詞語法顯得專業,讀者是否能懂就不是他們關心的了,反正他們是皇帝的女兒不愁嫁。而且教輔書多數還需要和各種形式的考試相互依存,狼狽獲利,於是這種固化、僵化,方便考試出題的表達方式就成了各種教育出版社圖書的專用語法。可想而知,那些虔誠的求學者,看了這正統的滴水不漏的卻如同天書般的描述是否能有所收穫?或許他們會覺得自己太笨,沒有學習計算機的天分吧。可憐以前我很長時間也這麼認為。

    前新東方的王強一次演講中提到了漢語和英語體現的文化差異:中國人(漢語)解釋一個概念,習慣把一堆形容詞放在前面,直到這堆臭裹腳布拆完,最後概念的核心才千呼萬喚始出來。這個習慣本質就是擺架子弄玄虛,很多寫書的人樂此不疲:多堆砌難懂的學術名詞可以體現專業性;形容詞多了滴水不漏;生造出一堆概念,說不定碰上哪個流行,自己就成了鼻祖。只是結果卻害慘了廣大讀者,想學點東西要拿出十倍的耐心。真正想學習知識的人還要披沙揀金,排除這一類以正統教材自居的教科書的影響,真是絕大的諷刺。反過來看看英文定義:

    An embedded system is a special-purpose computer system designed to perform one or a few dedicated functions, often with real-time computing constraints.It is usually embedded as part of a complete device including hardware and mechanical parts. In contrast, a general-purpose computer, such as a personal computer, can do many different tasks depending on programming. Embedded systems control many of the common devices in use today

    Since the embedded system is dedicated to specific tasks, design engineers can optimize it, reducing the size and cost of the product, or increasing the reliability and performance.

    讀完心情舒暢!embeded system中心是“一種特殊的計算機系統”。本人給個“下里巴人”版:“嵌入式系統就是嵌入到各種電子裝置中特殊專用的計算機系統。比如日常用的空調,洗衣機,電視等家用電器,以及MP3,MP4等消費電子產品,它們內部都有一個或多個CPU晶片,執行專用軟體完成某種特定功能,這些就屬於嵌入式系統。與此對應的是通用計算機系統,比如個人的PC機”

   這種表述不學術,也不夠嚴謹,卻更清楚易懂。可人們害怕降低身份,不願脫去學術這層高貴的畫皮。表達最學術最完善的未必最好,傳道首要應通俗易懂,而不是追求面面俱到。任何論述都有例外,不必去鑽牛角尖。世上本沒有絕對真理,要擡槓總能找到反例。如果總捎帶著那些百分之幾的例外,敘述起來包袱實在太重,酸腐的正反面辯證法方式也實在太無趣。先掌握主要,才有可能理解次要,否則就是一團糨糊。把所有情況一一說明,反而容易讓人學得累或看不懂,再嚴謹也等於什麼都沒說。(sorry,借寶地發通牢騷微笑)。教與學就象發射臺與收音機,初學者頻段很小,超出這個頻段,再大的功率也不能接收。

    適合初學的書大概有三類:

    a)高手針對某專題的淺顯闡述,要自己上網蒐集整理,書店找不到,比如CSDN的部落格:)。真正高手在民間而不是官方演講臺。

    b)IT公司內部培訓資料,公司培訓目的是為讓入職菜鳥儘快幹活,不是為出書賺錢,所以不會花心思拔高和注水。而且只有每天帶著生存壓力拼搏在一線多年的人,才能做出精煉而實用的總結。

    c)英文經典,不得不承認,英文詞語歧義較少,在科學表達方面有一定優勢,很多概念似乎只能意會不好言傳,換用英文就變得簡明準確;而且相比起來,老外在技術上也更純粹和虔誠。

    d)優秀原始碼的解析。這種書純粹圍繞程式碼解析,廢話少,實踐性強。

3.       掌握關鍵技術和節點,以點帶面

    社會快速發展,知識大爆炸時代已來臨,長期進化使人類發展到今天這個高度,但每個人在出生的那一剎那,實際上與其他動物站在幾乎同樣的起點(李笑來《把時間當做朋友》),人的生命有限,知識擴充套件的腳步卻從未停止。面對高壘的書籍和海量資訊,活到老學到老是每個人必須的選擇,即便如此,人力有時窮,必須有重點和取捨。人們對未知事物有本能地探究慾望,從小又被唸叨書到用時方恨少,於是很多人抱著不管有用沒用,多看點書總不會錯的想法東看西瞧。但別忘了學習某種程度也是投資,需要投入時間和興趣,如果每樣都嘗試以免用時恨少,只會無頭蒼蠅一樣在猶豫觀望和淺嘗輒止中浪費時間,最終走馬觀花一無所獲。然後只能厚著臉皮拼湊簡歷:熟悉”C,“學過”JAVA,“看過”linux,“用過”VC/VB。看上去一大堆,可沒底氣寫“精通”,能蒙誰呢。

    亂花漸欲迷人眼,只有擺脫各種花哨名詞和工具的誘惑,選擇和掌握關鍵核心技術,才能以從容的心態穩坐釣魚臺,俯視其他衍生技術。最優搜尋中,離目標越近,搜尋效率就越高,學習也一樣。對於技術細節,用到再學也不晚。那嵌入式的關鍵和核心是什麼呢?最基礎的C語言/作業系統!並非說C一定優於其他語言,但從學習角度只有C才能從下到上串聯和詮釋計算機體系結構、軟硬體、資料結構和演算法等。掌握C,進可攻退可守。“說穿了,用Java來取代傳統程式入門課程中使用的語言,比如CC++──無異讓整體教學水準後退了一大步。許多大學轉向Java的理由只是因為學生畢業後好找工作,但諷刺的是,這些學校培養出了僅具備膚淺技能的程式設計人才,他們正失去與具備深度知識的人才競爭的能力。(《不懂C語言?你該感到危機》),這種說法或許會引發一定爭議,但我認為反映了很大一部分現實。

    此外要特別關注不同技術模組的連線點,軟體發展過程中一個突出特點是不斷分化與融合,或者說不斷增加的層次。一個著名的玩笑“所有軟體問題都可以通過增加一箇中間層來解決”,事實也基本如此。新舊技術或層次之間需要轉換介面以相互配合,而這類轉換節點中往往就包含著雙方的一部分技術精華,很大程度影響程式設計師對系統的整體理解。比如:CC++的連線需要掌握extern C以及背後的C/C++部分編譯連線原理;C和彙編的連線需要掌握函式引數壓棧出棧以及暫存器佔用等體系結構相關呼叫規範;CJAVA需要掌握JNI的原理;C和作業系統則需要了解任務控制塊所包含的作業系統核心資料結構;C和硬體驅動則需要知道標準庫的作用以及內部實現概況。而這些關鍵點能夠描繪一張軟體系統的整體框圖,使程式設計師跳出具體技術的羈絆,具有整體視野。

4.掌握思想方法,應對潮流變遷

    橫向選擇關鍵技術,那縱向呢?IT業日新月異,任何具體技術都有時效性,前幾年流行一時的symbian現已隨著NOKIA的沒落而銷聲匿跡,廣大symbian開發者正經歷轉形的陣痛。但誰又能肯定這種痛苦不會落到目前風光的android開發者頭上?怎樣更好的適應潮流變遷,或者說哪些是變化中不變的因素呢?

    軟體領域,不同系統/語言和工具間表面上千差萬別,但它們的很多核心思想是一脈相承的。到一定火候之後,所提煉和掌握的思想方法不會隨工具和語言的變化而改變。比如某人通過C學會了雜湊表,只要他真正掌握這一思想的本質,知道它適用於哪些場合,解決哪些問題,即使轉用JAVA或其他工具,也不會丟失用雜湊表解決問題的能力。這種不依賴於具體語言和工具的思想方法才是計算機軟體真正的精華。

    但是不要奢望看幾篇文章就能真正掌握這些思想,只有在大量程式設計實踐中獲取足夠的正反面經驗,才能把前人理論融會貫通,昇華成自己的思想。有了這些,即便將來老眼昏花,也比那些只能依附於某樣特定工具的程式設計師層次來得高。

5.從歷史發展瞭解技術的演化脈絡。

    軟體發展到今天,不是靠某位天才拍腦袋想出來,而是在需求帶動發展,發展產生新需求的過程中不斷迴圈前進。也就是說,對於眼前各種複雜技術,可以回頭看看它們的出現是為了解決什麼問題,利用了怎樣的思路,經歷了怎樣從原始粗糙到精細專業的發展過程。幼年時期沒有包裝過的技術方案往往能更清楚的展示其本質思想。瞭解演化過程,掌握前因後果會大大加深對某項技術的理解,提升眼界和高度,況且歷史故事一般比單純的理論更有趣味。

6.利用網路。

    網路已逐漸成為最好的終身免費的課外老師,它正在並且會徹底改變現在的教育和學習方式。以前讀書時,有問題只能問老師,老師卻不是萬能的。現在網路上有無數萬能的名師,比如googlebaiduwiki,以及論壇中無數的高手,你的困惑往往很多人都經歷過,只要一句話就能使你茅塞頓開。要學會善用網路自己查詢問題答案,特別要關注高手的部落格和讀書筆記。意識到這種趨勢並擅加利用,會使你的成長學習快人一步

7.研究開原始碼

    世上有這樣一群人,他們開發各種優秀軟體,然後無私共享不求回報。有些開原始碼彙集了眾多高手的智慧,隱含無數巧妙,且經歷千錘百煉後,成為不朽的經典。比如作業系統領域的linux, 編譯器的gcc,圖象識別與處理的opencv,視訊編解碼的xvid/ffmpeg,加解密的openssl等,都是相關領域的聖經。

    程式碼對照理論,理解起來容易很多。多閱讀一些的優秀開源軟體,熟悉掌握常用技巧,逐漸就能胸中有丘壑。讀書破萬卷,下筆如有神嘛!So, read the fucking source code!

8.總結與積累

    讀書由薄到厚,然後由厚到薄,學習就是不斷髮現積累問題,同時解決消化問題的動態過程。總結與積累是前提,不注意積累,經驗轉眼就被遺忘,象黑瞎子掰玉米,掰一個丟一個。好記性不如爛筆頭,一個好的習慣是寫工作日記或部落格,記錄每天的收穫。每次當我回頭從筆記中看到自己在一點一滴不斷進步,那種快樂和滿足能激勵和鼓舞我在技術上不斷追求,活到老學到老。而且記錄也是總結整理和感悟的過程,往往可以從中獲得一些深層次的體悟和提高。

9.其他,如

    與同一愛好的朋友交流,從別人身上發現自己的盲區,使知識體系更全面;多閱讀英文資料與書籍,譯著一般只適合作為參考,要儘早習慣看英文手冊。另外有錢去上個培訓班比一個人苦學要快,不過培訓機構良莠不齊,要找到適合自己當前水平的正規機構。

    最後送大家四個字“學,習,思,悟”