1. 程式人生 > >嵌入式行業入門指導---知乎轉載【轉】

嵌入式行業入門指導---知乎轉載【轉】

用戶註冊 相關 java roc lcd控制器 中華 基本功 poll c語言、

此文是本人在知乎上看的,覺得很好就分享出來了,並不是本人原創

轉自:https://www.zhihu.com/question/47881392

作者:shang
鏈接:https://www.zhihu.com/question/47881392/answer/146734937
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請註明出處。

嵌入式Linux+Android學習路線圖
作者:韋東山


本文目錄
1. 程序員的三大方向
1.1 專業領域
1.1.1 學術研究
1.1.2 工程實現
1.2 業務領域
1.2.1 界面顯示
1.2.2 業務邏輯
1.3 操作系統領域

1.4 嵌入式Linux+Android系統包含哪些內容
2. 怎麽學習嵌入式Linux操作系統
2.1 入門路線圖
2.2 學習驅動程序之前的基礎知識
2.2.1 C語言
2.2.2 PC Linux基本操作:
2.2.3 硬件知識
2.2.4 要不要專門學習Windows下的單片機開發
2.2.5 為什麽選擇ARM9 S3C2440開發板,而不是其他性能更好的?
2.2.6 怎麽學習ARM+Linux的裸機開發
2.2.7 bootloader的學習
2.2.8 Linux內核的學習
2.2.9 根文件系統
2.3 驅動程序的學習
2.3.1 經典字符設備驅動程序
2.3.2 工作中各類驅動程序
2.3.3 調試方法
2.4 Linux應用程序的學習
3. 怎麽學習整個Android系統

我是1999年上的大學,物理專業。在大一時,我們班裏普遍彌漫著對未來的不安,不知道學習了物理後出去能做什麽。你當下的經歷、當下的學習,在未來的一天肯定會影響到你。畢業後我們也各自找到了自己的職業:出國深造轉行做金融、留校任教做科研、設計芯片、寫程序、創辦公司等等,這一切都離不開在校時學到的基礎技能(數學、IT、電子電路)、受過煆煉的自學能力。
所以,各位正在迷茫的在校生,各位正在嘗試轉行的程序員,未來一定有你的位置,是好是壞取決於你當下的努力與積累。

我不能預言幾年後什麽行業會熱門,也不能保證你照著本文學習可以發財。我只是一個有十幾年經驗的程序員,給對編程有興趣的你,提供一些建議。

1. 程序員的三大方向
程序員的方向,一般可以分為3類:專業領域、業務領域、操作系統領域。你了解它們後,按興趣選擇吧。
對於專業領域,我提供不了建議。
業務,也就是應用程序,它跟操作系統並不是截然分開的:
① 開發實體產品時,應用程序寫得好的人,有時候需要操作系統的知識,比如調度優先級的設置、知道某些函數可能會令進程休眠。
② 寫應用程序的人進階為系統工程師時,他需要從上到下都了解,這時候就需要有操作系統領域的知識了,否則,你怎麽設計整個系統的方案呢?
③ 做應用程序的人,需要了解行業的需求,理解業務的邏輯。所以,當領導的人,多是做應用的。一旦鉆入了某個行業,很難換行業。
④ 而操作系統領域,做好了這是通殺各行業:他只負責底層系統,在上面開發什麽業務跟他沒關系。這行很多是技術宅,行業專家。
⑤ 操作系統和業務之間並沒有一個界線。有操作系統經驗,再去做應用,你會對系統知根知底,碰到問題時都有解決思路。有了業務經驗,你再了解一下操作系統,很快就可以組成一個團隊自立門戶,至少做個CTO沒問題。
1.1 專業領域
它又可以分為下面2類。

1.1.1 學術研究
比如語音、圖像處理、人工智能,這類工作需要你有比較強的理論知識,我傾向於認為這類人是“科學家”,他們鉆研多年,很多時候是在做學術研究。
在嵌入式領域,需要把他們的成果用某種算法表達出來,針對某種芯片進行優化,這部分工作也許有專人來做。

1.1.2 工程實現
也有這樣一類人,他們懂得這些專業領域的概念,但是沒有深入鉆研。可以使用各類開源資料實現某個目標,做出產品。比如圖像處理,他懂得用opencv裏幾百個復雜函數來實現頭像識別。有時候還可以根據具體芯片來優化這些函數。
“專業領域”不是我的菜,如果你要做這一塊,我想最好的入門方法是在學校學習研究生、博士課程。

1.2 業務領域
換句話說,就是應用程序,這又可以分為下面2類。

1.2.1 界面顯示
做產品當然需要好的界面,但是,不是說它不重要,是沒什麽發展後勁。
現在的熱門詞是Android APP和IOS APP開發。你不要被Android、IOS兩個詞騙了,它們跟以前的VC、VB是同一路貨色,只是、僅僅是一套GUI控件的實現。
希望沒有冒犯到你,我有理由。
一個程序需要有GUI界面,但是程序的內在邏輯才是核心。Android、IOS的開發工具給我們簡化了GUI的開發,並提供了這些控件的交互機制,封裝並提供了一些服務(比如網絡傳輸)。
但是程序內部的業務邏輯、對視頻圖像聲音的處理等等,這才是核心。
另外別忘了服務器那邊的後臺程序:怎樣更安全地保存數據、保護客戶的隱私,怎樣處理成千上萬上百萬的並發訪問,等等,這也是核心。
但是,從Android、IOS APP入門入行,這很快!如果你是大四,急於找到一份工作,那麽花上1、2個月去學習Android或IOS,應該容易找到工作,畢竟APP的需求永遠是最大的,現在這兩門技術還算熱門。
在2011、2012年左右,Android程序員的起薪挺高,然後開始下滑。Android APP的入門基本只要1個月,所以懂的人也越來越多。
2013、2014年,IOS開發的工資明顯比Android高了,於是各類IOS培訓也火曝起來。中華大地向來不缺速成人才,估計再過一陣子IOS工程師也是白菜價了。
會Android、IOS只是基本要求,不信去51job搜搜Android或IOS,職位要求裏肯定其他要求。

