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