“生產(chǎn)者消費(fèi)者”問(wèn)題是一個(gè)著名的同時(shí)性編程問(wèn)題的集合。通過(guò)學(xué)習(xí)經(jīng)典的“生產(chǎn)者消費(fèi)者”問(wèn)題的實(shí)驗(yàn),讀者可以進(jìn)一步熟悉Linux中的多線(xiàn)程編程,并且掌握用信號(hào)量處理線(xiàn)程間的同步和互斥問(wèn)題。
讀者一定都聽(tīng)說(shuō)過(guò)著名的OSI協(xié)議參考模型,它是基于國(guó)際標(biāo)準(zhǔn)化組織(ISO)的建議發(fā)展起來(lái)的,從上到下共分為7層:應(yīng)用層、表示層、會(huì)話(huà)層、傳輸層、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層及物理層。這個(gè)7層的協(xié)議模型雖然規(guī)定得非常細(xì)致和完善,但在實(shí)際中卻得不到廣泛的應(yīng)用,其重要的原因之一就在于它過(guò)于復(fù)雜。
本章首先介紹了線(xiàn)程的基本概念、線(xiàn)程的分類(lèi)和特性以及線(xiàn)程的發(fā)展歷程。
在Linux中的網(wǎng)絡(luò)編程是通過(guò)socket接口來(lái)進(jìn)行的。人們常說(shuō)的socket是一種特殊的I/O接口,它也是一種文件描述符。socket是一種常用的進(jìn)程之間通信機(jī)制,通過(guò)它不僅能實(shí)現(xiàn)本地機(jī)器上的進(jìn)程之間的通信,而且通過(guò)網(wǎng)絡(luò)能夠在不同機(jī)器上的進(jìn)程之間進(jìn)行通信。
在實(shí)際情況中,人們往往遇到多個(gè)客戶(hù)端連接服務(wù)器端的情況。由于之前介紹的如connet()、recv()和send()等都是阻塞性函數(shù),如果資源沒(méi)有準(zhǔn)備好,則調(diào)用該函數(shù)的進(jìn)程將進(jìn)入睡眠狀態(tài),這樣就無(wú)法處理I/O多路復(fù)用的情況了。本節(jié)給出了兩種解決I/O多路復(fù)用的解決方法,這兩個(gè)函數(shù)都是之前學(xué)過(guò)的fcntl()和select()。
通過(guò)實(shí)現(xiàn)NTP協(xié)議的練習(xí),進(jìn)一步掌握Linux網(wǎng)絡(luò)編程,并且提高協(xié)議的分析與實(shí)現(xiàn)能力,為參與完成綜合性項(xiàng)目打下良好的基礎(chǔ)。
本章首先概括地講解了OSI分層結(jié)構(gòu)以及TCP/IP協(xié)議各層的主要功能,介紹了常見(jiàn)的TCP/IP協(xié)議族,并且重點(diǎn)講解了網(wǎng)絡(luò)編程中需要用到的TCP和UDP協(xié)議,為嵌入式Linux的網(wǎng)絡(luò)編程打下良好的基礎(chǔ)。
操作系統(tǒng)是通過(guò)各種驅(qū)動(dòng)程序來(lái)駕馭硬件設(shè)備的,它為用戶(hù)屏蔽了各種各樣的設(shè)備,驅(qū)動(dòng)硬件是操作系統(tǒng)最基本的功能,并且提供統(tǒng)一的操作方式。設(shè)備驅(qū)動(dòng)程序是內(nèi)核的一部分,硬件驅(qū)動(dòng)程序是操作系統(tǒng)最基本的組成部分,在Linux內(nèi)核源程序中也占有60%以上。因此,熟悉驅(qū)動(dòng)的編寫(xiě)是很重要的。
設(shè)備驅(qū)動(dòng)程序可以使用模塊的方式動(dòng)態(tài)加載到內(nèi)核中去。加載模塊的方式與以往的應(yīng)用程序開(kāi)發(fā)有很大的不同。以往在開(kāi)發(fā)應(yīng)用程序時(shí)都有一個(gè)main()函數(shù)作為程序的入口點(diǎn),而在驅(qū)動(dòng)開(kāi)發(fā)時(shí)卻沒(méi)有main()函數(shù),模塊在調(diào)用insmod命令時(shí)被加載,此時(shí)的入口點(diǎn)是init_module()函數(shù),通常在該函數(shù)中完成設(shè)備的注冊(cè)。
Qt/Embedded以原始Qt為基礎(chǔ),并做了許多出色的調(diào)整以適用于嵌入式環(huán)境。Qt/Embedded通過(guò)Qt API與Linux I/O設(shè)施直接交互,成為嵌入式Linux端口。同Qt/X11相比,Qt/Embedded很省內(nèi)存,因?yàn)樗恍枰粋€(gè)X服務(wù)器或是Xlib庫(kù),它在底層拋棄了X lib,采用framebuffer)作為底層圖形接口
FS2410開(kāi)發(fā)板的S3C2410處理器具有117個(gè)多功能通用I/O(GPIO)端口管腳,包括GPIO 8個(gè)端口組,分別為GPA(23個(gè)輸出端口)、GPB(11個(gè)輸入/輸出端口)、GPC(16個(gè)輸入/輸出端口)、GPD(16個(gè)輸入/輸出端口)、GPE(16個(gè)輸入/輸出端口)、GPF(8個(gè)輸入/輸出端口)、GPH(11個(gè)輸入/輸出端口)。
前面所講述的驅(qū)動(dòng)程序中都沒(méi)有涉及中斷處理,而實(shí)際上,有很多Linux的驅(qū)動(dòng)都是通過(guò)中斷的方式來(lái)進(jìn)行內(nèi)核和硬件的交互。中斷機(jī)制提供了硬件和軟件之間異步傳遞信息的方式。硬件設(shè)備在發(fā)生某個(gè)事件時(shí)通過(guò)中斷通知軟件進(jìn)行處理。中斷實(shí)現(xiàn)了硬件設(shè)備按需獲得處理器關(guān)注的機(jī)制,與查詢(xún)方式相比可以大大節(jié)省CPU資源的開(kāi)銷(xiāo)。
LED和蜂鳴器是最簡(jiǎn)單的GPIO的應(yīng)用,都不需要任何外部輸入或控制。按鍵同樣使用GPIO接口,但按鍵本身需要外部的輸入,即在驅(qū)動(dòng)程序中要處理外部中斷。按鍵硬件驅(qū)動(dòng)原理圖如圖11-7所示。
該實(shí)驗(yàn)是編寫(xiě)最簡(jiǎn)單的字符驅(qū)動(dòng)程序,這里的設(shè)備也就是一段內(nèi)存,實(shí)現(xiàn)簡(jiǎn)單的讀寫(xiě)功能,并列出常用格式的Makefile以及驅(qū)動(dòng)的加載和卸載腳本。讀者可以熟悉字符設(shè)備驅(qū)動(dòng)的整個(gè)編寫(xiě)流程。
本章主要介紹了嵌入式Linux設(shè)備驅(qū)動(dòng)程序的開(kāi)發(fā)。首先介紹了設(shè)備驅(qū)動(dòng)程序的概念及Linux對(duì)設(shè)備驅(qū)動(dòng)的處理,這里要明確驅(qū)動(dòng)程序在Linux中的定位。
目前的桌面機(jī)操作系統(tǒng)大多有著美觀、操作方便、功能齊全的GUI(圖形用戶(hù)界面),例如KDE或者GNOME。GUI(圖形用戶(hù)界面)是指計(jì)算機(jī)與其使用者之間的對(duì)話(huà)接口,可以說(shuō),GUI是當(dāng)今計(jì)算機(jī)技術(shù)的重大成就。它的存在為使用者提供了友好便利的界面,并大大地方便了非專(zhuān)業(yè)用戶(hù)的使用,使得人們從繁瑣的命令中解脫出來(lái),可以通過(guò)窗口、菜單方便地進(jìn)行操作。
通過(guò)編寫(xiě)一個(gè)跳動(dòng)的“Hello,World”字符串,進(jìn)一步熟悉嵌入式Qt的開(kāi)發(fā)過(guò)程。
這里要講的線(xiàn)程相關(guān)操作都是用戶(hù)空間中的線(xiàn)程的操作。在Linux中,一般pthread線(xiàn)程庫(kù)是一套通用的線(xiàn)程庫(kù),是由POSIX提出的,因此具有很好的可移植性。
本章主要講解了嵌入式Linux的圖形編程。首先介紹了幾種常見(jiàn)的嵌入式圖形界面編程機(jī)制,并給出了它們之間的關(guān)系。
AND指令將表示的數(shù)值與寄存器的值按位(bitwise)做邏輯與操作,并將結(jié)果保存到目標(biāo)寄存器中,同時(shí)根據(jù)操作的結(jié)果更新CPSR寄存器。