1.2.2 業務邏輯
舉個簡單例子,做一個打卡軟件,你需要考慮這些東西:
① 正常流程是上班下班時都要打卡
② 有人忘記了怎麽辦?作為異常記錄在案,推送給管理員
③ 請假時怎麽處理?
④ 加班怎麽處理?
對於更復雜的例子,視頻會議系統裏,各個模塊怎麽對接,各類協議怎麽兼容,你不深入這個行業,你根本搞不清楚。
應用開發的職位永遠是最多的,入門門檻也低。基本上只要你會C語言,面試時表現比較得體,一般公司都會給你機會。因為:
① 你進公司後,還需要重新培訓你:熟悉它們的業務邏輯。
② 你要做的,基本也就是一個個模塊,框架都有人給你定好了,你去填代碼就可以了。
說點讓你高興的事:軟件公司裏,做領導的基本都是寫應用程序的(當然還有做市場的)。寫應用程序的人,對外可以研究市場接待客戶,對內可以管理程序員完成開發,不讓他做領導讓誰做?
如果你的誌向是寫應用程序,那麽我建議你先練好基本功:數據結構、算法是必備,然後憑興趣選擇數據庫、網絡編程等等進行深入鉆研。
最後,選擇你看好的、感興趣的行業深耕個10年吧。做應用開發的人選擇了某個行業,後面是很難換行業的,選行很重要!

1.3 操作系統領域
UCOS太簡單,VxWorks太貴太專業,Windows不玩嵌入式了,IOS不開源,所以對於操作系統領域我們也只能玩Linux了。
在嵌入式領域Linux一家獨大!
Android呢?Android跟QT一樣,都是一套GUI系統。只是Google的實力太強了,現在Android無處不在,所以很多時候Linux+Android成了標配。註意,在這裏我們關心的是Android的整個系統、裏面的機制,而不是學習幾個API然後開發界面程序。
操作系統領域所包含的內容,簡單地說,就是制作出一臺裝好系統的專用“電腦”,可以分為:
① 為產品規劃硬件:
按需求、性能、成本選擇主芯片,搭配周邊外設,交由硬件開發人員設計。
② 給單板制作、安裝操作系統、編寫驅動
③ 定制維護、升級等系統方案
④ 還可能要配置、安裝Android等GUI系統:
⑤ 為應用開發人員配置開發環境
⑥ 從系統角度解決疑難問題
這個領域,通常被稱為“底層系統”或是“驅動開發”。

先解決2個常見誤區:
① 這份工作是寫驅動程序嗎?
看看上面羅列的6點,應該說,它包含驅動開發,但遠遠不只有驅動開發。
② 我們還需要寫驅動嗎?不是有原廠嗎?或者只需要改改就可以?
經常有人說,芯片原廠都做好驅動了,拿過來改改就可以了。如果,你的硬件跟原廠的公板完全一樣,原廠源碼毫無BUG,不想優化性能、削減成本,不想做一些有特色的產品,那這話是正確的。
但是在這個不創新就是找死的年代,可能嗎?!原因有二:
① 即使只是修改代碼,能修改的前提是能理解;能理解的最好煆煉方法是從零寫出若幹驅動程序
② 很多時候,需要你深度定制系統。
以前做聯發科手機只需要改改界面就可以出貨了,現在山寨廠一批批倒下。大家都使用原廠的方案而不加修改時,最後只能拼成本。

舉個例子,深圳有2家做交通攝像頭、監控攝像頭的廠家,他們曾經找我做過4個項目:
① 改進廠家給的SD卡驅動性能,使用DMA。
② 換了Flash型號後,系統經常出問題,需要修改驅動BUG。
③ 觸摸屏點擊不準,找原因,後來發現是旁路電容導致的。
④ 裁減成本,把4片DDR換為2片DDR,需要改bootloader對DDR的初始化。

這些項目都很急,搞不定就無法出貨,這時候找原廠?除非你是中興華為等大客戶,否則誰理你?
我在中興公司上班時,寫驅動的時間其實是很少的,大部分時間是調試:系統調優,上幫APP工程師、下幫硬件工程師查找問題。

我們從廠家、網上得到的源碼,很多都是標準的,當然可以直接用。但是在你的產品上也許優化一下更好。比如我們可以把攝像頭驅動和DMA驅動揉合起來,讓攝像頭的數據直接通過DMA發到DSP去。

我們可以在軟件和硬件之間起橋梁作用,對於實體產品,有可能是軟件出問題也可能是硬件出問題,一般是底層系統工程師比較容易找出問題。

當硬件、軟件應用出現問題,他們解決不了時,從底層軟件角度給他們出主意,給他們提供工具。
再比如方案選擇:芯片性能能否達標、可用的BSP是否完善等等,這只能由負責整個方案的人來考慮,他必須懂底層。
在操作系統領域,對知識的要求很多:
① 懂硬件知識才能看懂電路圖
② 英文好會看芯片手冊
③ 有編寫、移植驅動程序的能力
④ 對操作系統本身有一定的理解,才能解決各類疑難問題
⑤ 理解Android內部機制
⑥ 懂匯編、C語言、C++、JAVA

它絕對是一個大坑,沒有興趣、沒有毅力的人慎選。
① 這行的入門,絕對需要半年以上,即使全天學習也要半年。
② 它的職位,絕對比APP的職位少
③ 並且你沒有1、2年經驗,招你到公司後一開始你做的還是APP。

優點就是:
① 學好後,行業通殺,想換行就換行;想自己做產品就自己做產品。
② 相比做應用程序的人,不會被經常變動的需求搞得天天加班。
③ 門檻高,當然薪水相對就高。
操作系統領域,我認為適合於這些人:
① 硬件工程師想轉軟件工程師,從底層軟件入門會比較好
② 單片機工程師,想升級一下。會Linux底層的人肯定會單片機,會單片機的人不一定會Linux。
③ 時間充足的學生:如果你正讀大二大三,那麽花上半年學習嵌入式Linux底層多有益處。
④ 想掌握整個系統的人,比如你正在公司裏寫APP,但是想升為系統工程師,那麽底層不得不學。
⑤ 想自己創業做實體產品的工程師,你有錢的話什麽技術都不用學,但是如果沒錢又想做產品,那麽Linux底層不得不學。
⑥ 做Linux APP的人,沒錯,他們也要學習。
這部分人不需要深入,了解個大概就可以:bootloader是用來啟動內核,Linux的文件系統(第1個程序是什麽、做什麽、各目錄幹嘛用)、APP跟驅動程序的調用關系、工具鏈,有這些概念就可以了

