嵌入式設備樹怎麼編譯
⑴ 怎樣做一個優秀的嵌入式工程師
一、嵌入式工程師必備技能總覽
在介紹學習路徑之前,我們先來了解一下要成為一個優秀的嵌入式開發工程師,需要具備哪些技能。我們從硬體和軟體兩部分來介紹。
v 硬體部分:
1. 了解主要器件(電阻、電容、電感、各類二極體、三極體、場效應管、邏輯門電路等)。
2. 熟悉萬用表的用法,熟悉以上器件的測試方法和測試原理。
3. 了解器件封裝的常見類型和特點(直插、表貼、QFNP、BGA、SOT等)。
4. 掌握使用示波器、邏輯分析儀進行測量的方法。
5. 熟知常見器件間通信方式和匯流排。
6. 能熟練閱讀器件手冊(datasheet)並根據項目需求對器件進行選型、電路原理圖繪制、電路板布局布線,配合結構工藝完成電路板設計。
7. 能根據故障現象對電路板進行測量排查,找出錯誤並修正。
8. 掌握基本的手焊、拆焊、飛線技能。
v 軟體部分:
1. 熟練掌握C語言,熟悉位操作,位段和對齊方式等概念。
2. 掌握基本的匯編語言。
3. 熟悉編譯連接的過程和編譯指令。
4. 理解程序運行中堆與棧的分配和使用。
5. 熟悉linux系統操作和gcc編譯工具、Makefile編寫。
6. 熟悉主流嵌入式CPU的架構(如ARM)
7. 熟悉內核態和用戶態,了解不同程序運行的狀態和編程注意事項。
8. 熟悉系統引導流程,能移植uboot和操作系統,構建根文件系統和設備樹。
9. 掌握各類驅動程序模塊的編寫方法和編譯方法。
10. 熟悉網路編程原理和資料庫編程。
11. 了解UART,IIS,IIC,CAN,SPI等介面協議並能調試相關設備。
12. 了解至少一種物聯網應用層協議如MQTT等。
13. 了解常見的低功耗無線通信模塊的使用如wifi,藍牙,ZigBee。
二、學習路徑和重點
確實,我們嵌入式工程師需要掌握的知識很多,上述的每個知識點都可以展開作為一個單獨學科或者專題進行討論。上面繁多的技能要求可能讓很多同學望而生畏,不過我們嵌入式工程師的任務主要是工程實現,而不是理論研究,因此對於上面的知識點,我們不需要特別深入的了解,只需要在概念、原理和實踐方向進行理解和轉化,讓我們在工程實踐中能受這些理論的指導,利用這些理論完成設計和調試即可。
有一些同學有這樣的疑問:我以後的工作目標是嵌入式軟體工程師,那我還需要硬體部分的知識嗎?這個問題的答案是肯定的,主要有以下2個原因:
1. 嵌入式工程師沒有嚴格的軟硬體區分。
嵌入式工程師在實際工作中要不斷和硬體打交道,硬體工程師提供了原理圖和PCB布局布線圖,我們嵌入式工程師要根據數據手冊,器件編程指南以及硬體工程師提供的原理圖進行軟體設計,需要對設計進行上板驗證,需要調試除錯,這都需要我們有扎實的硬體設計功底,否則就需要不斷的去找硬體工程師來咨詢,必然會拖慢整個項目的進度。
2. 要想成為優秀的嵌入式軟體工程師,一定要熟知硬體知識。
優秀的嵌入式工程師會參與項目的需求分析,器件選型等硬體設計工作,這不僅需要我們有豐富的行業經驗,更需要我們有扎實的硬體基礎。
另外,驅動編寫等工作要求我們必須清晰的了解硬體的特性,如匯流排速度、時延、單雙工模式、是否有緩沖、是否支持DMA等等,了解硬體的特性才能充分挖掘硬體潛力,提升速度和穩定性。
又如,在和硬體工程師一起調試設備問題時,嵌入式軟體工程師需要根據硬體特點編寫對應的測試程序,如並行匯流排的數據相位測試、串列差分信號的眼圖測試,都需要嵌入式軟體工程師編寫對應的測試程序。如果嵌入式軟體工程師沒有相應的硬體知識,溝通成本會陡然增加,項目延期風險也就大大增加了。
綜上,要做優秀的嵌入式工程師,而不是渾渾噩噩混日子的小工,就要嚴格要求自己,把硬體知識也補上來。
⑵ 如何使用dtc編譯設備樹 devicetree
DTS (device tree source)
.dts文件是一種ASCII 文本格式的Device
Tree描述,此文本格式非常人性化,適合人類的閱讀習慣。基本上,在ARM
Linux在,一個.dts文件對應一個ARM的machine,一般放置在內核的arch/arm/boot/dts/目錄。由於一個SoC可能對應多個machine(一個SoC可以對應多個產品和電路板),勢必這些.dts文件需包含許多共同的部分,Linux內核為了簡化,把SoC公用的部分或者多個machine共同的部分一般提煉為.dtsi,類似於C語言的頭文件。其他的machine對應的.dts就include這個.dtsi。譬如,對於VEXPRESS而言,vexpress-v2m.dtsi就被vexpress-v2p-ca9.dts所引用,
vexpress-v2p-ca9.dts有如下一行:
/include/
"vexpress-v2m.dtsi"
當然,和C語言的頭文件類似,.dtsi也可以include其他的.dtsi,譬如幾乎所有的ARM
SoC的.dtsi都引用了skeleton.dtsi。
.dts(或者其include的.dtsi)基本元素即為前文所述的結點和屬性:
[plain] view
plainprint?
/ {
node1 {
a-string-property = "A string";
a-string-list-property = "first string", "second string";
a-byte-data-property = [0x01 0x23 0x34 0x56];
child-node1 {
first-child-property;
second-child-property = <1>;
a-string-property = "Hello, world";
};
child-node2 {
};
};
node2 {
an-empty-property;
a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */
child-node1 {
};
};
};
/ {
node1 {
a-string-property = "A string";
a-string-list-property = "first string", "second string";
a-byte-data-property = [0x01 0x23 0x34 0x56];
child-node1 {
first-child-property;
second-child-property = <1>;
a-string-property = "Hello, world";
};
child-node2 {
};
};
node2 {
an-empty-property;
a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */
child-node1 {
};
};
};
上述.dts文件並沒有什麼真實的用途,但它基本表徵了一個Device
Tree源文件的結構:
1個root結點"/";
root結點下面含一系列子結點,本例中為"node1" 和
"node2";
結點"node1"下又含有一系列子結點,本例中為"child-node1" 和
"child-node2";
各結點都有一系列屬性。這些屬性可能為空,如"
an-empty-property";可能為字元串,如"a-string-property";可能為字元串數組,如"a-string-list-property";可能為Cells(由u32整數組成),如"second-child-property",可能為二進制數,如"a-byte-data-property"。
下面以一個最簡單的machine為例來看如何寫一個.dts文件。假設此machine的配置如下:
1個雙核ARM
Cortex-A9 32位處理器;
ARM的local bus上的內存映射區域分布了2個串口(分別位於0x101F1000 和
0x101F2000)、GPIO控制器(位於0x101F3000)、SPI控制器(位於0x10170000)、中斷控制器(位於0x10140000)和一個external
bus橋;
External bus橋上又連接了SMC SMC91111
Ethernet(位於0x10100000)、I2C控制器(位於0x10160000)、64MB NOR
Flash(位於0x30000000);
External bus橋上連接的I2C控制器所對應的I2C匯流排上又連接了Maxim
DS1338實時鍾(I2C地址為0x58)。
其對應的.dts文件為:
[plain] view
plainprint?
/ {
compatible = "acme,coyotes-revenge";
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
compatible = "arm,cortex-a9";
reg = <0>;
};
cpu@1 {
compatible = "arm,cortex-a9";
reg = <1>;
};
};serial@101f0000 {
compatible = "arm,pl011";
reg = <0x101f0000 0x1000 >;
interrupts = < 1 0 >;
};serial@101f2000 {
compatible = "arm,pl011";
reg = <0x101f2000 0x1000 >;
interrupts = < 2 0 >;
};gpio@101f3000 {
compatible = "arm,pl061";
reg = <0x101f3000 0x1000
0x101f4000 0x0010>;
interrupts = < 3 0 >;
};intc: interrupt-controller@10140000 {
compatible = "arm,pl190";
reg = <0x10140000 0x1000 >;
interrupt-controller;
#interrupt-cells = <2>;
};spi@10115000 {
compatible = "arm,pl022";
reg = <0x10115000 0x1000 >;
interrupts = < 4 0 >;
};external-bus {
#address-cells = <2>
#size-cells = <1>;
ranges = <0 0 0x10100000 0x10000 // Chipselect 1, Ethernet
1 0 0x10160000 0x10000 // Chipselect 2, i2c controller
2 0 0x30000000 0x1000000>; // Chipselect 3, NOR Flashethernet@0,0 {
compatible = "smc,smc91c111";
reg = <0 0 0x1000>;
interrupts = < 5 2 >;
};i2c@1,0 {
compatible = "acme,a1234-i2c-bus";
#address-cells = <1>;
#size-cells = <0>;
reg = <1 0 0x1000>;
interrupts = < 6 2 >;
rtc@58 {
compatible = "maxim,ds1338";
reg = <58>;
interrupts = < 7 3 >;
};
};flash@2,0 {
compatible = "samsung,k8f1315ebm", "cfi-flash";
reg = <2 0 0x4000000>;
};
};
};
/ {
compatible = "acme,coyotes-revenge";
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
compatible = "arm,cortex-a9";
reg = <0>;
};
cpu@1 {
compatible = "arm,cortex-a9";
reg = <1>;
};
};
serial@101f0000 {
compatible = "arm,pl011";
reg = <0x101f0000 0x1000 >;
interrupts = < 1 0 >;
};
serial@101f2000 {
compatible = "arm,pl011";
reg = <0x101f2000 0x1000 >;
interrupts = < 2 0 >;
};
gpio@101f3000 {
compatible = "arm,pl061";
reg = <0x101f3000 0x1000
0x101f4000 0x0010>;
interrupts = < 3 0 >;
};
intc: interrupt-controller@10140000 {
compatible = "arm,pl190";
reg = <0x10140000 0x1000 >;
interrupt-controller;
#interrupt-cells = <2>;
};
spi@10115000 {
compatible = "arm,pl022";
reg = <0x10115000 0x1000 >;
interrupts = < 4 0 >;
};
external-bus {
#address-cells = <2>
#size-cells = <1>;
ranges = <0 0 0x10100000 0x10000 // Chipselect 1, Ethernet
1 0 0x10160000 0x10000 // Chipselect 2, i2c controller
2 0 0x30000000 0x1000000>; // Chipselect 3, NOR Flash
ethernet@0,0 {
compatible = "smc,smc91c111";
reg = <0 0 0x1000>;
interrupts = < 5 2 >;
};
i2c@1,0 {
compatible = "acme,a1234-i2c-bus";
#address-cells = <1>;
#size-cells = <0>;
reg = <1 0 0x1000>;
interrupts = < 6 2 >;
rtc@58 {
compatible = "maxim,ds1338";
reg = <58>;
interrupts = < 7 3 >;
};
};
flash@2,0 {
compatible = "samsung,k8f1315ebm", "cfi-flash";
reg = <2 0 0x4000000>;
};
};
};
上述.dts文件中,root結點"/"的compatible 屬性compatible =
"acme,coyotes-revenge";定義了系統的名稱,它的組織形式為:<manufacturer>,<model>。Linux內核透過root結點"/"的compatible
屬性即可判斷它啟動的是什麼machine。
在.dts文件的每個設備,都有一個compatible
屬性,compatible屬性用戶驅動和設備的綁定。compatible
屬性是一個字元串的列表,列表中的第一個字元串表徵了結點代表的確切設備,形式為"<manufacturer>,<model>",其後的字元串表徵可兼容的其他設備。可以說前面的是特指,後面的則涵蓋更廣的范圍。如在arch/arm/boot/dts/vexpress-v2m.dtsi中的Flash結點:
[plain] view
plainprint?
flash@0,00000000 {
compatible = "arm,vexpress-flash", "cfi-flash";
reg = <0 0x00000000 0x04000000>,
<1 0x00000000 0x04000000>;
bank-width = <4>;
};
flash@0,00000000 {
compatible = "arm,vexpress-flash", "cfi-flash";
reg = <0 0x00000000 0x04000000>,
<1 0x00000000 0x04000000>;
bank-width = <4>;
};
compatible屬性的第2個字元串"cfi-flash"明顯比第1個字元串"arm,vexpress-flash"涵蓋的范圍更廣。
再比如,Freescale
MPC8349 SoC含一個串口設備,它實現了國家半導體(National Semiconctor)的ns16550
寄存器介面。則MPC8349串口設備的compatible屬性為compatible = "fsl,mpc8349-uart",
"ns16550"。其中,fsl,mpc8349-uart指代了確切的設備, ns16550代表該設備與National Semiconctor
的16550
UART保持了寄存器兼容。
接下來root結點"/"的cpus子結點下面又包含2個cpu子結點,描述了此machine上的2個CPU,並且二者的compatible
屬性為"arm,cortex-a9"。
注意cpus和cpus的2個cpu子結點的命名,它們遵循的組織形式為:<name>[@<unit-address>],<>中的內容是必選項,[]中的則為可選項。name是一個ASCII字元串,用於描述結點對應的設備類型,如3com
Ethernet適配器對應的結點name宜為ethernet,而不是3com509。如果一個結點描述的設備有地址,則應該給出@unit-address。多個相同類型設備結點的name可以一樣,只要unit-address不同即可,如本例中含有cpu@0、cpu@1以及serial@101f0000與serial@101f2000這樣的同名結點。設備的unit-address地址也經常在其對應結點的reg屬性中給出。ePAPR標准給出了結點命名的規范。
⑶ 嵌入式linux 修改dts文件同時需要修改preloader么
U-Boot 引入了扁平設備樹FDT 這樣的動態介面,使用一個單獨的FDT blob(二進制大對象,是一個可以存儲二進制文件的容器)存儲傳遞給內核的參數[3]。一些確定信息,例如cache 大小、中斷路由等直接由設備樹提供,而其他的信息,例如eTSEC 的MAC 地址、頻率、PCI 匯流排數目等由U-Boot 在運行時修改。U-Boot 使用扁平設備樹取代了bd_t,而且也不再保證對bd_t 的後向兼容。需要修改的,重新編譯dts文件。
⑷ openwrt中怎麼在設備樹里pci的設備驅動開啟
不知道可以幫到你否,非復制粘貼,首先可以在Openwrt設置頁面上看是否正確識別出了3G 網卡,如果未識別先去看下Openwrt的固件版本和路由器型號,然後可以到Openwrt官網查詢固件是否支持該網卡,或者是預置網卡驅動否,如果沒有預置業可以到Openwrt官網查詢是否具備該型號網卡的驅動,驅動文件應該是ipk文件,傳到路由器上編譯進去即可。
⑸ linux的spi設備樹信息怎麼被讀入內核
linux3.0隻是個內核,用來 編譯成二進制,然後被燒到板上去。 ubuntu 是個操作系統,它是用來搭建一個linux環境,然後在這個環境下 編譯 linux內核、文件系統、linux應用程序等。(不用windows環境是因為在windows下編譯linux程序很麻煩)
⑹ 嵌入式linux內核獲取啟動參數是先從nand還是設備樹
U-boot會給Linux Kernel傳遞很多參數,如:串口,RAM,videofb、MAC地址等。而Linux kernel也會讀取和處理這些參數。兩者之間通過struct tag來傳遞參數。U-boot把要傳遞給kernel的東西保存在struct tag數據結構中,啟動kernel時,把這個結構體的物理地址傳給kernel;Linux kernel通過這個地址,用parse_tags分析出傳遞過來的參數。
⑺ 編譯linux內核設備樹文件使用什麼命令
Linux源碼的arch/powerpc/boot/dts/目錄下存放了很多dts文件,可以作為參考文件。另外dtc編譯器在內核源碼2.6.25版本之後已經被包含進去。在2.6.26版本之後,生成blob的簡單規則已經加入makefile,如下命令:
$ make ARCH=powerpc canyonlands.dtb
也可以根據自己的硬體修改好dts文件後,用下面類似命令生成dtb文件。
$ dtc -f -I dts -O dtb -R 8 -S 0x3000 test.dts > mpc836x_mds.dtb
$ mkimage -A ppc -O Linux -T flat_dt -C none -a 0x300000 -e 0 -d mpc836x_mds.dtb mpc836x_mds.dtu
⑻ 有沒有嵌入式開發的學習路線,越詳細越好
一、學習路徑
萬丈高樓平地起,不管多優秀的工程師都是從小白開始的。一條清晰合理的學習路線能幫助小白們高效率的完成基礎知識的儲備工作,注意這里是知識的儲備過程,而經驗是從實踐中得到的。學習路徑是多種多樣的,不同能力和不同基礎的人有不太相同的路徑,這里分享我自己的學習路徑,供大家參考。
1.了解計算機原理,操作系統基礎知識。了解硬碟,內存和CPU的關系,程序是如何載入到內存運行的,了解操作系統進程切換和時間片的概念。
2.學習C語言,掌握編譯器基本知識,能編寫簡單的程序。學習硬體相關知識。
3.購買洞洞板或者麵包板,配合stm32等單片機核心板及相應教材,實踐IO操作,中斷,定時器,ADC,UART通信,IIC通信,SPI通信,CAN通信等基本功能。在此過程中不斷鞏固提升C語言編程水平。
4.掌握了某一種單片機的基本編程和控制後,可以進軍嵌入式操作系統的學習。在此期間可以繼續使用STM32核心板,加購LCD串口液晶顯示屏,不需要買帶字型檔的顯示屏,簡單實用的串口顯示屏就可以。然後可以從Free RTOS開始學習,這個操作系統代碼少,概念清晰,易於學習操作系統的原理,也易於移植,基本上可以參考官網以及網路上的資料順利的將操作系統移植到STM32核心板。通過FreeRTOS,可以學習嵌入式操作系統的基本原理,並可以編寫LCD驅動程序來感受硬體驅動程序的概念。
5.學習嵌入式Linux操作系統,購買ARM9或以上版本的主控的開發板,要求開發板上至少有串口和網口。學習板級支持包的開發,交叉編譯,GDB調試,UBOOT移植,內核移植,根文件系統製作,設備樹,驅動程序編寫,網路編程相關知識。
6.學習物聯網相關模塊的使用,可以購買ESP32核心板進行wifi,藍牙的模塊控制學習,購買其他模塊實現其他小項目的練習。
通過上面的一番閉關修煉,你已經學習了嵌入式開發的主要知識架構,接下來就要多做小項目,多練習排錯,才能不斷積累經驗。
二、學習方法
1.先整再零:
對於一個實例項目,先從整體出發,保證調通,能正常運行,出現預期結果。遇到模糊的問題先跳過,整體有了一定認識後再對個別細節進行深入了解,但不能跳過深入了解細節的環節。
2.邊學邊練:
開發是一類實踐性很強的技能,嵌入式開發要與硬體打交道,就需要更多的動手操作和觀察。
學習某一方向的嵌入式開發知識時,需要給自己的學習進行必要的「投資」,購買麵包板、洞洞板、萬用表、調溫烙鐵套裝、各種器件、晶元,以至開發板。以上材料不需要一次性都買齊,可以按照當前學習的內容分階段購買,經濟條件有限的同學也不用擔心,以上材料的開銷除開發板之外都不貴,可網路購買。對於開發板,可以買學長學姐的二手板卡,能過測試就證明板卡是OK的。
有了學習材料,就要學以致用,例如今天學習了三極體做開關,就可以自己動手畫畫電路圖,然後在洞洞板上實踐一下,通過實際操作,加深印象的同時,也能驗證自己的設計方案。
3.勤於思考和提問,網路如此發達,提問的能力和技巧我就不再贅述了。
三、技能提升建議
如果你進入的是一家規模較小的公司,那麼你可能有機會接觸各類技術。這是絕佳的鍛煉機會,要注意不要特別深入某一方向而不關注其他技術,要知道大牛需要的是多方位的技能。
大公司的話,往往分工比較細致而明確,那就需要在完成自己工作的同時多關注項目組中其他同事遇到的問題,能協助解決最好,不能解決的要關註解決的情況和方法,多蹭經驗。幫助別人的同時就是在幫助自己提高,多花時間處理實際問題是難得的經驗。
不管在哪種場合工作,一定注意經驗的積累,好記不如帶墨,要用文字將經驗記錄下來,將遇到的問題詳細描述清楚,沒事的時候翻看一下,工作時間長了,你會發現這是一筆難得的財富。
限於篇幅,這里就不再多講技術的細節了,希望各位讀者在技術成長的過程當中都能有自己清晰的學習路徑,安排好自己的學習計劃,穩扎穩打!