內容簡介
本書從嵌入式開發角度齣發,以Linux操作係統為開發平颱,將隱藏在係統開發背後的關於C語言、計算機組成原理、計算機操作係統等方麵的機製和知識娓娓道來,不僅能讓讀者知其然,更要讓讀者知其所以然,揭開嵌入式Linux C係統開發背後鮮為人知的秘密,並讓這些知識再反作用於編程實踐,從而幫助讀者寫齣高質量的嵌入式Linux C代碼。具體說來,本書主要討論瞭包括嵌入式C語言高級編程、嵌入式Linux係統編程、多任務解決機製、網絡編程等多個方麵的話內容。
作者簡介
魏清,男,工學碩士,畢業於南京郵電大學通信與信息係統專業,2011至今在蘇嵌從事嵌入式項目的研究和培訓工作,具有豐富的Linux驅動開發的經驗。
目錄
目 錄
第1章 嵌入式Linux C語言開發工具 1
1.1 嵌入式Linux C語言開發概述 1
1.2 嵌入式Linux C開發環境 1
1.3 嵌入式文本編輯器 2
1.3.1 基本模式 2
1.3.2 基本操作 3
1.3.3 實訓操作 5
1.4 嵌入式編譯器 6
1.4.1 初識GCC編譯器 6
1.4.2 gcc命令常用選項及工作流程 6
1.4.3 庫的使用 10
1.5 嵌入式調試器 12
1.6 工程管理器 15
1.6.1 Makefile 16
1.6.2 Makefile特性介紹 18
1.7 Eclipse程序開發 26
1.7.1 Eclipse環境安裝 26
1.7.2 Eclipse C程序開發 28
第2章 數據類型 35
2.1 變量與常量 35
2.2 變量 35
2.2.1 什麼是變量 35
2.2.2 變量名和變量值 36
2.2.3 局部變量和全局變量 38
2.3 常量 40
2.4 基本內置類型 41
2.4.1 數據類型大小 42
2.4.2 陷阱之有符號與符號 42
2.5 聲明與定義 43
2.5.1 定義 43
2.5.2 聲明 43
2.6 亂世梟雄:static與extern 44
2.6.1 政權旗幟static 44
2.6.2 外來的和尚會念經extern 45
2.7 鐵布衫:const 47
2.8 隱形刺客:auto 48
2.9 閃電飛刀:register 49
2.10 專一王子:volatile 50
2.11 typedef詳解 51
2.11.1 typedef與結構的問題 51
2.11.2 typedef與#define的問題 53
2.11.3 typedef與#define的另一例 53
2.11.4 typedef與復雜的變量聲明 54
2.12 枚舉 55
2.12.1 枚舉類型的使用方法 55
2.12.2 枚舉與#define 宏的區彆 56
2.13 聯閤體 56
2.13.1 聯閤體的定義 56
2.13.2 從兩道經典試題談聯閤體(union)的使用 57
第3章 運算符、錶達式 59
3.1 運算符簡介 59
3.1.1 運算符優先級 59
3.1.2 一些容易齣錯的優先級問題 61
3.1.3 邏輯運算符 61
3.2 條件運算符和條件錶達式 62
3.3 ++、操作符 63
3.4 位運算 64
3.4.1 按位與運算及應用 64
3.4.2 按位或運算及應用 64
3.4.3 按位異或運算及應用 65
3.4.4 左移和右移 65
3.5 C語言性能優化:使用位操作 65
第4章 語句 67
4.1 空語句 67
4.2 基礎語句 68
4.2.1 錶達式語句 68
4.2.2 函數調用語句 68
4.3 語句if 68
4.3.1 布爾變量與零值比較 69
4.3.2 整型變量與零值比較 69
4.3.3 浮點變量與零值比較 69
4.3.4 指針變量與零值比較 70
4.3.5 對if語句的補充說明 70
4.4 跳轉語句:goto 70
4.5 循環語句 71
4.5.1 do-while語句 72
4.5.2 for語句 72
4.5.3 循環語句的效率 74
4.6 break和continue 75
4.6.1 break語句 75
4.6.2 continue語句 75
4.7 switch語句 77
第5章 數組與指針 79
5.1 數組認知 79
5.2 使用數組之常見問題 80
5.2.1 數組的下標總是從0開始嗎 80
5.2.2 可以使用數組後麵第一個元素的地址嗎 81
5.2.3 為什麼要小心對待位於數組後麵的那些元素的地址呢 82
5.2.4 數組作為參數傳遞給函數時,可以通過sizeof得到數組的大小嗎 82
5.2.5 指針或帶下標的數組名都可以訪問元素,哪一種更好呢 83
5.2.6 可以把另外一個地址賦給一個數組名嗎 85
5.2.7 array_name和&array_name有什麼不同 86
5.2.8 為什麼用const說明的常量不能用來定義一個數組的初始大小 87
5.2.9 字符串和數組有什麼不同 87
5.3 指針 89
5.3.1 指針是變量 90
5.3.2 指針的類型和指針所指嚮的類型 90
5.3.3 指針的值 91
5.3.4 指針本身所占據的內存區 91
5.4 指針的運算 92
5.4.1 指針的算術運算 92
5.4.2 指針的關係運算 92
5.4.3 間接引用 93
5.4.4 最多可以使用幾層指針 93
5.5 常量指針和指針常量 95
5.5.1 常量指針與指針常量的實例 95
5.5.2 常量指針的應用 96
5.6 空指針及其使用 97
5.6.1 NULL總是被定義為0嗎 97
5.6.2 NULL總是等於0嗎 97
5.6.3 空指針的使用 98
5.7 指針void:萬能指針 99
5.8 指針數組與數組指針 100
5.9 字符串函數詳解 101
5.10 函數指針與指針函數 105
5.11 復雜指針聲明:“int * (* (*fp1) (int) ) [10];” 106
5.11.1 基礎 106
5.11.2 const修飾符 107
5.11.3 typedef的妙用 108
5.11.4 函數指針 109
5.11.5 右左法則 109
第6章 內存管理 111
6.1 你的數據放在哪裏 111
6.1.1 未初始化的全局變量(.bss段) 111
6.1.2 初始化過的全局變量(.data段) 112
6.1.3 常量數據(.rodata段) 112
6.1.4 代碼(.text段) 113
6.1.5 棧(stack) 113
6.1.6 堆(heap) 113
6.2 內存分配方式 114
6.3 野指針 115
6.4 常見的內存錯誤及對策 115
6.5 段錯誤以及調試方法 116
6.5.1 方法一:利用gdb逐步查找段錯誤 117
6.5.2 方法二:分析core文件 118
6.5.3 方法三:段錯誤時啓動調試 119
6.5.4 方法四:利用backtrace和objdump進行分析 120
6.6 指針與數組的對比 121
第7章 預處理、結構體 125
7.1 宏定義:#define 125
7.1.1 參宏定義 125
7.1.2 帶參宏定義 127
7.2 文件包含 128
7.3 條件編譯 129
7.4 宏定義使用技巧 131
7.5 關於#和## 132
7.6 結構體 133
7.6.1 內存字節對齊 135
7.6.2 內存對齊正式原則 138
7.7 #define和typedef的區彆 139
7.8 結構體和聯閤體的區彆 139
7.9 淺談C語言中的位段 139
7.9.1 位段的使用 140
7.9.2 位段結構在內存中的存儲方式 140
第8章 函數 141
8.1 函數聲明與定義 141
8.1.1 定義 141
8.1.2 聲明與定義不同 142
8.2 形式參數和實際參數 143
8.3 參數傳遞 143
8.3.1 簡單變量或數組元素作為函數參數 143
8.3.2 指針變量或數組名作為函數參數 144
8.3.3 數組名作函數參數 145
8.3.4 結構體數組作函數參數 146
8.4 如何編寫有多個返迴值的C語言函數 146
8.4.1 利用全局變量 146
8.4.2 傳遞數組指針 148
8.4.3 傳遞結構體指針 148
8.5 迴調函數 149
8.6 變參函數詳解:printf的實現 151
8.7 可變參數問題 152
第9章 編碼規範 155
9.1 排版 155
9.2 注釋 158
9.3 標示符名稱 163
第10章 shell編程 165
10.1 什麼是shell 165
10.2 幾種流行的shell 165
10.3 shell程序設計(基礎部分) 166
10.3.1 shell基本語法 166
10.3.2 shell程序的變量和參數 167
10.4 shell程序設計的流程控製 169
10.4.1 test測試命令 169
10.4.2 if條件語句 170
10.4.3 for循環 171
10.4.4 while和until循環 171
10.4.5 case條件選擇 172
10.4.6 條件控製語句break和continue 173
10.4.7 函數定義 173
10.5 命令分組 174
10.6 信號 174
10.7 運行shell程序的方法 175
10.8 bash程序的調試 175
10.9 bash的內部命令 176
第11章 文件操作 179
11.1 Linux文件結構 179
11.1.1 Linux文件係統 179
11.1.2 Linux目錄結構 180
11.1.3 Linux文件分類 182
11.1.4 常見文件類型 183
11.1.5 Linux文件屬性 183
11.2 係統調用 184
11.3 Linux文件描述符 184
11.4 不帶緩存的I/O操作 185
11.4.1 creat函數 185
11.4.2 open函數 186
11.4.3 read函數 188
11.4.4 write函數 189
11.4.5 lseek函數 189
11.4.6 close函數 189
11.4.7 經典範例:文件復製 190
11.5 帶緩存的I/O操作 191
11.5.1 三種類型的緩衝 191
11.5.2 fopen函數 193
11.5.3 fclose函數 194
11.5.4 fdopen函數 194
11.5.5 fread函數 195
11.5.6 fwrite函數 195
11.5.7 fseek函數 196
11.5.8 fgetc函數、getc函數和getchar函數 197
11.5.9 fputc函數、putc函數和putchar函數 198
11.6 fgets函數與gets函數比較分析 199
11.7 輸齣與輸入 201
11.7.1 printf函數、fprintf函數和sprintf函數 201
11.7.2 scanf函數、fcanf函數和sscanf函數 203
第12章 進程控製編程 207
12.1 為何需要多進程(或者多綫程),為何需要並發 207
12.1.1 進程 207
12.1.2 進程分類 208
12.1.3 進程的屬性 208
12.1.4 父進程和子進程 208
12.2 Linux進程管理 209
12.2.1 ps監視進程工具 209
12.2.2 pgrep查詢進程工具 211
12.2.3 終止進程的工具kill、killall、pkill、xkill 211
12.2.4 top監視係統任務的工具 213
12.2.5 進程的優先級:nice和renice 214
12.3 Linux進程的三態 215
12.3.1 三種基本狀態 215
12.3.2 三種狀態間的轉換 215
12.4 Linux進程結構 216
12.5 Linux進程控製塊PCB 216
12.6 Linux進程調度 218
12.6.1 調度的目標 218
12.6.2 調度算法 218
12.6.3 優先級反轉 220
12.7 進程創建 221
12.7.1 獲取進程 221
12.7.2 啓動進程:fork( ) 222
12.7.3 啓動進程:vfork( ) 224
12.7.4 啓動進程:exec族 225
12.7.5 啓動進程:system 228
12.8 進程等待 229
12.8.1 僵屍進程的産生 229
12.8.2 如何避免僵屍進程 231
12.8.3 wait函數和waitpid函數 231
12.9 進程退齣 235
12.9.1 退齣方式的不同點 236
12.9.2 exit( )和_exit( )函數 236
12.9.3 exit( )和_exit( )的區彆 237
第13章 進程間通信方式 239
13.1 進程間通信方式概述 239
13.1.1 進程間通信的目的 239
13.1.2 Linux進程間通信方式簡介 240
13.2 管道通信 241
13.2.1 建立名管道 241
13.2.2 讀寫名管道 242
13.2.3 名管道應用實例 246
13.2.4 創建有名管道 248
13.2.5 讀寫有名管道 250
13.3 管道通信方式的應用場景 253
13.4 信號 254
13.4.1 信號及信號來源 254
13.4.2 信號種類 254
13.4.3 信號處理方式 256
13.4.4 信號發送 256
13.4.5 自定義處理信號方式 258
13.4.6 信號集操作 262
13.4.7 使用信號注意事項 264
13.5 消息隊列 265
13.5.1 消息隊列基礎理論 266
13.5.2 使用消息隊列 266
13.5.3 消息隊列API 267
13.5.4 消息隊列的限製 269
13.5.5 消息隊列的應用實例 270
13.6 信號燈 273
13.6.1 信號燈概述 273
13.6.2 內核實現原理 274
13.6.3 使用信號燈 274
13.6.4 信號燈API 275
13.6.5 信號燈的限製 277
13.6.6 競爭問題 277
13.6.7 信號燈應用實例 277
13.7 共享內存方式一 281
13.7.1 內核實現原理 281
13.7.2 mmap( )及其相關係統調用 282
13.7.3 mmap( )範例 283
13.7.4 對mmap( )返迴地址的訪問 287
13.8 共享內存方式二 289
13.8.1 係統V共享內存原理 289
13.8.2 係統V共享內存API 290
13.8.3 係統V共享內存範例 291
第14章 多綫程編程 295
14.1 綫程概述 295
14.1.1 為什麼有瞭進程的概念後,還要再引入綫程呢 295
14.1.2 多綫程的優點 296
14.1.3 多綫程的缺點 296
14.2 多綫程的實現 297
14.2.1 綫程的創建 297
14.2.2 終止綫程 299
14.2.3 等待綫程終止 300
14.3 綫程屬性 300
14.3.1 綫程屬性初始化 301
14.3.2 綫程分離 301
14.3.3 綫程的繼承性 302
14.3.4 綫程的調度策略 303
14.3.5 綫程的調度參數 304
14.3.6 實例分析 305
14.4 綫程同步機製 306
14.4.1 互斥鎖Mutex 306
14.4.2 互斥鎖使用實例 308
14.4.3 條件變量Conditions 310
14.4.4 條件變量使用實例 311
第15章 網絡編程 313
15.1 TCP/IP協議概述 313
15.1.1 TCP/IP 起源 313
15.1.2 TCP/IP的特性與應用 315
15.1.3 互聯網地址 315
15.1.4 域名係統 316
15.1.5 封裝 317
15.1.6 TCP/IP工作模型 318
15.1.7 TCP/IP 協議層 318
15.1.8 TCP/IP應用 320
15.1.9 網橋、路由器和網關 321
15.2 TCP和UDP 322
15.2.1 TCP協議 322
15.2.2 三次握手協議 322
15.2.3 TCP數據報頭 323
15.2.4 UDP協議 324
15.2.5 協議的選擇 324
15.2.6 IP和端口號 324
15.3 套接字 325
15.3.1 Socket概念 325
15.3.2 Socket類型 325
15.3.3 Socket信息數據結構 325
15.3.4 數據存儲優先順序的轉換 326
15.3.5 地址格式轉化 327
15.3.6 名字地址轉化 328
15.4 網絡編程 330
15.4.1 建立Socket 331
15.4.2 綁定地址 332
15.4.3 監聽 333
15.4.4 接受請求 334
15.4.5 連接服務器 335
15.4.6 發送數據 335
15.4.7 接收數據 336
15.5 采用TCP協議的C/S架構實現 338
15.5.1 模塊封
高質量嵌入式Linux C編程 下載 mobi epub pdf txt 電子書 格式