本文中,就把操作系統默認為Linux,講講怎麽學習嵌入式Linux+Android系統。

1.4 嵌入式Linux+Android系統包含哪些內容
嵌入式Linux系統包含哪些東西?不要急,舉一個例子你就知道了。
① 電腦一開機,那些界面是誰顯示的?
是BIOS,它做什麽?一些自檢,然後從硬盤上讀入windows,並啟動它。
類似的,這個BIOS對應於嵌入式Linux裏的bootloader。這個bootloader要去Flash上讀入Linux內核,並啟動它。

② 啟動windows的目的是什麽?
當然運行應用程序以便上網、聊天什麽的了。
這些上網程序、聊天程序在哪?
在C盤、D盤上。
所以,windows要先識別出C盤、D盤。在Linux下我們稱之為根文件系統。

③ windows能識別出C盤、D盤,那麽肯定有讀寫硬盤的能力。
這個能力我們稱之為驅動程序。當然不僅僅是操作硬盤,還有網卡、USB等等其他硬件。
嵌入式Linux能從Flash上讀出並執行應用程序,肯定也得有Flash的驅動程序啊,當然也不僅僅是Flash。
簡單地說,嵌入式LINUX系統裏含有bootloader、內核、驅動程序、根文件系統、應用程序這5大塊。而應用程序,我們又可以分為:C/C++、Android。
所以,嵌入式Linux+Android系統包含以下6部分內容:
① bootloader
② Linux內核
③ 驅動程序
④ 使用C/C++編寫的應用程序
⑤ Android系統本身
⑥ Android應用程序

Android跟Linux的聯系實在太大了,它的應用是如此廣泛,學習了Linux之後沒有理由停下來不學習Android。在大多數智能設備中,運行的是Linux操作系統;它上面要麽安裝有Android,要麽可以跟Android手機互聯。現在,Linux+Android已成標配。

2. 怎麽學習嵌入式Linux操作系統
本文假設您是零基礎,以實用為主,用最快的時間讓你入門;後面也會附上想深入學習時可以參考的資料。

在實際工作中,我們從事的是“操作系統”周邊的開發,並不會太深入學習、修改操作系統本身。
① 操作系統具有進程管理、存儲管理、文件管理和設備管理等功能,這些核心功能非常穩定可靠,基本上不需要我們修改代碼。我們只需要針對自己的硬件完善驅動程序
② 學習驅動時必定會涉及其他知識,比如存儲管理、進程調度。當你深入理解了驅動程序後,也會加深對操作系統其他部分的理解
③ Linux內核中大部分代碼都是設備驅動程序,可以認為Linux內核由各類驅動構成
但是,要成為該領域的高手,一定要深入理解Linux操作系統本身,要去研讀它的源代碼。

在忙完工作,閑暇之余,可以看看這些書:
① 趙炯的《linux內核完全註釋》,這本比較薄,推薦這本。他後來又出了《Linux 內核完全剖析》,太厚了,搞不好看了後面就忘記前面了。
② 毛德操、胡希明的《LINUX核心源代碼情景分析》,此書分上下冊,巨厚無比。當作字典看即可:想深入理解某方面的知識,就去看某章節。
③ 其他好書還有很多,我沒怎麽看,沒有更多建議

基於快速入門,上手工作的目的,您先不用看上面的書,先按本文學習。

2.2 學習驅動程序之前的基礎知識2.2.1 C語言
只要是理工科專業的,似乎都會教C語言。我見過很多C語言考試90、100分的,一上機就傻了,我懷疑他們都沒在電腦上寫過程序。
理論再好,沒有實踐不能幹活的話,公司招你去幹嘛?
反過來,實踐出真知,學習C語言,必須練練練、寫寫寫!
當你掌握基本語法後,就可以在電腦上練習一些C語言習題了;
當你寫過幾個C程序後,就可以進入下一階段的裸機開發了。
① 不需要太深入
作為快速入門,只要你會編寫“Hello, world!”,會寫冒泡排序,會一些基礎的語法操作,暫時就夠了。
指針操作是重點,多練習;
不需要去學習過多的數據結構知識,只需要掌握鏈表操作,其他不用學習,比如:隊列、二叉樹等等都不用學;
不需要去學習任何的函數使用,比如文件操作、多線程編程、網絡編程等等;
這些知識,在編寫Linux應用程序時會用,但是在操作系統特別是驅動學習時,用不著!
永往直前吧,以後碰到不懂的C語言問題,我們再回過頭來學習。
在後續的“裸機開發”中,會讓你繼續練習C語言,那會更實戰化。

C語言是在寫代碼中精進的。
② 可以在Visual Studio下學習,也可以在Linux下學習,後者需要掌握一些編譯命令
我們暫時沒有提供C語言的教程,找一本C語言書,網上找找免費的C語言視頻(主要看怎麽搭建環境),就可以自學了。

2.2.2 PC Linux基本操作:
對於PC Linux,我們推薦使用Ubuntu,在它上面安裝軟件非常簡便。
我們的工作模式通常是這樣:在Windows下閱讀、編寫代碼,然後把代碼上傳到PC Linux去編譯。
實際上,Ubuntu的桌面系統已經很好用了,我們拿到各種智能機可以很快上手,相信Ubuntu的桌面系統也可以讓你很快上手。

為了提高工作效率,我們通常使用命令行來操作Ubuntu。
不用擔心,你前期只需要掌握這幾條命令就可以了,它們是如此簡單,我幹脆列出它們:
① cd : Change Directory(改變目錄)
cd 目錄名 // 進入某個目錄
cd .. // cd “兩個點”:返回上一級目錄
cd - // cd “短橫”:返回上一次所在目錄

