本書從教學(xué)的角度出發(fā),全面討論了嵌入式軟件設(shè)計的思想與方法。在編排上循序漸進,從基礎(chǔ)準備,到驅(qū)動模型,再深入到整個系統(tǒng)及系統(tǒng)的構(gòu)建。在講解上通過建立模型來幫助讀者系統(tǒng)掌握嵌入式軟件設(shè)計的普遍原理與編程接口。內(nèi)容包括:高效、穩(wěn)定和規(guī)范的程序基礎(chǔ),多任務(wù)環(huán)境,I/O系統(tǒng)的內(nèi)部結(jié)構(gòu),驅(qū)動模型,BSP設(shè)計要素,嵌入式軟件設(shè)計的經(jīng)驗技巧;在硬件基礎(chǔ)方面討論了總線與設(shè)備的模型,基于MIPS和ARM SoC在多個系統(tǒng)平臺VxWorks,Lnux及WinCE下的系統(tǒng)資源的操控。
本書可作為在校學(xué)生學(xué)習(xí)嵌入式軟件設(shè)計原理的教學(xué)參考用書,也可作為嵌入式軟件開發(fā)工程人員深入掌握系統(tǒng)軟件設(shè)計的指南,以及嵌入式軟件培訓(xùn)的參考教材。
《嵌入式軟件設(shè)計之思想與方法》可作為在校學(xué)生學(xué)習(xí)嵌入式軟件設(shè)計原理的教學(xué)參考用書,也可作為嵌入式軟件開發(fā)工程人員深入掌握系統(tǒng)軟件設(shè)計的指南,以及嵌入式軟件培訓(xùn)的參考教材。
硬件技術(shù)的飛速發(fā)展,使硬件的性能顯著提高,并且成本極速降低。微處理器已經(jīng)深入到人們生活和生產(chǎn)的各個領(lǐng)域,各種產(chǎn)品和設(shè)備都逐漸增加了復(fù)雜的智能化功能,使得消費類電子產(chǎn)品、個人媒體產(chǎn)品、個人數(shù)字助理以及工業(yè)控制等領(lǐng)域得以快速發(fā)展。隨著這些產(chǎn)品的高度智能化和復(fù)雜化,嵌入式軟件的需求得到迅猛發(fā)展。從單片機的控制軟件,到功能強大的多任務(wù)實時操作系統(tǒng)平臺,產(chǎn)品的智能化程度越來越高,易用性越來越好,嵌入式軟件及其應(yīng)用領(lǐng)域越來越廣泛,從而對嵌入式軟件的要求也變得越來越復(fù)雜。本書旨在為嵌入式軟件開發(fā)愛好者提供一個入門的引導(dǎo)。面對復(fù)雜的嵌入式系統(tǒng)軟件,作為一位初學(xué)者,如何清楚把握嵌入式軟件的設(shè)計對象與目標,如何尋找一個很好的切入點,盡快參與到嵌入式軟件的設(shè)計當(dāng)中,對于這些問題,希望通過本書的講解,能夠為讀者提供一些有益的啟示。筆者多年來一直在嵌入式軟件領(lǐng)域從事實際項目的開發(fā)工作,出于對軟件設(shè)計的執(zhí)著與偏愛,筆者把這些年從事嵌入式軟件設(shè)計的經(jīng)驗點滴整理出來,與更多的嵌入式軟件設(shè)計愛好者分享。目前,盡管介紹嵌入式軟件設(shè)計方面的書籍較多,但全面、系統(tǒng)地討論如何從頭開始設(shè)計嵌入式系統(tǒng)軟件的書籍卻很少。很多嵌入式軟件設(shè)計方面的書籍都是一些諸如百科全書的參考手冊,由于體系過于龐大,或討論過于專業(yè),初學(xué)者很難在短時間內(nèi)把握其中有用的部分,因而更難將龐大體系里各書籍中的精華串到一起,而本書正是這些書籍精華的一種提煉。本書以講述的方式,深入剖析嵌入式系統(tǒng)軟件設(shè)計的各個層面,以及設(shè)計實踐中的各個關(guān)鍵之事,以幫助讀者輕松地領(lǐng)會嵌入式軟件設(shè)計的方法,掌握嵌入式軟件的核心架構(gòu)。書中通過對嵌入式系統(tǒng)的分解,重點講述嵌入式系統(tǒng)軟件的層次結(jié)構(gòu)。通過對目前多個主流系統(tǒng)(VxWorks,Linux,WinCE)內(nèi)核進行深入淺出的剖析與對比,幫助讀者建立起正確的驅(qū)動設(shè)計模型;通過對不同硬件平臺(MIPS,ARM)所開發(fā)的板級支持包(BSP)的深入討論,幫助讀者掌握硬件適配層(OAL)設(shè)計的核心概念,使讀者清楚理解系統(tǒng)環(huán)境的上下文,前因后果,從而更好地把握各個軟件模塊設(shè)計的分界與接口,把握設(shè)計的對象與目標,在設(shè)計中做到心中有數(shù),目標明確,從而更好、更快地解決問題。要想成為一名成功的嵌入式軟件程序員,程序的設(shè)計能力是首要的技能。如何打好程序設(shè)計基礎(chǔ),如何編寫工程化的程序,如何在設(shè)計中與團隊協(xié)作開發(fā)、在后續(xù)開發(fā)中有效地升級與維護,如何編寫規(guī)范的文檔等,這些都是工程化軟件設(shè)計中非常關(guān)鍵的環(huán)節(jié),本書花費大量篇幅進行介紹,以幫助讀者提高程序設(shè)計能力。書中從各種復(fù)雜的軟件系統(tǒng)中抽象出驅(qū)動模型和板級支持包的設(shè)計模型;對于硬件基礎(chǔ),也通過模型化的方法講述了總線的一般概念與作用,抽象出輸入/輸出設(shè)備的模型。通過這些模型化的講解,便于讀者掌握嵌入式軟件設(shè)計的目標與內(nèi)容,從而提高軟件設(shè)計能力。1. 讀者對象本書的讀者對象為嵌入式程序設(shè)計的初學(xué)者,本書也可作為大中專學(xué)生學(xué)習(xí)嵌入式軟件設(shè)計的入門參考。對于那些已從事嵌入式軟件設(shè)計一段時間,但是在設(shè)計實踐中感覺力不從心,需要全面掌握嵌入式軟件設(shè)計內(nèi)容與目標,掌握一些新的技巧與方法的讀者,相信本書將會起到良師益友的作用。本書也可以作為嵌入式軟件培訓(xùn)的教材。2. 題材與組織本書共分為四篇,其中第一篇著重討論作為一名優(yōu)秀的嵌入式軟件設(shè)計人員所必備的知識和技能。需要說明的是:限于時間和精力,本書沒能全面囊括嵌入式軟件設(shè)計的所有知識點和技術(shù)面,但希望本書能讓讀者掌握基本的框架,使讀者在今后的學(xué)習(xí)和工作實踐中,更好地結(jié)合優(yōu)秀讀物和參考資料,不斷學(xué)習(xí)和實踐,從而提高自身的軟件設(shè)計能力和水平。
張邦術(shù),1999年畢業(yè)于電子科技大學(xué),先后在聯(lián)想、泰鼎、微開和泰克公司從事近10年嵌入式軟件及系統(tǒng)軟件的研發(fā)工作,在VxWorks,Linux和WinCE系統(tǒng)平臺上的開發(fā),以及在音/視頻、移動媒體、測試儀器等領(lǐng)域具有豐富的設(shè)計經(jīng)驗,在軟件團隊的組建、培訓(xùn)和項目管理等方面積累了大量經(jīng)驗。
第一篇 基礎(chǔ)方法篇
第1章 程序基礎(chǔ)
1.1 設(shè)計高性能程序的必要性3
1.1.1 設(shè)計高性能程序的必要性3
1.1.2 嵌入式軟件的設(shè)計范疇3
1.1.3 嵌入式軟件的分層結(jié)構(gòu)6
1.2 嵌入式軟件的程序設(shè)計要求8
1.2.1 代碼結(jié)果的要求9
1.2.2 代碼形式的要求10
1.3 嵌入式軟件開發(fā)的基本思路和原則10
1.3.1 系統(tǒng)分析,定義接口11
1.3.2 函數(shù)實現(xiàn),優(yōu)化算法12
1.3.3 清理代碼,補充注釋14
1.3.4 測試修訂,完善文檔 14
1.4 程序?qū)嵗饰?4
1.4.1 正確理解棧14
1.4.2 內(nèi)存泄漏18
1.4.3 消除編譯依賴18
1.4.4 消除潛在隱患20
1.4.5 規(guī)范實現(xiàn)范例21
1.4.6 性能優(yōu)化23
1.5 程序設(shè)計其他注意點30
1.5.1 謹慎使用“宏”30
1.5.2 正確理解預(yù)定義宏34
1.5.3 避免歧義37
第2章 多任務(wù)操作系統(tǒng)
2.1 板級支持包40
2.2 嵌入式操作系統(tǒng)與實時性40
2.2.1 嵌入式操作系統(tǒng)41
2.2.2 實時操作系統(tǒng)42
2.3 多任務(wù)概述42
2.3.1 進程、線程與任務(wù)43
2.3.2 何時需要多任務(wù)44
2.3.3 任務(wù)狀態(tài)的轉(zhuǎn)換50
2.3.4 進程調(diào)度與調(diào)試算法51
2.3.5 任務(wù)相關(guān)的API51
2.4 進程間共享代碼與可重入性53
2.4.1 共享代碼53
2.4.2 共享代碼可重入性問題53
2.4.3 使用私有數(shù)據(jù)55
2.4.4 使用臨界區(qū)數(shù)據(jù)57
2.5 線程間通信57
2.5.1 共享數(shù)據(jù)結(jié)構(gòu)57
2.5.2 互斥59
2.5.3 信號量60
2.5.4 臨界區(qū)與信號量的實現(xiàn)實例63
第3章 硬件基礎(chǔ)
3.1 ARM74
3.1.1 ARM編程模式75
3.1.2 ARM指令概述78
3.1.3 ARM異常及處理80
3.2 MIPS86
3.2.1 MIPS編程模式87
3.2.2 MIPS指令概述90
3.2.3 MIPS中斷與異常95
3.3 接口基礎(chǔ)98
3.3.1 總線概述99
3.3.2 I2C總線105
3.3.3 PCI總線108
3.3.4 設(shè)備模型115
3.3.5 一個IDE控制器設(shè)備實例117
第二篇 驅(qū)動模型篇
第4章 驅(qū)動的通用模型
4.1 設(shè)備驅(qū)動的作用121
4.2 驅(qū)動類型123
4.2.1 Linux中的驅(qū)動類型123
4.2.2 WinCE中的驅(qū)動類型125
4.2.3 VxWorks中的驅(qū)動類型125
4.3 設(shè)備驅(qū)動的通用模型126
4.3.1 模塊部分的驅(qū)動126
4.3.2 設(shè)備的驅(qū)動例程127
第5章 VxWorks的驅(qū)動模型
5.1 VxWorks的I/O系統(tǒng)131
5.1.1 I/O系統(tǒng)概述131
5.1.2 文件名與設(shè)備133
5.1.3 基本I/O134
5.1.4 緩沖I/O136
5.1.5 格式化I/O136
5.2 VxWorks的驅(qū)動及其內(nèi)部結(jié)構(gòu)137
5.2.1 驅(qū)動的安裝、驅(qū)動表138
5.2.2 設(shè)備的創(chuàng)建、設(shè)備鏈表140
5.2.3 文件的打開、文件描述符表142
5.2.4 文件的讀、寫、控制和關(guān)閉操作143
第6章 Linux的驅(qū)動模型
6.1 Linux的驅(qū)動加載方式145
6.1.1 內(nèi)核驅(qū)動模塊與模塊化驅(qū)動145
6.1.2 模塊化驅(qū)動的加載與卸載146
6.2 Linux的驅(qū)動架構(gòu)147
6.2.1 一個最簡單的內(nèi)核驅(qū)動148
6.2.2 一個最簡單的模塊驅(qū)動151
6.2.3 Linux驅(qū)動中注冊驅(qū)動153
6.2.4 Linux系統(tǒng)中的設(shè)備文件154
6.3 Linux字符型設(shè)備驅(qū)動155
6.3.1 驅(qū)動的加載與清理155
6.3.2 中斷的申請與釋放156
第7章 WinCE的驅(qū)動模型
7.1 WinCE驅(qū)動類型158
7.2 設(shè)備管理器及其驅(qū)動模型159
第三篇 BSP/OAL篇
第8章 BSP的基本概念
8.1 BSP與驅(qū)動161
8.2 BSP開發(fā)的目標任務(wù)162
第9章 BSP的設(shè)計要素
9.1 中斷處理163
9.1.1 物理中斷號與邏輯中斷號163
9.1.2 CPU中斷與中斷控制器擴展164
9.1.3 中斷源的查找165
9.1.4 中斷處理線程166
9.2 CPU異常166
9.2.1 異常向量表167
9.2.2 向量表的安裝173
9.2.3 異常處理代碼實例177
9.3 硬件I/O的訪問188
9.3.1 避免使用絕對物理地址188
9.3.2 內(nèi)存一致性問題192
9.3.3 I/O訪問的刷新198
第10章 Linux的啟動過程
10.1 Linux的啟動流程199
10.2 Linux的啟動過程簡介201
10.2.1 _stext函數(shù)201
10.2.2 start_kernel函數(shù)203
10.2.3 setup_arch函數(shù)204
10.2.4 trap_init函數(shù)204
10.2.5 init_IRQ函數(shù)205
10.2.6 sched_init函數(shù)205
10.2.7 do_initcalls函數(shù)205
10.2.8 init函數(shù)206
10.2.9 init程序207
第11章 WinCE的設(shè)計
11.1 WinCE OS平臺開發(fā)簡介209
11.1.1 WinCE平臺的開發(fā)流程209
11.1.2 WinCE內(nèi)核結(jié)構(gòu)211
11.1.3 WinCE設(shè)計中的一些名詞術(shù)語212
11.2 WinCE BSP開發(fā)213
11.2.1 啟動裝載器213
11.2.2 OAL開發(fā)215
11.2.3 WinCE配置文件219
11.3 WinCE設(shè)備驅(qū)動的開發(fā)流程221
11.3.1 設(shè)備驅(qū)動源代碼221
11.3.2 修改配置文件222
11.3.3 向OS平臺注入驅(qū)動223
第四篇 擴展篇
第12章 理解程序的內(nèi)部結(jié)構(gòu)
12.1 x86匯編及其程序結(jié)構(gòu)226
12.1.1 x86程序段定義227
12.1.2 關(guān)聯(lián)段寄存器、確定段的種類230
12.1.3 段組偽指令230
12.2 嵌入式系統(tǒng)中的程序結(jié)構(gòu)231
12.2.1 嵌入式系統(tǒng)中執(zhí)行程序的映像231
12.2.2 鏈接器與命令腳本236
12.3 ELF文件格式241
12.3.1 ELF文件格式概述241
12.3.2 ELF文件格式分析器248
第13章 嵌入式系統(tǒng)的設(shè)計思想
13.1 直截了當(dāng)?shù)乃枷?62
13.2 層次化的思想267
13.3 循序漸進的思想269
13.4 實踐是最好的老師269
13.5 團隊協(xié)作意識270
13.6 大膽嘗試與積極創(chuàng)新270
結(jié) 束 語272
參考文獻273
插圖索引
圖11 嵌入式軟件的分層結(jié)構(gòu)7
圖21 VxWorks中的任務(wù)狀態(tài)轉(zhuǎn)換圖50
圖22 驅(qū)動中的可重入性問題154
圖23 驅(qū)動中的可重入性問題256
圖24 使用共享數(shù)據(jù)區(qū)訪問臨界區(qū)的例子58
圖31 ARM程序狀態(tài)寄存器格式77
圖32 MIPS CPU寄存器88
圖33 MIPS FPU寄存器90
圖34 I2C數(shù)據(jù)位的傳輸106
圖35 I2C起始條件和停止條件106
圖36 I2C總線數(shù)據(jù)傳輸時序圖107
圖37 PCI CONFIGADDRESS寄存器格式113
圖38 PCI類型0配置空間頭部114
圖39 ITE8172 IDE控制器框圖 118
圖51 驅(qū)動在系統(tǒng)中的層次結(jié)構(gòu)132
圖52 VxWorks I/O系統(tǒng)的調(diào)用關(guān)系133
圖53 VxWorks驅(qū)動安裝140
圖54 VxWorks設(shè)備添加141
圖55 VxWorks文件打開142
圖56 文件讀操作的I/O控制流程143
圖61 Linux驅(qū)動與操作系統(tǒng)核心之間的關(guān)系147
圖71 WinCE驅(qū)動內(nèi)部框圖158
圖72 WinCE系統(tǒng)中應(yīng)用程序與設(shè)備驅(qū)動的交互160
圖91 驅(qū)動程序中完整的中斷處理架構(gòu)164
圖92 IT8172G中斷控制器內(nèi)部框圖177
圖101 Linux啟動流程框圖200
圖102 Linux啟動執(zhí)行過程細節(jié)201
圖111 WinCE OS開發(fā)的工作流程210
圖112 WinCE的內(nèi)部層次結(jié)構(gòu)211
圖113 WinCE BSP框圖214
圖121 x86匯編段結(jié)構(gòu)228
圖122 宏匯編中的段鏈接映像230
圖123 x86段組定義 231
圖124 節(jié)的簡單格式237
圖125 節(jié)的完整定義239
圖126 口(ENTRY)的定義240
圖127 ELF目標文件格式242
插表索引
表31 ARM寄存器組織結(jié)構(gòu)75
表32 ARM狀態(tài)寄存器的模式位78
表33 ARM異常處理的入口地址81
表34 ARM異常的優(yōu)先級86
表35 MIPS系統(tǒng)控制寄存器CP088
表36 MIPS32/MIPS64裝入/存儲指令所支持的數(shù)據(jù)類型91
表37 MIPS對齊的裝入存儲指令91
表38 MIPS非對齊的裝入存儲指令91
表39 MIPS原子更新的裝入存儲指令92
表310協(xié)處理器裝入存儲指令92
表311 MIPS立即數(shù)操作的算術(shù)指令92
表312 MIPS三操作數(shù)算術(shù)指令92
表313 MIPS二操作數(shù)算術(shù)指令93
表314 MIPS移位指令93
表315 MIPS乘除法指令94
表316 MIPS 256M區(qū)域內(nèi)無條件跳轉(zhuǎn)指令95
表317 MIPS PC相對的條件轉(zhuǎn)移指令95
表318 MIPS的中斷、狀態(tài)及緣由寄存器的映射關(guān)系96
表319 MIPS異常向量的基地址97
表320 MIPS異常向量的偏移地址97
表321 I2C總線術(shù)語定義105
表322 PCI總線命令110
表323 ITE8172 IDE控制器的PCI配置寄存器119
表324 ITE8172 IDE總線主設(shè)備IDE輸入/輸出寄存器119
表325 IDE命令寄存器120
表111 WinCE常見的映像配置文件219
表121 字符串表簡單例子246
表122 對字符串表索引所得到的字符串246