• <tbody id="wslfv"><pre id="wslfv"></pre></tbody>
    <span id="wslfv"></span>
    <tbody id="wslfv"><pre id="wslfv"></pre></tbody>
    <th id="wslfv"><track id="wslfv"><rt id="wslfv"></rt></track></th>

    <li id="wslfv"><acronym id="wslfv"></acronym></li>
    更多課程 選擇中心

    嵌入式培訓
    達內IT學院

    400-111-8989

    嵌入式教程:嵌入式入門知識點匯總

    • 發布:嵌入式培訓
    • 來源:嵌入式教程
    • 時間:2019-02-13 19:11

    以下是一個C語言函數,有三行代碼,實現將數字轉為對應字符的功能。當然,真正的函數實現應該增加判斷a的取值是否在0到9之間,這里簡單的邏輯實現僅僅是為了闡述嵌入式的知識點。我們的故事就從我們寫下這行代碼開始,止于這行代碼變成指令在CPU中運行。寫這篇文章是為了講清楚作為一名嵌入式軟件開發工程師應該要具備的技能,即其應該要掌握的知識點。

    char str2num(char a){

    char b = a + 0x30;

    printf("%c", b);

    return b;

    一、嵌入式入門知識點:集成開發環境

    我們寫代碼、編譯、鏈接、調試等都是在集成開發環境中進行,作為一個嵌入式工程師應該非常精通一個集成開發環境,就像至少要精通一種芯片的體系結構一樣,如Keil之于51。其相關點包括:

    工程的屬性設置,這非常重要,包括庫路徑、頭文件路徑、代碼優化級別、調試選項、宏定義等等。不僅僅是讀懂,而是應該去改動這些設置,看看有什么變化和影響,真正地掌握。

    每個文件的屬性設置也要充分了解,如產生匯編中間文件等;

    中間文件和結果文件的路徑以及文件的格式作用;

    工程管理;

    設置字體和code style(顏色和高亮顯示)是讓自己的眼睛更舒服。

    知曉集成開發環境和工具鏈的對應關系。集成開發環境的編輯鏈接調試按鈕對應什么應該要知道吧。有些芯片平臺可能并沒有很好的集成開環境(如MIPS),那只能熟悉命令行操作了。

    一般的基礎開發環境都支持插件開發,理解一下就好,除非自己的工作就是做這個的。

    當然,看代碼一般不在集成環境里面進行,我喜歡source insight,高亮顯示和智能關聯,極大地提高效率。在開發環境和source insight里面寫代碼都較常見。

    二、嵌入式入門知識點:工具鏈

    引言的函數是高級語言,而CPU能理解的是機器語言,也就是0101這些二進制數據。所以要想讓CPU執行這個函數,得依靠工具鏈的支持。一般我們是在PC上進行開發,即所謂的宿主,但執行這段代碼的是嵌入式處理器,也就是所謂的目標系統。所以這種工具鏈也成為交叉工具鏈,對應的開發環境稱為交叉編譯環境。我個人認為很多事物和思想都是相通的,舉一反三,我們需要做的就是精通,至少很熟悉一種工具鏈,如gcc工具鏈。能夠運用工具鏈并不代表你很熟悉,真正的熟悉應該是理解工具鏈的作用以及其在實現這個作用的過程中的大致做法,也就是實現的原理。我們需要弄懂的包括:

    1. 編譯器

    理解編譯原理。編譯是將每個C文件轉換為接近機器語言而又能夠被開發工程師理解的匯編語言,而且其將每個文件的代碼和變量數據進行重新組織,分成幾個部分,如這個文件里面的函數都會集中放到一個代碼段.CODE(除非你自己把某個函數規定要某個指定的段),常量數據段.CONST(類似代碼段只讀),靜態變量和全局變量所在的.DATA(有些平臺兩個段的名字也不一樣,按作用實際一樣的),未初始化的全局變量.BSS;另外一個很重要的任務是記錄可重定位的符號(函數、變量)信息,如引言函數調用printf這個函數,而printf函數的地址暫時是未知的,那文件中需要為這個調用做好將來重定位的準備。這時看到的代碼段的起始地址往往是0。

    理解編譯選項。其實集成開發環境的工程屬性和文件的屬性設置對應的就是這個編譯選項。

    2. 匯編器

    匯編器是將匯編語言轉為機器語言,輸出的也是可重定位文件。一般編譯器都包含了匯編這個步驟,直接輸出可重定位.O文件。而匯編器一般是處理以匯編語言編寫的文件。

    3. 鏈接器

    鏈接就是將所有可重定位文件的代碼段、數據段等進行統一組織和空間分配,其依據就是工程的鏈接文件,另外最重要的是實現重定位的過程。鏈接文件是有其固有的語法格式的,要熟悉其語法,會自己寫鏈接文件,不能僅僅是拷貝和局部改動,而是真正能利用鏈接來實現自己普通的和特有的想法。最后鏈接器會生成一定格式的可執行文件,如exe和elf格式等。另外,掌握芯片平臺的存儲資源范圍也是寫好鏈接文件的前提條件。

    4. makefile

    makefile是gcc工具鏈非常重要的部分,其作用就用命令行的方式來替代集成開發環境,實現編譯和鏈接的自動化執行過程。makefile是腳本執行,同樣有固定的語法,需要很好地領會。

    5. binutils

    即二進制工具集,掌握和利用好這些工具能夠提高開發的效率。例如在GCC工具鏈中我們想快速定位到某個變量的地址,并不需要去查看一些結果文件,而是敲命令mn就可以了。

    至此,我們假定已經將引言的C函數編譯成.O文件了,加入到工程并調用,寫好makefile和link,就可以輸出為可執行文件了。

    三、嵌入式入門知識點:理解各種類型的文件格式

    嵌入式開發需要和硬件打交道,硬件資源有限,交叉調試環境往往沒有PC軟件那么友好。因此要懂得利用一切游泳資源來提高開發調試效率。我現在的機子沒有交叉編譯環境,我叫一個嵌入式開發工程師幫我取得引言中代碼的反匯編代碼,他竟然回答說要調試的時候用匯編模式才能看到反匯編代碼。這明顯就是一般PC工程師的認識。實際我們可以在很多地方看到反匯編的信息的。

    可執行文件格式,如elf。應該很好地理解這個文件格式。我們常聽到一句話是“存在即是道理”,里面所有的數據結構都有其對應的作用。我們可能會看到在鏈接文件里面會有一個ENTRY的標識,而在elf的文件頭格式中有一個entry的域,其是一一對應的,它代表著這個可執行文件的第一條執行指令的地址。有很多人可能會認為這個地址應該是main的地址吧,其實并不是,而是運行時庫的入口。當然,我們并不需要對著elf的格式說明來查看這個二進制文件。不是有binutils嗎?它就是用來查看我們需要的信息的。

    map文件。map文件是以文本文件的形式來記錄elf格式文件中的各種代碼和數據段的地址信息和長度,以及各個函數和變量對應的地址等等。結合link文件來理解map文件會很有趣。map文件反映的函數和變量的地址信息對于調試會非常有用,尤其是一個團隊開發一個項目時往往有多個工程,多個模塊,而工程A在調試時,集成開發環境的watch是監看不到工程B的某個變量的。這時就需要直接輸入該變量地址來查看內容值。

    lst文件。其是反匯編文件,掌握匯編語言是嵌入式工程師的必備技能,平時可能較少用匯編開發程序,但調試的時候需要經常看反匯編是很正常的。

    理解代碼和數據的組織方式。.O和.ELF都有描述。我們在學習C語言的時候,老師往往不會講這些內容。這里指的是我們要知道編譯器如何按它的方式去理解我們的想法(函數和變量),并以其自己的方式去管理這些函數和變量。也就是一個C文件通過編譯輸出.O文件時,其產生的.CODE、.DATA、.BSS、.SYM等等段。

    四、嵌入式入門知識點:加載

    嵌入式軟件工程師和PC工程師最大的區別是嵌入式軟件工程師需要對自己所寫的每一行代碼負責,負責的意義代表著這行代碼的作用、它在可執行文件中的位置、它真正要加載到哪里(即虛擬運行地址)、它什么時候會被加載、它什么時候會被執行等等。

    加載一般指的是將目標代碼復制到內存對應位置的過程(記得,RAM是掉電不保存內容的)。一般有以下幾種方式:

    對于存儲資源豐富型系統,一般是使用高端嵌入式處理器的系統,在系統啟動時ELF文件一般是放在外存儲設備中。這種系統都部署了嵌入式操作系統,能夠解釋ELF格式文件,將ELF里面真正的代碼和數據段加載到內存對應的位置。其第一個加載的自然是ENTRY對應的起始地址所在的代碼段。

    對應存儲資源緊缺型系統,一般是使用低端嵌入式控制器的系統,其部署的操作系統往往是精簡高效型系統,它并不直接解釋ELF格式,而是解釋ELF再處理后的格式文件。這種系統往往是定制型的操作系統,而ELF再處理也跟操作系統相關。但再處理后的格式依然要保持必要的信息,如entry,.CODE,.DATA等等。在系統啟動階段,再處理后大幅減少容量的文件一般也是放在外存儲設備中,在必要時被操作系統讀取并加載到內存中。

    有時一些代碼會被固化到ROM中,如系統啟動執行的代碼都是固化到ROM中,如PC上電執行的第一條指令就是固化的,而且固化的地址就是運行地址,無需加載。對于嵌入式控制器,這個固化也可以理解為將代碼燒寫到flash rom中。這應該是常見的利用開發板進行開發所進行的步驟。

    有時一個系統里面又有RAM又有ROM,那有部分代碼會固化到ROM中,但其運行地址并不是固化的地址,這時也需要將代碼加載到RAM中對應的地址才能運行。

    五、嵌入式入門知識點:內存管理

    上節所說的加載一定是將代碼加載到實際的物理內存,但我們的可執行文件中的運行地址是虛擬運行地址,兩者之間是什么映射的呢?這就是內存管理單元(MMU)的作用域。高端處理器一般都有MMU,但低端控制器一般是沒有MMU的,但低端控制器也會按一定的方式去做好映射,最簡單的就是虛擬和物理一一對應嘛。有MMU管理的系統也不是硬件就能解決所有問題,其也需要借助于頁表來記錄映射關系,MMU里面有一個叫做TLB的東西,是頁表的CACHE,在每次訪問內存時會被將虛擬地址的前N位轉為對應的物理內存塊的前N位,依據就是頁表(可以理解為轉換表)。

    六、嵌入式入門知識點:執行

    執行肯定指的是CPU的取指執行了,我們需要懂得什么?我們要理解的是芯片的體系結構,理解其精簡指令集。

    寄存器,包括通用寄存器和專用寄存器。通用寄存器一般用來暫存數據和做計算用。專用寄存器是實現專有的功能,最重要的是PC和SP。PC即程序寄存器,記錄的是當前指令執行的地址,SP是棧指針,記錄的是當前的棧頂地址。棧的使用絕對是一個非常絕妙的發明,棧的遞歸恰好對應的是函數的調用和返回,函數的調用就是將必要的信息入棧,這里最重要的是包括返回地址;而程序返回就是出棧,我們可以看到像RET這樣的指令對應的偽指令都是將當前SP的值賦給PC,然后SP增加或者減少(根據體系結構而定)。

    理解指令集。

    理解流水線相關的問題、cache的問題。調試的時候特別要注意指令預取所帶來的問題。

    七、嵌入式入門知識點:運行時庫

    我們剛開始學C語言的時候應該都有一種迷惑,我們在main中調用printf這個函數就能打印了,但我們又沒看到它具體的實現是在哪里。另外,我們大部分人往往都有一個誤解,以為main入口是程序執行的第一個指令,實際是不對的。

    pirntf的功能是打印信息到屏幕上,我們可以設想在main執行之前一定要初始化屏幕的輸出驅動吧。

    操作系統支持多線程,而執行的程序是一個進程,main就是一個主線程,在我們的程序里面沒看到什么進程線程之類的東西,就是在main之前做好的。

    我們一般在C++中看到某個類有構造函數和虛構函數,它們分別是在main之前和退出之后要做的動作,怎么支持這個功能呢?

    這些大致的功能就是運行時庫所要支持的功能,不同的操作系統有不同的要求,但從現在開始,我們不能再認為main就是程序第一個要執行的指令。

    八、嵌入式入門知識點:C庫

    printf這個函數實際上是標準C庫的一個函數。每種語言都會有很多的支持庫,所以我們要懂得如何去利用現有的庫來實現我們的功能,而不是什么都要自力更生。當然從節約存儲資源和提高執行效率的角度,可以參考C庫某函數的實現,然后進行改進。C庫包括常見的字符串轉換(如引言的str2num)、浮點計算等模塊。

    九、嵌入式入門知識點:API

    引言函數調用printf這個函數,而這個函數一般是操作系統提供的函數,其不會把代碼實現拿到引言函數所在的應用工程去build,拿到的僅僅是API庫。也就是說應用先通過API層進入到操作系統層再調用實際的打印驅動代碼。API怎么實現?一般使用陷入指令或者軟件中斷,當然API的設計也是一門藝術,在資源緊缺型的系統中更是如此,因為陷入的時候我們除了要提供打印的參數,還要提供打印函數對應的索引,這個索引實現的方式并不單一,這就是具體設計時要考慮的。

    十、嵌入式入門知識點:ABI

    ABI即二進制程序接口,主要涉及的是棧幀的實現和函數調用時的傳參約定。這是在C語言和匯編語言交叉編程時特別要注意的知識點。

    棧幀記錄的是非常重要的上下文信息,在多任務操作系統移植時,它記錄的信息一定是要進行重點關注的,往往是匯編語言進行編寫。因此理解棧幀是移植操作系統的必要步驟。當然理解好棧幀能夠很好地幫助調試。

    傳參約定,即在傳遞參數時用寄存器存還是棧來存,或者兩者都有(如MIPS工具鏈),存放的順序,在參數類型不同或者個數不同時又是怎么約定的。

    寄存器的使用約定,通用寄存器的執行速度肯定優于內存,所以寄存器的使用非常頻繁。在函數調用的過程中,自然會出現某個函數執行到一半的時候就發生調用了,這時某些寄存器就要先保存起來,以免被下一個要調用的程序破壞;而某些寄存器在使用之前按規定是先要保存再利用,返回前將其恢復就可以了。

    十一、嵌入式入門知識點:編碼格式

    將數字轉為字符串就是加上0X30,這是跟進ASCII碼表來實現的。做嵌入式開發很多時候需要理解很多編碼格式,如UNICODE,字庫等等碼表。

    十二、嵌入式入門知識點:軟件層次

    嵌入式開發工程師不應僅僅停留在某個應用或者某個模塊上,而是應盡量全面地學會或者把控整個系統,雖然不能每個模塊的代碼都去理解一遍,但基本的流程要懂。基本的軟件層次從低到高有啟動、驅動、操作系統、API、中間件、UI、應用等等。

    十三、嵌入式入門知識點:硬件體系結構

    現在的芯片都可以成為SOC,不僅CPU,很多模塊都已經集成到芯片上,如ADC、SRAM等等。要懂得各個模塊的使用接口,還要理解CPU和各種接口對應的總線的訪問方式,他們是怎么競爭訪問的。

    十四、嵌入式入門知識點:編程思想

    要真正地學好一門語言,不是指懂得它的語法,而是要有解決問題的思想。對于嵌入式開發,應該學會面向對象的編程思想。其實C++的類CLASS和C語言的數據結構STRUCT不是一回事嗎?

    通過上面的介紹相信你對于嵌入式入門學習有了一個大概的了解和認識,如果你想參加嵌入式培訓可以選擇達內,達內2月份嵌入式培訓正在報名中.....2月14日情侶來報名達內贈送電影票兩張,當天繳費學費直降1314元,你還在等待什么,抓緊來報名吧!

    預約申請免費試聽課

    填寫下面表單即可預約申請免費試聽!怕錢不夠?可就業掙錢后再付學費! 怕學不會?助教全程陪讀,隨時解惑!擔心就業?一地學習,可全國推薦就業!

    上一篇:嵌入式教程分享:嵌入式系統具有哪些特性
    下一篇:嵌入式教程分享:如何運用嵌入式位運算

    裸編程怎么做?裸編程具體做法

    嵌入式編程中你必須知道的小知識

    嵌入式C語言編程小知識總結

    有哪些工具可以讓嵌入式開發事半功倍?

    • 掃碼領取資料

      回復關鍵字:視頻資料

      免費領取 達內課程視頻學習資料

    • 視頻學習QQ群

      添加QQ群:1143617948

      免費領取達內課程視頻學習資料

    Copyright ? 2021 Tedu.cn All Rights Reserved 京ICP備08000853號-56 京公網安備 11010802029508號 達內時代科技集團有限公司 版權所有

    選擇城市和中心
    黑龍江省

    吉林省

    河北省

    湖南省

    貴州省

    云南省

    廣西省

    海南省

    欧美一级高清片,一级欧美免费大片视频,欧美三级在线电影免费 百度 好搜 搜狗
    <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>