② pwd : Print Work Directory(打印當前目錄 顯示出當前工作目錄的絕對路徑)

③ mkdir : Make Directory(創建目錄)
mkdir abc // 創建文件夾abc
mkdir -p a/b/c // 創建文件夾a,再a下創建文件夾b,再在b下創建文件夾c

④ rm : Remove(刪除目錄或文件)
rm file // 刪除名為file的文件
rm -rf dir // 刪除名為dir的目錄

⑤ ls : List(列出目錄內容)

⑥ mount : 掛載
mount -t nfs -o nolock,vers=2 192.168.1.123:/work/nfs_root /mnt
mount -t yaffs /dev/mtdblock3 /mnt

⑦ chown : Change owner(改變文件的屬主,即擁有者)
chown book:book /work -R // 對/work目錄及其下所有內容,屬主改為book用戶,組改為book

⑧ chmod : Change mode(改變權限),下面的例子很簡單粗暴
chmod 777 /work -R // 對/work目錄及其下所有內容,權限改為可讀、可寫、可執行

⑨ vi : Linux下最常用的編輯命令,使用稍微復雜,請自己搜索用法。
要練習這些命令,你可以進入Ubuntu桌面系統後,打開終端輸入那些命令;或是用SecureCRT、putty等工具遠程登錄Ubuntu後練習。

2.2.3 硬件知識
我們學習硬件知識的目的在於能看懂原理圖,看懂通信協議,看懂芯片手冊;不求能設計原理圖,更不求能設計電路板。
對於正統的方法,你應該這樣學習:
① 學習《微機原理》,理解一個計算機的組成及各個部件的交互原理。
② 學習《數字電路》,理解各種門電路的原理及使用,還可以掌握一些邏輯運算(與、或等)。
③ 《模擬電路》?好吧,這個不用學,至少我在工作中基本用不到它,現在全忘光了。
就我個人經驗來說,這些課程是有用的,但是:
① 原理有用,實戰性不強。
比如《微機原理》是基於x86系統,跟ARM板子有很大差別,當然原理相通。
我是在接觸嵌入式編程後,才理解了這些課程。
② 每本書都那麽厚,內容都很多,學習時間過長,自學有難度。

針對這些校園教材的不足,並結合實際開發過程中要用到的知識點,我們推出了《學前班_怎麽看原理圖》的系列視頻:
學前班第1課第1節_怎麽看原理圖之GPIO和門電路.wmv
學前班第1課第2.1節_怎麽看原理圖之協議類接口之UART.wmv
學前班第1課第2.2節_怎麽看原理圖之協議類接口之I2C.wmv
學前班第1課第2.3節_怎麽看原理圖之協議類接口之SPI.wmv
學前班第1課第2.4節_怎麽看原理圖之協議類接口之NAND Flash.wmv
學前班第1課第2.5節_怎麽看原理圖之協議類接口之LCD.wmv
學前班第1課第3節_怎麽看原理圖之內存類接口.wmv
學前班第1課第4.1節_怎麽看原理圖之分析S3C2410開發板.wmv
學前班第1課第4.2節_怎麽看原理圖之分析S3C2440開發板.wmv
學前班第1課第4.3節_怎麽看原理圖之分析S3C6410開發板.wmv
即使你只具備初中物理課的電路知識,我也希望能通過這些視頻,讓你可以看懂原理圖,理解一些常見的通信協議;如果你想掌握更多的硬件知識,這些視頻也可以起個索引作用,讓你知道缺乏什麽知識。
這些視頻所講到的硬件知識,將在《裸板開發》系列視頻中用到,到時可以相互對照著看,加深理解。

2.2.4 要不要專門學習Windows下的單片機開發
很多學校都開通了單片機的課程,很多人都是從51單片機、AVR單片機,現在比較新的STM32單片機開始接觸嵌入式領域,並且使用Windows下的開發軟件,比如keil、MDK等。
問題來了,要不要專門學習Windows下的單片機開發?
① 如果這是你們專業的必修課,那就學吧
② 如果你的專業跟單片機密切相關,比如機械控制等,那就學吧
③ 如果你只是想從單片機入門,然後學習更廣闊的嵌入式Linux,那麽放棄在Windows下學習單片機吧!

理由如下:
① Windows下的單片機學習,深度不夠
Windows下有很好的圖形界面單片機開發軟件,比如keil、MDK等。
它們封裝了很多技術細節,比如:
你只會從main函數開始編寫代碼,卻不知道上電後第1條代碼是怎麽執行的;
你可以編寫中斷處理函數,但是卻不知道它是怎麽被調用的;
你不知道程序怎麽從Flash上被讀入內存;
也不知道內存是怎麽劃分使用的,不知道棧在哪、堆在哪;
當你想裁剪程序降低對Flash、內存的使用時,你無從下手;
當你新建一個文件時,它被自動加入到工程裏,但是其中的機理你完全不懂;
等等等。

② 基於ARM+Linux裸機學習,可以學得更深,並且更貼合後續的Linux學習。
實際上它就是Linux下的單片機學習,只是一切更加原始:所有的代碼需要你自己來編寫;哪些文件加入工程,需要你自己來管理。
在工作中,我們當然傾向於使用Windows下更便利的工具,但是在學習階段,我們更想學習到程序的本質。

一切從零編寫代碼、管理代碼,可以讓我們學習到更多知識:
你需要了解芯片的上電啟動過程,知道第1條代碼如何運行;
你需要掌握怎麽把程序從Flash上讀入內存;
需要理解內存怎麽規劃使用,比如棧在哪,堆在哪;
需要理解代碼重定位;
需要知道中斷發生後,軟硬件怎麽保護現場、跳到中斷入口、調用中斷程序、恢復現場;
你會知道,main函數不是我們編寫的第1個函數;
你會知道,芯片從上電開始,程序是怎麽被搬運執行的;
你會知道,函數調用過程中,參數是如何傳遞的;
你會知道,中斷發生時,每一個寄存器的值都要小心對待;
等等等。

