嵌入式系統(tǒng)架構(gòu)淺談:編程設(shè)計(jì)模式 (一)---訪問(wèn)硬件的設(shè)計(jì)模式
掃描二維碼
隨時(shí)隨地手機(jī)看文章
這系列開(kāi)始談軟件上面的設(shè)計(jì),對(duì)設(shè)計(jì)模式在面向?qū)ο罄锩鎽?yīng)該各位都知道,或許你在實(shí)際開(kāi)發(fā)當(dāng)中用到,也或許你見(jiàn)過(guò)別人的代碼中用到。當(dāng)你程序的代碼足夠龐大的時(shí)候,你會(huì)發(fā)現(xiàn)維護(hù)寸步難行,牽一發(fā)而動(dòng)全身,這個(gè)時(shí)候你就能夠理解在開(kāi)發(fā)初期對(duì)程序架構(gòu)的搭建重要性。而架構(gòu)最基本熟知的其中就是設(shè)計(jì)模式,使用設(shè)計(jì)模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性、程序的重用性。嘗試去研究?jī)?yōu)秀的開(kāi)源代碼,你會(huì)驚嘆別人對(duì)程序的掌控,這時(shí)你會(huì)稍稍明白架構(gòu)的目的所在。
文章基于《C嵌入式編程設(shè)計(jì)模式》這本書(shū),英文是Design Patterns for Embedded Systems in C。主要是做個(gè)筆記,并添加一點(diǎn)個(gè)人的理解,分享出來(lái)與各位探討。比較針對(duì)嵌入式系統(tǒng),單片機(jī),程序已C語(yǔ)言為主,盡管是面向過(guò)程,但不妨礙我們使用面向?qū)ο蟮乃季S來(lái)開(kāi)發(fā)。
1. 訪問(wèn)硬件的設(shè)計(jì)模式
嵌入式系統(tǒng),特別單片機(jī)最明顯的是對(duì)硬件的直接訪問(wèn)?;A(chǔ)硬件不僅有CPU,內(nèi)存,鍵盤,傳感器,通訊RS232等這樣的設(shè)備。做單片機(jī)的不得不對(duì)硬件進(jìn)行控制,讀,寫(xiě)操作,而這篇文章已解決管理和操作這些硬件通常的一個(gè)模式?;蛟S對(duì)你來(lái)說(shuō)并不陌生,但是是否能夠系統(tǒng)的,詳細(xì)的表達(dá)出來(lái)這就不僅僅只是了解就能達(dá)到的。
下面討論的設(shè)計(jì)模式已經(jīng)在操作硬件上得到證明是可靠有效的。簡(jiǎn)單總結(jié)說(shuō),硬件代理模式是以封裝詳細(xì)信息為目的的硬件抽象的一個(gè)原型模式,它有可能改變提供給硬件或來(lái)自硬件的信息處理方法。硬件適配器模式擴(kuò)展硬件代理模式,以提供支持不同硬件接口的能力。中介者支持多種硬件設(shè)備的協(xié)調(diào),實(shí)現(xiàn)系統(tǒng)級(jí)行為。觀察者模式是發(fā)布遙感數(shù)據(jù)到需要的軟件元素的方法。去抖動(dòng)模式和中斷模式是硬件設(shè)備接口簡(jiǎn)單重用的方法。定時(shí)器模式擴(kuò)展中斷定時(shí)器為嵌入式系統(tǒng)提供精確時(shí)序。
1.1 硬件代理模式
硬件代理模式概念是對(duì)訪問(wèn)硬件接口的封裝,限制客戶直接訪問(wèn)硬件造成問(wèn)題。
1.1.1 模式結(jié)構(gòu)
模式結(jié)構(gòu)非常簡(jiǎn)單,可能客戶會(huì)有多個(gè),但是每個(gè)硬件設(shè)備僅有一個(gè)硬件代理,客戶只能訪問(wèn)代理接口,無(wú)法直接訪問(wèn)硬件就是這個(gè)模式的目的。
1.1.2 角色
1.1.2.1 硬件設(shè)備(HardwareDevice)
硬件設(shè)備可以是各種,內(nèi)存,傳感器等,包含了端口地址,內(nèi)存地址,寄存器地址等等元素。與硬件代理的關(guān)聯(lián)是通過(guò)軟件尋址方式,對(duì)硬件的讀寫(xiě)操作。
1.1.2.2 硬件代理(HardwareProxy)
這個(gè)是系統(tǒng)中的主功能。給上層應(yīng)用提供的硬件訪問(wèn)接口,上層應(yīng)用無(wú)須詳細(xì)關(guān)心硬件的具體實(shí)現(xiàn)?;旧贤ǔC總€(gè)代理都有initialize()、configure()和disable()函數(shù)。大部分還會(huì)有對(duì)設(shè)備的值讀取訪問(wèn),或者寫(xiě)訪問(wèn)接口。但是一般不能隨意讀寫(xiě),會(huì)詳細(xì)到讀取到最終的值。
函數(shù)包括:
access():從設(shè)備返回一個(gè)特殊值。大多數(shù)情況下,代理會(huì)對(duì)每個(gè)來(lái)自設(shè)備單獨(dú)的信息提供單獨(dú)的函數(shù)。例如返回傳感器的溫度,濕度值。
configure():提供硬件配置的方法。一般會(huì)有參數(shù)列表,通過(guò)傳入?yún)?shù)來(lái)配置正確的工作狀態(tài)。
disable()、enable():提供設(shè)備的安全禁用或開(kāi)啟的方法。
initialize():用于第一次啟動(dòng)時(shí)候的初始化硬件。
mutate():用于向設(shè)備寫(xiě)入數(shù)據(jù),通常總是有一個(gè)或更多的輸入?yún)?shù)。
marshal()、unmarshal():這兩個(gè)為私有函數(shù),用于把客戶數(shù)據(jù)格式轉(zhuǎn)為硬件所需格式,后者相反,把硬件原始數(shù)據(jù)格式轉(zhuǎn)換為客戶格式。常用于加密解密,壓縮解壓縮等。
deviceAddr:是一個(gè)私有變量,提供底層直接訪問(wèn)硬件的地址。必須隱藏在代理中,不能給客戶訪問(wèn)的機(jī)會(huì),所以特別注意到一些接口,是否會(huì)通過(guò)了指針把該變量暴露出去。
1.1.2.3 代理客戶(ProxyClient)
客戶代碼調(diào)用硬件代理服務(wù)來(lái)訪問(wèn)硬件設(shè)備。
1.1.3 效果
該模式非常普遍并且具有封裝硬件接口以及編碼系統(tǒng)的所有優(yōu)點(diǎn)。這為不對(duì)客戶端進(jìn)行任何改變而從根本上改變實(shí)際硬件接口提供了靈活性。基本上所有的硬件設(shè)備都能用此模式搭建,注意的是不能暴露細(xì)節(jié),只能返回一個(gè)最后的結(jié)果,特別在讀寫(xiě)操作,否則就不具備有封裝性了。
1.1.4 實(shí)現(xiàn)
可以有很多不同方法用C語(yǔ)言實(shí)現(xiàn),最常見(jiàn)的是如linux驅(qū)動(dòng),使用結(jié)構(gòu)體里的函數(shù)指針統(tǒng)一硬件的接口。然后在具體的硬件設(shè)備上實(shí)現(xiàn)。
1.2 適配器模式
硬件適配器模式提供一種方法,使已經(jīng)存在硬件接口能適用應(yīng)用期望??梢哉f(shuō)是在硬件代理模式基礎(chǔ)上,為了能夠適應(yīng)底層不同的硬件設(shè)備,在中間增加一層適配器。比如在通訊上面在硬件上都存在RS232,RS485,程序需要在不同情況下使用232通訊或485通訊,而適配器可以提供統(tǒng)一的接口給客戶層,通過(guò)指針指向所需通訊,則可以實(shí)現(xiàn)。最大的特點(diǎn)是在運(yùn)行中選擇,相比使用宏定義需要生成不同執(zhí)行程序,可以在程序中實(shí)現(xiàn)自適應(yīng)的功能。
1.2.1 模式結(jié)構(gòu)
1.2.2 角色
1.2.2.1 硬件適配器(HardwareAdapter)
硬件適配器在客戶和硬件代理之間執(zhí)行匹配??蛻舾嬷m配器所需的硬件設(shè)備,適配器執(zhí)行客戶的請(qǐng)求。
1.2.2.2 客戶硬件接口(HardwareInterfaceToClient)
客戶的硬件接口表示客戶期望硬件代理提供的一組服務(wù)和參數(shù)列表。僅僅作為接口,并沒(méi)有實(shí)現(xiàn),是通過(guò)適配器提供硬件實(shí)現(xiàn)。
1.2.2.3 硬件設(shè)備(HardwareDevice)
與硬件代理模式中描述一致。
1.2.2.4 硬件代理(HardwareProxy)
與硬件代理模式中描述一致。
1.2.3 效果
該模式允許使用各種硬件代理,并且在不同的應(yīng)用中使用與它們相關(guān)的硬件設(shè)備,同時(shí)亦有的應(yīng)用使用不同的硬件設(shè)備時(shí)不需要做改變。我個(gè)人理解有點(diǎn)類似是面向?qū)ο笳Z(yǔ)言中的多態(tài)概念。
1.2.4 實(shí)現(xiàn)
同樣如linux系統(tǒng)驅(qū)動(dòng),創(chuàng)建一個(gè)結(jié)構(gòu)體的接口代理,硬件設(shè)備使用這些接口具體實(shí)現(xiàn),然后使用一個(gè)指向結(jié)構(gòu)體接口的指針,把需要使用的硬件設(shè)備注冊(cè)到指針上,客戶代碼只需調(diào)用這個(gè)指針,即可操作具體的硬件設(shè)備,而且可以動(dòng)態(tài)的修改指針的指向,從而實(shí)現(xiàn)動(dòng)態(tài)的加載切換。
1.3 中介者模式
中介者模式提供的是為一組硬件設(shè)備復(fù)雜交互協(xié)調(diào)的一個(gè)方法。
1.3.1 模式結(jié)構(gòu)
中介者模式使用一個(gè)中介類來(lái)協(xié)調(diào)各個(gè)設(shè)備集合的行為,來(lái)達(dá)到整理的一個(gè)效果。這里舉一個(gè)具體的例子,比如一臺(tái)車有4個(gè)輪子,也就4個(gè)電機(jī)設(shè)備,當(dāng)向前行駛的時(shí)候四個(gè)輪子都是向前前進(jìn),這時(shí)候中介者就承擔(dān)了控制4個(gè)輪子的責(zé)任。所以說(shuō)中介者其實(shí)就是一個(gè)中央控制。
1.3.2 角色
1.3.2.1 合作者接口(CollaboaratorInterface)
是被中介者調(diào)用的接口,對(duì)于硬件通常是initaialize(),enable(),reset()等這類函數(shù),但是具體的是在具體合作者實(shí)現(xiàn)。
1.3.2.2 中介者(Mediator)
在模式中協(xié)調(diào)所有的具體合作者。中介者對(duì)于每個(gè)具體合作者都有一個(gè)鏈接,以便他能給具體合作者發(fā)送信息。此外,當(dāng)有事情發(fā)生時(shí),每個(gè)具體合作者必須能給中介者發(fā)送消息。中介者提供協(xié)調(diào)的邏輯。
1.3.2.3 具體合作者(SpecificCollaborator)
表示一個(gè)硬件設(shè)備??梢詮闹薪檎攉@取命令,也可以發(fā)送信息給中介者。
1.3.3 效果
該模式創(chuàng)建中介者來(lái)協(xié)調(diào)合作具體硬件,但是對(duì)客戶來(lái)說(shuō)又不需要直接耦合硬件設(shè)備,極大的簡(jiǎn)化了整理的設(shè)計(jì)。很多嵌入式系統(tǒng)必須高精度時(shí)間相應(yīng),動(dòng)作的延時(shí)可能造成不可估計(jì)的影響,中介者能夠在這些規(guī)定時(shí)間反應(yīng)很重要。
1.3.4 實(shí)現(xiàn)
中介者的實(shí)現(xiàn)可以通過(guò)指針數(shù)組,鏈表等,能夠連接到每個(gè)具體的合作者。另外統(tǒng)一接口能夠給中介者代碼上帶來(lái)很多便利。
1.4 觀察者模式
觀察者模式非常的普遍,你可以在任何地方看到它的身影。這模式提供一個(gè)方法來(lái)“監(jiān)聽(tīng)”所感興趣的消息,而不需要修改數(shù)據(jù)服務(wù)器,這意味著傳感器數(shù)據(jù)很容易分享給所需的客戶。
1.4.1 模式結(jié)構(gòu)
觀察者模式,另外一個(gè)名字是“發(fā)布-訂閱模式”。首先模式下數(shù)據(jù)服務(wù)器不需要清楚客戶,相反是由客戶通知數(shù)據(jù)服務(wù)器,也就是訂閱。訂閱意思是允許數(shù)據(jù)服務(wù)器在通知列表中添加(和刪除)自身。最常見(jiàn)的通知策略是當(dāng)新數(shù)據(jù)到達(dá)服務(wù)器時(shí),服務(wù)器發(fā)送數(shù)據(jù)。但是客戶也能定期更新,向服務(wù)器獲取數(shù)據(jù),以減小服務(wù)器的計(jì)算負(fù)擔(dān),確保客戶具有實(shí)時(shí)數(shù)據(jù)。另外更復(fù)雜的模式是在數(shù)據(jù)服務(wù)器和客戶中間添加一層中央控制器,用于連接服務(wù)器與客戶的通訊,這樣服務(wù)器就完全不需要與客戶直接聯(lián)系。如果有大量使用消息使用觀察者模式,添加中央不失為一種好方法。
1.4.2 角色
1.4.2.1 抽象客戶接口(AbstratClient)
它包含了accept(Datum)函數(shù),當(dāng)AbstratClient訂閱時(shí)或者AbstratSubject認(rèn)為有適合發(fā)送數(shù)據(jù)去調(diào)用它。AbstratClient是抽象的,不提供任何具體實(shí)現(xiàn)。
1.4.2.2 抽象發(fā)布接口(AbstratSubject)
在模式中AbstratSubject是數(shù)據(jù)服務(wù)器。在提供模式相關(guān)的3個(gè)函數(shù)。subscribe(acceptPtr)服務(wù)添加指向接收函數(shù)通知列表的指針。unsubscribe(acceptPtr)函數(shù)從通知列表中刪除接收功能。最后,notify()函數(shù)遍歷通知列表通知訂閱的客戶。
1.4.2.3 具體客戶(concreteClient)
concreteClient是AbstratClient接口的具體實(shí)現(xiàn)。
1.4.2.4 具體發(fā)布(concreteSubject)
concreteSubject是AbstratSubject接口的具體實(shí)現(xiàn)。不僅提供函數(shù)的實(shí)現(xiàn),而且提供獲取和管理它發(fā)布數(shù)據(jù)的方法。扮演concreteSubject也可以是硬件設(shè)備,傳感器等。
1.4.2.5 數(shù)據(jù)(Datum)
該元素是實(shí)際的數(shù)據(jù)包,可以是int,更多的是復(fù)雜的結(jié)構(gòu)體。
1.4.2.6 回調(diào)接口(NotificationHandle)
NotificationHandle是調(diào)用客戶的accept方法的代表。最常見(jiàn)的實(shí)現(xiàn)方式是函數(shù)指針。
1.4.3 效果
觀察者模式是在服務(wù)器分配數(shù)據(jù)的過(guò)程,并且在運(yùn)行時(shí)可以動(dòng)態(tài)地管理客戶列表。實(shí)際一個(gè)例子,讀取硬件的值,通常我們可能是使用輪詢的方式讀取,輪詢的弊端是響應(yīng)不及時(shí),讀取間隔時(shí)間很難去固定和評(píng)估。另一種方法是定時(shí)中斷讀取,但是定時(shí)讀取未必每次都會(huì)有數(shù)據(jù)產(chǎn)生。還有是觸發(fā)中斷的方法,如果在中斷讀取數(shù)據(jù)后,需要計(jì)算,在中斷里進(jìn)行可能不太好,原則是盡量不要中斷占用太多的CPU。這個(gè)時(shí)候觀察者模式的好處體現(xiàn)出來(lái)了,首先能夠保證響應(yīng)及時(shí),因?yàn)槭褂玫幕卣{(diào)方式,第二能一個(gè)硬件發(fā)布,多個(gè)接收客戶,一對(duì)多的模式,第三能夠確保每次執(zhí)行客戶回調(diào)都能有數(shù)據(jù)產(chǎn)生。其實(shí)觀察者模式隨處可見(jiàn),ROS系統(tǒng)的節(jié)點(diǎn)通訊就是基于這個(gè)策略。該模式明顯的缺點(diǎn)是實(shí)現(xiàn)較復(fù)雜,而且當(dāng)然也不是所有情況都適應(yīng),希望各位能夠詳細(xì)分析后,選擇合適的方法。
1.4.4 實(shí)現(xiàn)
該模式復(fù)雜的方面在通知句柄的實(shí)現(xiàn),以及通知句柄列表的管理。通知句柄通常是一個(gè)回調(diào)函數(shù)指針。通知列表最簡(jiǎn)單的方式是定義足夠大的數(shù)組來(lái)包含所有潛在用戶,但是實(shí)際占用空間大浪費(fèi)內(nèi)存,所以并不常用。另一個(gè)常見(jiàn)的是使用鏈表管理,也就是給每個(gè)通知句柄添加在鏈表上,這樣只要遍歷鏈表即可通知所有客戶,強(qiáng)烈推薦使用鏈表形式。
1.5 去抖動(dòng)模式
這個(gè)模式用于消除來(lái)自硬件金屬表面間歇性連接引起的多個(gè)假時(shí)間。
1.5.1 模式結(jié)構(gòu)
解決的方案是接受第一次發(fā)生的事件,等待抖動(dòng)減弱,然后再對(duì)讀取它的狀態(tài)。
1.5.2 角色
1.5.2.1 應(yīng)用客戶(ApplicationClient)
該元素是去抖動(dòng)最后的接受者。當(dāng)在抖動(dòng)消除后,使用deviceEventReceive()接收最后讀取到的值。
1.5.2.2 具體硬件(BouncingDevice)
代表了硬件設(shè)備。這個(gè)設(shè)備絕大部分都是全硬件,機(jī)械特性的,所以才會(huì)引起抖動(dòng)的現(xiàn)象。sendEvent()用于發(fā)送事件,激活中斷接收到首次的響應(yīng)。getState()操作時(shí)通過(guò)讀取內(nèi)存或IO端口顯示,讀取具體的硬件值。deviceState通常是二值屬性,即ON或OFF。
1.5.2.3 硬件客戶(DeviceClient)
是用于處理進(jìn)入事件的中斷,去除抖動(dòng),并讀取確保代表實(shí)際設(shè)備狀態(tài)。它的eventRecevie()函數(shù)通過(guò)BouncingDevice的sendEvent()函數(shù)激活。同時(shí),它需要設(shè)置延時(shí)定時(shí)器,去抖動(dòng)事件過(guò)后,如果狀態(tài)與第一次讀取的一致,證明值是真實(shí)的。這樣它就發(fā)送相應(yīng)的信息給ApplicationClient。舊狀態(tài)保存在變量oldState中,每當(dāng)狀態(tài)發(fā)生改變的時(shí)候更新這個(gè)變量。
1.5.2.4 定時(shí)器(DebouncingTimer)
這個(gè)定時(shí)器可以通過(guò)delay()服務(wù)來(lái)提供空閑等待??梢允褂脀hile()等待,或者硬件定時(shí)器實(shí)現(xiàn)。
1.5.3 效果
通常去抖動(dòng)的任務(wù)是由軟件來(lái)承擔(dān),這是一個(gè)簡(jiǎn)單的去抖動(dòng),應(yīng)用程序只需要關(guān)心硬件狀態(tài)產(chǎn)生的真實(shí)值才接收。
1.5.4 實(shí)現(xiàn)
硬件客戶通常使用中斷來(lái)通知應(yīng)用客戶?;蛘呤褂糜^察者模式混合也可以給等個(gè)客戶提供信號(hào)。在RTOS系統(tǒng)去抖動(dòng)必須注意時(shí)間單位的延時(shí)時(shí)間,比如如果想要45毫秒的延時(shí),那么必須使用大于等于期望時(shí)間最接近時(shí)間精度。如果在等待去抖動(dòng)時(shí),你不介意完全占用CPU,那么這就很簡(jiǎn)單,使用while(loop--)循環(huán)就好了。
1.6 中斷模式
在嵌入式系統(tǒng),硬件設(shè)備很多時(shí)候都是自主發(fā)生,如果你不加以注意,這些事件就會(huì)丟失。當(dāng)一個(gè)你感興趣的事件發(fā)生時(shí),使用中斷來(lái)通知是非常有效的方法。基本上芯片都支持外部硬件中斷的方式。中斷能保證響應(yīng)的及時(shí),但是中斷會(huì)搶占CPU的控制,所以中斷里面不適合處理算法等這種耗時(shí)長(zhǎng)的任務(wù)。這個(gè)模式下可以是純軟件的中斷模式。
1.6.1 模式結(jié)構(gòu)
確保中斷函數(shù)一般是沒(méi)有入?yún)ⅲ头祷刂档摹?
1.6.2 角色
1.6.2.1 中斷響應(yīng)(InterruptHandler)
是中斷模式里面唯一有具體行為的元素。它能夠安裝和卸載中斷向量的功能。install()函數(shù)運(yùn)行時(shí),拷貝傳入的中斷句柄到向量表中,使用合適的中斷服務(wù)程序地址。deinstall()函數(shù)相反,用于卸載回復(fù)原本的向量表。
每個(gè)handleInterrupt_x()函數(shù)處理指定的中斷。
1.6.2.2 中斷向量表(InterruptVectorTable)
就是中斷服務(wù)程序的地址數(shù)組。它依賴在指定的內(nèi)存位置上。當(dāng)中斷號(hào)x出現(xiàn)時(shí),CPU掛起當(dāng)前進(jìn)程,調(diào)用這個(gè)數(shù)組中相應(yīng)的第x個(gè)索引地址。
1.6.2.3 向量指針(VectorPtr)
VectorPtr是數(shù)據(jù)類型,具體是一個(gè)沒(méi)有參數(shù)和返回值的函數(shù)指針。
1.6.3 效果
該模式最大的優(yōu)勢(shì)是可以高響應(yīng)處理感興趣的事件。通常情況下,當(dāng)中斷服務(wù)程序執(zhí)行時(shí),關(guān)閉中斷,這意味著中斷服務(wù)程序必須快速執(zhí)行以確保不會(huì)丟失其他中斷。
使用中斷有點(diǎn)特別注意是資源的保護(hù)。當(dāng)有可能會(huì)在中斷和普通程序中處理了同一個(gè)元素,設(shè)想當(dāng)普通程序讀取數(shù)據(jù)中途發(fā)生了中斷,而中斷會(huì)導(dǎo)致普通程序暫停,然后在中斷里面修改了數(shù)據(jù)返回。普通函數(shù)將會(huì)讀取損壞的數(shù)據(jù),即部分是新數(shù)據(jù),部分是舊數(shù)據(jù)。解決方法有1.在普通函數(shù)讀取數(shù)據(jù)時(shí)禁止中斷,訪問(wèn)完成后恢復(fù)中斷。2.使用互斥信號(hào)量。
1.6.4 實(shí)現(xiàn)
中斷函數(shù)執(zhí)行之前必須保存現(xiàn)場(chǎng),在執(zhí)行完成需要恢復(fù)現(xiàn)場(chǎng)。事實(shí)上每個(gè)中斷服務(wù)程序必須:
-
保存CPU寄存器,包括CPU指令指針和任何處理器標(biāo)志,如進(jìn)位,奇偶校驗(yàn)。
-
清除終端位。
-
執(zhí)行適當(dāng)處理。
-
恢復(fù)CPU寄存器。
-
返回。
1.7 輪詢模式
另一種從硬件獲取數(shù)據(jù)常用的模式是定期檢查,稱為輪詢過(guò)程。當(dāng)數(shù)據(jù)或信號(hào)不是很緊急,或者當(dāng)數(shù)據(jù)可用時(shí),硬件沒(méi)有能力產(chǎn)生中斷,又或者硬件本身能保留數(shù)據(jù)到下次讀取情況,這是輪詢就非常好用。
1.7.1 模式結(jié)構(gòu)
輪詢模式是讀取硬件上數(shù)據(jù)最簡(jiǎn)單的方法。輪詢能夠定期或不定期進(jìn)行,可以是定時(shí)器讀取,也可以當(dāng)系統(tǒng)需要時(shí)讀取。
1.7.2 角色
1.7.2.1 應(yīng)用過(guò)程(ApplicationProcessingElement)
這個(gè)元素用于循環(huán)調(diào)用poll()操作。這個(gè)也可以是定時(shí)器中斷里面。
1.7.2.2 硬件(Device)
Device通過(guò)可訪問(wèn)的函數(shù)提供數(shù)據(jù)或設(shè)備狀態(tài)信息。這個(gè)類上面實(shí)例了兩個(gè)方法,getData()用來(lái)獲取數(shù)據(jù),getState()用來(lái)獲取數(shù)據(jù)狀態(tài)。MAX_POLL_DEVICE連接到所有的硬件設(shè)備,以便poll()函數(shù)全部能夠掃描并通知給客戶。
1.7.2.3 輪詢者(OpportunisticPoller)
具有poll()函數(shù),用于掃描連接的設(shè)備以讀取數(shù)據(jù)和狀態(tài),并把數(shù)據(jù)轉(zhuǎn)發(fā)給客戶。這個(gè)元素可以添加定時(shí)器操作,實(shí)現(xiàn)定期讀取數(shù)據(jù)的功能。
1.7.2.4 客戶(PollDataClient)
該元素來(lái)自一個(gè)或多個(gè)設(shè)備數(shù)據(jù)和狀態(tài)信息的客戶。
1.7.3 效果
輪詢比使用中斷服務(wù)簡(jiǎn)單的多,能夠同時(shí)檢測(cè)多種不同的設(shè)備,但是基本上沒(méi)有中斷響應(yīng)那樣及時(shí),所以使用輪詢最好確保最長(zhǎng)的讀取間隔時(shí)間,確保在一個(gè)時(shí)間內(nèi)至少讀取一次數(shù)據(jù),否則數(shù)據(jù)將會(huì)丟失,但有時(shí)候這不是一個(gè)問(wèn)題,所以具體情況就具體分析。
1.7.4 實(shí)現(xiàn)
最簡(jiǎn)單的顯示方法是在系統(tǒng)操作的主進(jìn)程循環(huán)中插入硬件檢查,這叫做“對(duì)稱機(jī)會(huì)輪詢”,因?yàn)樗偸且酝瑯拥姆绞讲僮?,即使處理循環(huán)事件長(zhǎng)度可能變化。非對(duì)稱機(jī)會(huì)輪詢是在整個(gè)進(jìn)程中方便時(shí)候讀取新數(shù)據(jù)(對(duì)稱是固定位置讀取數(shù)據(jù),非對(duì)稱是在需要的時(shí)候再讀?。?,這種方式具有更好的響應(yīng),但是對(duì)主流程有更大影響,而且難以維護(hù)。
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!