1樓:陽光勾勒淺笑
韋東山:6000字長文告訴你如何學習嵌入式linux
原文連結:網頁連結
我在100ask_imx6ull售後群裡,發現很多初學者只有微控制器基礎,甚至沒有微控制器基礎。在學習linux時,對很多概念比較陌生,導致不知道學什麼,也不知道學了之後有什麼用。所以我趁著五一假期,編寫此文。
所有的電子產品,所用技術都可以認為要麼是微控制器,要麼是linux;gui方面主要是qt/android,它們都是執行於linux之上的。
也許你不服!不是還有ucos、vxwork、wince、ios嗎?下面這個圖是關於作業系統的佔比,是2023年的,我沒找到更新的圖,但是很有參考意義:
我們說的微控制器不使用作業系統,在上圖中沒有體現出來。但是使用微控制器裝置肯定遠遠超過linux。很多人也是先學習微控制器,從微控制器進入電子工程師行業
日常生活中,有哪些產品使用微控制器、linux呢?下面舉一些例子:
我們設計一個產品時,是使用微控制器還是linux,取決於成本:硬體成本、軟體成本、維護成本、升級成本。而不應該根據個人偏好來選擇:
我喜歡微控制器,所以就排斥使用linux;我喜歡linux,就排斥使用微控制器。為了有更多的選擇,我們需要既懂微控制器,又懂linux。
以點燈為例,
無論是微控制器還是linux,我們要做的事情都一樣:
① 看原理圖,確定引腳是哪一個,確定它輸出什麼電平才可以
② 看晶片手冊,確定要怎麼操作暫存器
③ 寫程式
但是,怎麼編寫程式,微控制器和linux有很大不同。
使用微控制器開發程式時,我們一上來就寫一個main函式,下面是一些簡化的**:
led程式裡面的init_led、led_on、led_off函式是你一個人寫的,愛取什麼名就取什麼名,愛怎麼寫就怎麼寫。
lcd程式裡的函式也是你寫的,完全是自由發揮。
很多微控制器專案不是很複雜,2、3個人從上到下統統搞定,裡面的函式大多時間是直接去讀寫暫存器。
很多微控制器專案嚴重依賴於硬體,換一個晶片後怎麼辦?重寫一套**唄。
在微控制器程式裡,沒有應用程式、驅動程式的概念,很可能一個人包攬了硬體設計、模組除錯(或稱之為驅動)、功能開發(或稱之為應用)的全部活。
在linux中,不允許應用開發人員直接去操作硬體,比如你想點個燈,不好意思,你無法直接訪問暫存器;你需要通過驅動程式來訪問暫存器。
為什麼?有幾大原因:
① linux系統中執行著眾多程式,必須保證質量差的程式無法破壞系統:
假設你寫的程式比較爛,那我不能讓你去隨便訪問暫存器,把系統搞崩潰了怎麼辦?你本意是去點燈,但是你看錯了暫存器,你把電源關了怎麼辦?
所以這些操作硬體的活,還是交給信得過的人來做吧:交給驅動工程師,他既懂硬體又懂軟體。
② 保證程式的可移植性:
編寫應用程式時,大家都使用統一的函式,以後換一個晶片時,應用程式不用變;只需要根據這個介面提供驅動程式就可以了。
③ 團隊協作:
使用linux系統的專案一般比較大,術業有專攻,一個人不太可能從上到下都全部掌握。比如做人臉識別專案,有擅長做影象處理的,他可不管你要用多少種攝像頭,有影象給他就可以。而多種攝像頭的硬體操作方法各有不同,這些交給驅動程式工程師。
所以,在linux中應用程式和驅動程式是分開的。
以led、lcd程式為例,簡化的**如下:
也許你已經大概猜出來了,應用程式怎麼呼叫驅動程式?通過標準的介面:
①open:
開啟驅動程式。
② read/write:
讀、寫資料。
③ ioctl:
傳入各種引數,獲得各種引數。
④ mmap:
記憶體對映,比如對映之後,應用程式可以直接讀寫lcd的視訊記憶體。
你看!從這些介面裡,我們根本看不到暫存器的操作。底層的程式驅動會根據這些呼叫,去設定暫存器、操作硬體。
所以,我高大上的應用工程師,幹嘛苦哈哈地去看原理圖、看在片手冊、讀寫暫存器,搞不好還要去除錯硬體bug。這些髒活、累活就交給驅動工程師吧。客戶的需求千變萬化,我996時間都不夠用了。
切,我上懂軟體、下懂硬體的驅動工程師,肯定不能把這麼重要的活交給你去做了,把我的系統搞崩潰了怎麼辦。
開玩笑、開玩笑、開玩笑的,有應用工程師、驅動工程師的優劣之分,大家都是為了做出產品。現在有一個趨勢,一個任務從上到下你都需要懂,這就是所謂的全棧工程師。
還是以led為例,應用程式和驅動程式的協作如下圖所示:
在linux中,「一切皆檔案」,要訪問某個硬體,也是要開啟檔案、讀寫檔案。應用程式要根據標準的檔案介面:open/read/write/ioctl/mmap等來訪問驅動程式。
用***_open、***_write來構成一個驅動程式,這就是驅動框架。
怎麼實現這些***_open、***_write函式?我們要做的事情跟微控制器是類似的,一樣要去看電路圖、看晶片手冊,然後在這些函式裡讀寫暫存器:這稱為硬體操作。
所以,linux驅動程式= 驅動框架 + 硬體操作。
有微控制器基礎的人,對硬體操作比較熟悉了,把重點放在驅動框架上就可以。
高能預警:驅動框架可不簡單,對於led來說是簡單,但是還有更復雜的驅動程式,它要考慮「通用」,這很要命。
這幾天在群裡跟學員聊天,有一位學員的學習方法很好:先觀其廣,再究其深。有時候要「不求甚解」,很多時候保持疑問先學下去,這些疑問就自然解決了。
比如課程中涉及彙編知識,如果你要徹底弄清楚,你需要去學習《arm架構與程式設計》;當你學完這本書,你的同學搞不好已經可以上手工作了。
我們先把學習目標定下來:快速瞭解嵌入式linux開發的流程,知道要學什麼,具備跟從業者交流的能力。
下面我們用類比和邏輯推匯出嵌入式linux系統的組成,沒錯,「推導」。
從上圖可以知道:
① 租成:
嵌入式linux系統
② bootloader:
它的目的是啟動核心,去哪等讀核心?讀到**?去flash等外設讀核心,存到記憶體裡去。所以需要有flash裡外設的驅動能力,為了除錯方便還會有網路功能。
所以,可以認為 booloader = 裸機集合,它就是一個複雜的微控制器程式。
③ linux核心
不僅如此,linux核心還有程序排程能力、記憶體管理等功能。
所以:linux核心 = 驅動集合 + 程序排程 + 記憶體管理等。
bootloader有很多種,常用的叫作u-boot。
在實際工作中,對於u-boot基本上是修修改改,甚至不改。但是u-boot本身是很複雜的,比如為了便於除錯,它支援網路功能;有些核心是儲存在fat32分割槽裡,於是它要能解析fat32分割槽,讀fat32分割槽的檔案。
花那麼多精力去學習u-boot,但是工作中基本用不到,這對初學者很不友善。
所以,對於初學者,我建議:理解u-boot的作用、會使用u-boot的命令,這就可以了。
如果你的工作就是修改、完善bootloader,那麼再去研究它吧。
之前我們說過linux核心 = 驅動集合 + 程序排程 + 記憶體管理等,如果要學習linux核心,從驅動程式入手是一個好辦法。
但是人人都要學習linux核心、人人都要學習linux驅動嗎?顯然不是。
作為初學者,懂幾個簡單的驅動程式,有利於工作交流;理解中斷、程序、執行緒的概念,無論是對驅動開發、應用程式開發,都是很有好處的。
所以對於初學者,建議前期只學習這幾個驅動:led、按鍵、中斷。
① led驅動程式:
這是最簡單的驅動程式。
② 按鍵驅動程式:
它也比較簡單,從它引入「中斷」。
③ 中斷:
從「中斷」它可以引入:休眠-喚醒、程序/執行緒、poll機制、非同步通知等概念。這些概念無論是對驅動開發,還是對應用開發,都很重要。
所以,對於初學者,我建議必須學習這幾個驅動:led、按鍵、中斷。
入門之後,如果你想從事核心開發、驅動開發,那麼可以去鑽研幾個驅動程式(輸入系統、i2c匯流排、spi匯流排等),掌握若干個大型驅動程式後,你對核心的套路就有所瞭解了,再去研究其他部分(比如程序管理、檔案系統)時你會發現套路是如此通用。
攝像頭(vl42)、音效卡alsa驅動是linux中比較複雜的2類驅動,它們是很難的,如果工作與此相關再去研究。
要學,即使以後你只想研究核心,一些基本的應用開發編寫能力也是需要的:
① 基本裝置的訪問,比如lcd、輸入裝置
② 程序、執行緒、程序通訊、執行緒同步與互斥
③ 休眠-喚醒、poll機制、訊號
④ 網路程式設計
①②③部分的知識,跟驅動有密切的關係,它們是相輔相承的。
掌握了基本驅動開發能力、基本應用開發能力之後,在工作中你就可以跟別人友好溝通了,不至於一臉懵逼。
你辛辛苦苦寫出了應用程式,怎麼把它放到板子上,讓它開機就自動啟動?
你寫的程式,它依賴於哪些庫,這些庫放到板子上哪個目錄?
怎麼做一個可升級的系統?即使升級中途斷電了,也要保證程式至少還可以執行老的版本?
這些需要我們瞭解一下根檔案系統。
瞭解了init程序,你就瞭解了根檔案系統的組成,就可以隨心所欲裁剪系統,為你的專案製作出最精簡的系統。
嵌入式涉及的東西太多太雜了,如果心裡沒有主線,碰到什麼都要去研究個透徹,最終反而忘記自己要學什麼了。
比如我們會用到makefile,瞭解它的基本規則,會用我們提供的makefile就可以。
不需要深入研究那些make函式,因為在工作中都有現成的makefile給你使用,不需要自己去編寫一套makefile。何必花上好幾天去深入研究它呢?
比如我們會用到bootloader,難道又要花上幾個月來深入研究u-boot嗎?工作中基本不需要改u-boot,會用那幾個命令就可以。
不要脫離初學者的主線:應用基礎、驅動基礎。有了這2個基礎後,你想深入研究某部分時,再去花時間吧。
每次上課我都要給學生寫一次那些驅動,十幾次下來閉著眼睛都知道核心的套路了。
記不住那些函式?我也記不住,我都是去參考同類的驅動程式,這又不是閉卷考試。
但是要理清楚思路,你寫這個程式要完成什麼功能、怎麼實現這些功能?這個要弄清楚。
我的專長是作業系統,是快速地帶領大家掌握一些專案開發的基礎知識。
如果你決定深入研究某方面時,我並不能帶你多久。你要去看原始碼,去看這方面的專業書籍。
比如想深入鑽研核心的記憶體管理時,它有頁表對映(你需要閱讀arm架構的手冊)、slab分配器、vmalloc/malloc實現、mmap實現、缺頁中斷、父程序子程序之間的頁面管理等等,內容非常多。有時候連書籍都沒有,你需要直接啃**。
當你想從事某個行業時,就需要深入研究行業相關的知識。
比如can匯流排,它可以寫成一本書:can協議、can報文、socket can、車身網路拓撲結構,can應用報文,can網路管理報文,can診斷報文。
想做物聯網閘道器,需要深入研究mqtt,mqtt協議相對簡單,但是mqtt英文原版協議有130多頁,中文版有近100頁,是一本小書了。
每個行業都有自己的業務邏輯,在掌握基本的程式設計能力之一,你需要結合具體的業務去深入學習。
————————————————
嵌入式系統怎麼樣,嵌入式系統發展前景怎樣?
嵌入式軟體開發是未來幾年最熱門和最受歡迎的職業之一。權威部門統計,我國目前嵌入式軟體人才缺口每年為40萬人左右,未來隨著 三網融合 不斷提速,手機 數字電視 資訊家電 網路 汽車電子 醫療電子等都將是嵌入式軟體的重要應用領域,嵌入式開發人才將會越發搶手。當前,企業需要的嵌入式開發人才要求具備c語言程...
簡述嵌入式系統的概念及特點,什麼是嵌入式系統?嵌入式系統的特點是什麼
嵌入式系統的概念 嵌入式系統裝置一般都由嵌入式計算機系統和執行裝置組成,嵌入式計算機系統是整個嵌入式系統的核心,由硬體層 中間層 系統軟體層和應用軟體層組成。執行裝置也稱為被控物件,它可以接受嵌入式計算機系統發出的控制命令,執行所規定的操作或任務。嵌入式系統的特點 系統核心小 專用性強 系統精簡 高...
嵌入式系統和Windows系統區別
嵌入式系統和windows系統的區別如下 1 含義的不同 嵌入式系統是一種 完全嵌入受控器件內部,為特定應用而設計的專用計算機系統 根據英國電氣工程師協會的定義,嵌入式系統為控制 監視或輔助裝置 機器或用於工廠運作的裝置。而windows系統屬於通用計算機系統,通用計算機通用計算機系統是相對於嵌入式...