你掌握了ARM+Linux的裸機開發,再回去看Windows下的單片機開發,會驚呼:怎麽那麽簡單!並且你會完全明白這些工具沒有向你展示的技術細節。
驅動程序=Linux驅動程序軟件框架+ARM開發板硬件操作,我們可以從簡單的裸機開發入手,先掌握硬件操作,並且還可以:
① 掌握如何在PC Linux下編譯程序、把程序燒錄到板子上並運行它
② 為學習bootloader打基礎:掌握了各種硬件操作後,後面一組合就是一個bootloader

2.2.5 為什麽選擇ARM9 S3C2440開發板,而不是其他性能更好的?
有一個錯誤的概念:S3C2440過時了、ARM9過時了。
這是不對的,如果你是軟件工程師,無論是ARM9、ARM11、A8還是A9,對我們來說是沒有差別的。

一款芯片,上面有CPU,還有眾多的片上設備(比如UART、USB、LCD控制器)。我們寫程序時,並不涉及CPU,只是去操作那些片上設備。
所以:差別在於片上設備,不在於CPU核;差別在於寄存器操作不一樣。
因為我們寫驅動並不涉及CPU的核心,只是操作CPU之外的設備,只是讀寫這些設備的寄存器。
之所以推薦S3C2440,是因為它的Linux學習資料最豐富,並有配套的第1、2期視頻。

2.2.6 怎麽學習ARM+Linux的裸機開發
學習裸機開發的目的有兩個:
① 掌握裸機程序的結構,為後續的u-boot作準備
② 練習硬件知識,即:怎麽看原理圖、芯片手冊,怎麽寫代碼來操作硬件
後面的u-boot可以認為是裸機程序的集合,我們在裸機開發中逐個掌握各個部件,再集合起來就可以得到一個u-boot了。
後續的驅動開發,也涉及硬件操作,你可以在裸機開發中學習硬件知識。

註意:如果你並不關心裸機的程序結構,不關心bootloader的實現,這部分是可以先略過的。在後面的驅動視頻中,我們也會重新講解所涉及的硬件知識。
推薦兩本書:杜春蕾的《ARM體系結構與編程》,韋東山的《嵌入式Linux應用開發完全手冊》。後者也許是國內第1本涉及在PC Linux環境下開發的ARM裸機程序的書,如果我說錯了,請原諒我書讀得少。

對於裸機開發,我們提供有2部分視頻:
① 環境搭建
第0課第1節_剛接觸開發板之接口接線.wmv
第0課第2節_剛接觸開發板之燒寫裸板程序.wmv
第0課第3節_剛接觸開發板之重燒整個系統.wmv
第0課第4節_剛接觸開發板之使用vmwae和預先做好的ubuntu.wmv
第0課第5節_剛接觸開發板之u-boot打補丁編譯使用及建sourceinsight工程.wmv
第0課第6節_剛接觸開發板之內核u-boot打補丁編譯使用及建sourceinsight工程.wmv
第0課第7節_剛接觸開發板之制作根文件系統及初試驅動.wmv
第0課第8節_在TQ2440,MINI2440上搭建視頻所用系統.wmv
第0課第9節_win7下不能使用dnw燒寫的替代方法.wmv

② 裸機程序開發
第1課 環境搭建及工具、概念介紹.wmv
第2課 GPIO實驗.wmv
第3課 存儲管理器實驗.wmv
第4課 MMU實驗.wmv
第5課 NAND FLASH控制器.wmv
第6課 中斷控制器.wmv
第7課 系統時鐘和UART實驗.wmv
第8課 LCD實驗.wmv

要聲明的是:
錄制上述《裸機程序開發》視頻時,本意是結合《嵌入式Linux應用開發完全手冊》的《第2篇 ARM9嵌入式系統基礎實例篇》來講解,所以視頻裏沒有完全從零編寫代碼,需要結合書本來學習。
① 書和視頻並不是完全配套的,不要照搬,其中的差異並不難解決。
《嵌入式Linux應用開發完全手冊》發表於2008年,使用了很多款開發板,並且那時的開發板配置較低(Nand Flash是64M);
《裸機程序開發》視頻使用JZ2440開發板錄制。
② 書和視頻,適用於所有S3C2440開發板,包括mini2440、tq2440等
天下S3C2440配置都是相似的,基本也就是LED、按鍵所用引腳不同,LCD型號不同;你學習了書、視頻,如果連這些差異都搞不定的話,那就是你我的失敗了。
學習方法是這樣的:
① 先看《環境搭建》視頻來搭建開發環境
② 書(第2篇)和視頻(裸機程序開發)結合,看完一章,練習一章
一定要編寫代碼,即使是照抄也要寫。
③ 如果對於ARM架構相關的知識,覺得模糊或是想了解得更深入,參考《ARM體系結構與編程》
學習程度:
① 理解一個裸機程序的必要結構:異常向量、硬件初始化、代碼重定位、棧
② 知道如何操作GPIO、Flash、LCD、觸摸屏等硬件
③ 很多人覺得MMU難以理解,可以放過它

2.2.7 bootloader的學習
bootloader有很多種,vivi、u-boot等等,最常用的是u-boot。
u-boot功能強大、源碼比較多,對於編程經驗不豐富、閱讀代碼經驗不豐富的人,一開始可能會覺得難以掌握。
但是,u-boot的主要功能就是:啟動內核。它涉及:讀取內核到內存、設置啟動參數、啟動內核。按照這個主線,我們嘗試自己從零編寫一個bootloader,這個程序相對簡單,可以讓我們快速理解u-boot主要功能的實現。
從零編寫bootloader的視頻有:
畢業班第1課第1.1節_自己寫bootloader之編寫第1階段.wmv
畢業班第1課第1.2節_自己寫bootloader之編寫第2階段.wmv
畢業班第1課第2節_自己寫bootloader之編譯測試.wmv
畢業班第1課第3節_自己寫bootloader之改進.wmv
分析u-boot 1.1.6的視頻有:
第9課第1節 u-boot分析之編譯體驗.wmv
第9課第2節 u-boot分析之Makefile結構分析.wmv
第9課第3節 u-boot分析之源碼第1階段.wmv
第9課第3節 u-boot分析之源碼第2階段.wmv
第9課第4節 u-boot分析之u-boot命令實現.wmv
第9課第5節 u-boot分析_uboot啟動內核.wmv
移植一個全新u-boot的視頻有:
畢業班第2課第1節_移植最新u-boot之初試.wmv
畢業班第2課第2.1節_移植最新u-boot之分析啟動過程之概述.wmv
畢業班第2課第2.2節_移植最新u-boot之分析啟動過程之內存分布.wmv
畢業班第2課第2.3節_移植最新u-boot之分析啟動過程之重定位.wmv
畢業班第2課第3.1節_移植最新u-boot之修改代碼之建新板_時鐘_SDRAM_UART.wmv
畢業班第2課第3.2節_移植最新u-boot之修改代碼支持NAND啟動.wmv
畢業班第2課第3.3節_移植最新u-boot之修改代碼支持NorFlash.wmv
畢業班第2課第3.4節_移植最新u-boot之修改代碼支持NandFlash.wmv
畢業班第2課第3.5節_移植最新u-boot之修改代碼支持DM9000網卡.wmv
畢業班第2課第4.1節_移植最新u-boot之裁剪和修改默認參數.wmv
畢業班第2課第4.2節_移植最新u-boot支持燒寫yaffs映象及制作補丁.wmv

《嵌入式Linux應用開發完全手冊》上對u-boot的講解有如下章節:
15.1 Bootloader簡介
15.1.1 Bootloader的概念
15.1.2 Bootloader的結構和啟動過程
15.1.3 常用Bootloader介紹
15.2 U-Boot分析與移植
15.2.1 U-Boot工程簡介
15.2.2 U-Boot源碼結構
15.2.3 U-Boot的配置、編譯、連接過程
15.2.4 U-Boot的啟動過程源碼分析
15.2.5 U-Boot的移植
15.2.6 U-Boot的常用命令
15.2.7 使用U-Boot來執行程序

學習方法如下:
① 先學習《從零編寫bootloader的視頻》,這可以從最少的代碼理解bootloader的主要功能
② 再看書上對u-boot的講解,並結合《分析u-boot 1.1.6的視頻》來理解
③ 最後,有時間有興趣的話,看《移植一個全新u-boot的視頻》,這不是必須的。
學習程度:
① 理解u-boot的啟動過程,特別是u-boot代碼重定位:怎麽從Flash上把自己讀入內存
② 理解u-boot的核心:命令
③ 知道bootloader如何給內核傳遞參數
④ 知道bootloader是根據“bootcmd”指定的命令啟動內核
⑤ 作為入門:只求理解,不要求能移植u-boot

2.2.8 Linux內核的學習
前面說過,內核本身不是我們學習的重點,但是了解一下內核的啟動過程,還是很有必要的:工作中有可能要修改內核以適配硬件,掌握了啟動過程才知道去修改哪些文件。
分析內核的視頻有:
第10課第1節 內核啟動流程分析之編譯體驗.wmv
第10課第2節 內核啟動流程分析之配置.wmv
第10課第3節 內核啟動流程分析之Makefile.wmv
第10課第4節 內核啟動流程分析之內核啟動.wmv
移植內核的視頻有:
畢業班第3課第1節_移植3.4.2內核之框架介紹及簡單修改.wmv
畢業班第3課第2節_移植3.4.2內核之修改分區及制作根文件系統.wmv
畢業班第3課第3節_移植3.4.2內核之支持yaffs文件系統.wmv
畢業班第3課第4節_移植3.4.2內核之裁剪及ECC簡介及制作補丁.wmv

《嵌入式Linux應用開發完全手冊》上對內核的講解有如下章節:
16.1 Linux版本及特點
16.2 Linux移植準備
16.2.1 獲取內核源碼
16.2.2 內核源碼結構及Makefile分析
16.2.3 內核的Kconfig分析
16.2.4 Linux內核配置選項
16.3 Linux內核移植
16.3.1 Linux內核啟動過程概述
16.3.2 修改內核以支持S3C2410/S3C2440開發板
16.3.3 修改MTD分區
16.3.4 移植YAFFS文件系統
16.3.5 編譯、燒寫、啟動內核

學習方法如下:
① 先看書,並結合《分析內核的視頻》進行理解
② 如果有興趣,再根據《移植內核的視頻》自己掌握移植內核,這不是必須的
學習程度:
① 知道機器ID的作用,根據機器ID找到單板對應的文件
② 知道Makefile、Kconfig的作用,知道怎麽簡單地配置內核
③ 知道怎麽修改分區
④ 作為入門:只求理解,不要求能移植

2.2.9 根文件系統
在驅動程序開發階段,我們喜歡搭建一個最小根文件系統來調試驅動;
在開發應用程序時,也需要搭建文件系統,把各種庫、配置文件放進去;
在發布產品時,你還需要修改配置文件,使得產品可以自動運行程序;
甚至你想實現插上U盤後自動啟動某個程序,這也要要修改配置文件;
這一切,都需要你理解根文件系統的構成,理解內核啟動後是根據什麽配置文件來啟動哪些應用程序。

分析根文件系統的視頻有:
第11課第1節 構建根文件系統之啟動第1個程序.wmv
第11課第2節 構建根文件系統之init進程分析.wmv
第11課第3節 構建根文件系統之busybox.wmv
第11課第4節 構建根文件系統之構建根文件系統.wmv

《嵌入式Linux應用開發完全手冊》上對文件系統的講解有如下章節:
17.1 Linux文件系統概述
17.1.1 Linux文件系統的特點
17.1.2 Linux根文件系統目錄結構
17.1.3 Linux文件屬性介紹
17.2 移植Busybox
17.2.1 Busybox概述
17.2.2 init進程介紹及用戶程序啟動過程
17.2.3 編譯/安裝Busybox
17.3 使用glibc庫
17.3.1 glibc庫的組成
17.3.2 安裝glibc庫
17.4 構建根文件系統
17.4.1 構建etc目錄
17.4.2 構建dev目錄
17.4.3 構建其他目錄
17.4.4 制作/使用yaffs文件系統映象文件
17.4.5 制作/使用jffs2文件系統映象文件

學習方法:結合書和視頻學習。
學習程序:
① 理解配置文件的作用
② 知道根文件系統中lib裏的文件來自哪裏
③ 可以制作、燒寫文件系統映象文件
2.3 驅動程序的學習
《嵌入式Linux應用開發完全手冊》對驅動程序的講解不多,我們推出的“韋東山Linux視頻第2期_驅動現場編寫調試”,可以認為完全脫離了書本。
所以,驅動程序的學習完全按照視頻來就可以了。
第2期的視頻,對每一個驅動,先講解硬件原理,然後從零寫代碼,從簡單到復雜,逐漸完善它的功能。
我們不會羅列專業術語,會參考日常生活的例子,力爭用最形象的比喻讓你輕松入門,同時又會很深入。

註意:我們可以讓你入門時很輕松,但是要深入理解的話,這需要你跟著視頻練習代碼,這是個要慢慢思考的過程,不會輕松。

輕松的話,憑什麽拿高工資?
再次申明:即使照抄也要寫代碼!很多人視頻看得很高興,但是寫代碼時就傻了。

2.3.1 經典字符設備驅動程序
視頻中以LED、按鍵驅動為例,講解並練習開發過程中碰到的機制:查詢、休眠-喚醒、中斷、異步通知、poll、同步、互斥等等。
後續更復雜的驅動程序,就是在這些機制的基礎上,根據硬件特性設計出精巧的軟件框架。
相關的視頻有(文件名中帶“_P”的屬於第2期加密視頻):
第12課第1節 字符設備驅動程序之概念介紹.wmv
第12課第2.1節 字符設備驅動程序之LED驅動程序_編寫編譯.wmv
第12課第2.2節 字符設備驅動程序之LED驅動程序_測試改進.wmv
第12課第2.3節 字符設備驅動程序之LED驅動程序_操作LED.wmv
第12課第3節 字符設備驅動程序之查詢方式的按鍵驅動程序.wmv
第12課第4.1節 字符設備驅動程序之中斷方式的按鍵驅動_Linux異常處理結構.wmv
第12課第4.2節 字符設備驅動程序之中斷方式的按鍵驅動_Linux中斷處理結構.wmv
第12課第4.3節 字符設備驅動程序之中斷方式的按鍵驅動_編寫代碼.wmv
第12課第5節 字符設備驅動程序之poll機制.wmv
第12課第6節 字符設備驅動程序之異步通知.wmv
第12課第7節 字符設備驅動程序之同步互斥阻塞.wmv
第12課第8節 字符設備驅動程序之定時器防抖動_P.wmv
第13課第1節 輸入子系統概念介紹_P.wmv
第13課第2節 輸入子系統第編寫驅動程序_P.wmv

《嵌入式Linux應用開發完全手冊》上對字符設備驅動程序的講解有如下章節:
第19章 字符設備驅動程序
19.1 Linux驅動程序開發概述
19.1.1 應用程序、庫、內核、驅動程序的關系
19.1.2 Linux驅動程序的分類和開發步驟
19.1.3 驅動程序的加載和卸載
19.2 字符設備驅動程序開發
19.2.1 字符設備驅動程序中重要的數據結構和函數
19.2.2 LED驅動程序源碼分析
第20章 Linux異常處理體系結構
20.1 Linux異常處理體系結構概述
20.1.1 Linux異常處理的層次結構
20.1.2 常見的異常
20.2 Linux中斷處理體系結構
20.2.1 中斷處理體系結構的初始化
20.2.2 用戶註冊中斷處理函數的過程
20.2.3 中斷的處理過程
20.2.4 卸載中斷處理函數
20.3 使用中斷的驅動程序示例
20.3.1 按鍵驅動程序源碼分析
20.3.2 測試程序情景分析

學習方法:
① 沿著數據流向,從應用程序的對驅動程序的使用進行情景分析。
所謂情景分析,就是假設應用程序發起某個操作,你去分析其中的運作過程。比如應程序調用open、read、ioctl等操作時涉及驅動的哪些函數調用。
你要思考一個問題:一個應用程序,怎麽獲得按鍵信息,怎麽去控制LED。把其中數據的流向弄清楚了,對字符驅動程序也就基本理解了。
② 學習異常和中斷時,可以結合書和視頻;對於驅動程序中其他內容的學習,可以不看書。

2.3.2 工作中各類驅動程序
我們的視頻中講解的驅動程序非常多,目的有二:
① 在你工作中遇到同類驅動時提供借鑒
② 供你學習、練習,煆煉閱讀驅動程序的“語感”,提升編寫程序的能力,增加調試經驗
我們還打算擴充驅動視頻,把它打造成“Linux驅動程序大全”視頻,基本上都會采取從零現場編寫的方式。
也許有人說:在工作中我們基本上只是移植、修改驅動而已,很少從頭編寫。這話沒錯,但是能修改的前提是理解;想更好地理解,最好的方法是從零寫一個出來。在學習階段,不要怕耗費太多時間,從零開始編寫,慢慢完善它,在這過程中你既理解了這個驅動,也煆煉了能力,做到觸類旁通。
如果有時間,建議你學完這些所有的視頻,直到你自認為:
① 給你一個新板,你可以很快實現相關驅動
② 給你一個新硬件,你可以很快給它編寫/移植驅動。
我們錄制的視頻很多,下面只羅列到“課”,不羅列到“節”。
第2期視頻:
第14課 驅動程序分層分離概念_總線驅動設備模型
第15課 LCD驅動程序
第16課 觸摸屏驅動程序
第17課 USB驅動程序
第18課 塊設備驅動程序
第19課 NAND FLASH驅動程序
第20課 NOR FLASH驅動程序
第21課 網卡驅動程序
第22課 移植DM9000C驅動程序
第23課 I2C設備裸板程序
第24課 I2C驅動程序 (不看此課,看第32課,第32課講得更好)
第26課 聲卡驅動程序 (不看此課,看第3期的ALSA驅動,那講得更好)
第27課 DMA驅動程序
第28課 hotplug_uevent機制
第32課 3.4.2內核下的I2C驅動程序
第3期的驅動視頻:
攝像頭驅動_虛擬驅動vivi
攝像頭驅動_USB攝像頭
攝像頭驅動_CMOS攝像頭
WIFI網卡驅動程序移植
3G網卡驅動程序移植
ALSA聲卡驅動程序

學習方法:
① 再次強調,不能光看不練:一定要寫程序,即使照抄也得寫
② 必學:LCD、觸摸屏、NAND Flash、Nor Flash、hotplug_uevent機制
③ 學完之後,強烈建議換一個不同的開發板,嘗試在新板上寫驅動程序。
按視頻學習會一切順利,很多問題你可能沒想到、沒想通,換一個新板會讓你真正掌握。

2.3.3 調試方法
有一種說法,程序是三分寫七分調,我們從操作系統的角度提供了一些很有用的調試方法。
相關的視頻有:
第29課第1節_裸板調試之點燈法_P.wmv
第29課第2節_裸板調試之串口打印及棧初步分析_P.wmv
第29課第3.1節_裸板調試之JTAG原理_P.wmv
第29課第3.2節_裸板調試之JTAG調試體驗_P.wmv
第29課第3.3節_裸板調試之JTAG調試命令行調試_P.wmv
第29課第3.4節_裸板調試之JTAG調試源碼級調試_P.wmv
第30課第1.1節_驅動調試之printk的原理_P.wmv
第30課第1.2節_驅動調試之printk的使用_P.wmv
第30課第1.3節_驅動調試之打印到proc虛擬文件_P.wmv
第30課第2.1節_驅動調試之段錯誤分析_根據pc值確定出錯的代碼位置_P.wmv
第30課第2.2節_驅動調試之段錯誤分析_根據棧信息確定函數調用過程_P.wmv
第30課第3節_驅動調試之自制工具_寄存器編輯器_P.wmv
第30課第4節_驅動調試之修改系統時鐘中斷定位系統僵死問題_P.wmv
第31課第1節_應用調試之使用strace命令跟蹤系統調用_P.wmv
第31課第2節_應用調試之使用gdb和gdbserver_P.wmv
第31課第3節_配置修改內核打印用戶態段錯誤信息_P.wmv
第31課第4.1節_應用調試之自制系統調用_P.wmv
第31課第4.2節_應用調試之使用自制的系統調用_P.wmv
第31課第5.1節_應用調試之輸入模擬器之設計思路_P.wmv
第31課第5.2節_應用調試之輸入模擬器之編寫保存功能_P.wmv
第31課第5.3節_應用調試之輸入模擬器之編寫測試模擬功能_P.wmv

2.4 Linux應用程序的學習
對於大多數人來說,第1個C程序是在Windows的Visual Studio C++(簡稱VC)上寫的,所以你們關心的也許是:嵌入式Linux應用程序,跟VC應用程序之間的區別:

① 編譯方法不同:
在VC上點點鼠標即可編譯,對於嵌入式Linux應用程序,我們需要“交叉編譯”:程序要在PC Linux上編譯,但是運行時要放到單板上。
並且,它的編譯環境需要你自己搭建:解壓出工具鏈後設計PATH,還要自己構造一套Makefile系統。
② 調試方法不同:
在VC上點點鼠標就可以調試,對於嵌入式Linux應用程序,你可以更喜歡用打印;或是在PC Linux上通過GDB觀察應用程序在單板上的運行狀況。

③ 可用的資源不同:
對於VC程序,你可以直接使用微軟公司提供的各種類庫;對於嵌入式Linux應用程序,很多時候需要去尋找、下載、編譯、使用開源庫。

④ 功能不同:
VC程序運行在PC上,一般是用來解決某些純軟件的問題,比如整理數據、修圖、聯網播放音樂之類。嵌入式Linux應用程序一般都要操作若幹種硬件,比如監控設備中要操作攝像頭、存儲音視頻,無人機中要操作GPS、螺旋槳,POS機中要操作銀行卡等等。它跟單板上的硬件聯系很大,很多時候需要你懂點硬件知識,至少是知道怎麽通過驅動程序來操作這些硬件。

上述4點的不同,花很少的時間就可以掌握。
如果你有誌於開發應用程序,那麽一定要有算法、數據結構、網絡編程等基礎,然後再掌握一些設計模式,最後就是多參加一些實際項目的開發了。
基於我們提供的視頻,你可以這樣學習:

① 先掌握第1期講解的根文件系統:
在後續學習中你會經常構建根文件系統,比如往裏面添加庫、修改配置文件讓你的程序自動運行。
② 掌握怎麽編譯、燒寫u-boot、內核:
在實際工作中,一般來說不需要你去燒寫u-boot、內核,但是在自學階段還是自己掌握吧,免得去麻煩別人。
按開發板手冊即可操作,你甚至不用管裏面的原理。

③ 掌握Makefile:
可以看如下第3期視頻,以後編譯程序時只要執行make命令即可:
第1課第4節_數碼相框_編寫通用的Makefile
④ 學習第1個項目:數碼相框
該項目不使用任何開源的GUI項目,完全是自己構建一套GUI系統,實現了文件瀏覽、文件顯示(文本和圖片)、圖片操作(放大、縮小、自動播放)等功能;涉及網絡編程、多線程編程、開源庫使用等等。

雖然數碼相框作為一個產品已經落伍了,但是該項目所涉及的技術,特別是以面向對象的編程思想設計出一個模塊化的、易擴展的系統,非常適合沒有大型項目開發經驗的人。很多同學,都是根據該項目所教會的編程思想找到了心怡的工作。

第3期視頻取名為“項目開發”,而非“應用開發”,它的第2、3個項目跟內核、驅動耦合很大。如果只關心應用開發,或是急於找一份工作,可以先看第1個項目。
第2個項目涉及攝像頭、ALSA聲卡、WIFI網卡、3G網卡,這些都是在實際工作過程中經常用到的設備,比如我們後面補充的QQ物聯就用到攝像頭、聲卡、WIFI網卡。
第3個項目是電源管理,講解怎麽講你的單板休眠以省電。
編輯於 2017-02-16

嵌入式行業入門指導---知乎轉載【轉】