《物聯(lián)網(wǎng)實(shí)例開發(fā)教程》課件第二章 nesC編程語言_第1頁(yè)
《物聯(lián)網(wǎng)實(shí)例開發(fā)教程》課件第二章 nesC編程語言_第2頁(yè)
《物聯(lián)網(wǎng)實(shí)例開發(fā)教程》課件第二章 nesC編程語言_第3頁(yè)
《物聯(lián)網(wǎng)實(shí)例開發(fā)教程》課件第二章 nesC編程語言_第4頁(yè)
《物聯(lián)網(wǎng)實(shí)例開發(fā)教程》課件第二章 nesC編程語言_第5頁(yè)
已閱讀5頁(yè),還剩19頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

2.1nesC概述2.2nesC語法2.3基于nesC語言的應(yīng)用程序2.1nesC概述1.?nesC的由來nesC是對(duì)C語言的擴(kuò)展,是基于TinyOS的結(jié)構(gòu)化概念和執(zhí)行模型而設(shè)計(jì)的,它把組件化/模塊化思想和基于事件驅(qū)動(dòng)的執(zhí)行模型結(jié)合起來。TinyOS是一種面向傳感器網(wǎng)絡(luò)的新型操作系統(tǒng),最初是用匯編語言和C語言編寫的,但在應(yīng)用過程中發(fā)現(xiàn),C語言不能有效方便地支持面向傳感器網(wǎng)絡(luò)的應(yīng)用和操作系統(tǒng)的開發(fā),相關(guān)工作人員為此對(duì)C語言進(jìn)行了一定的擴(kuò)展,開發(fā)出了nesC語言。2.?nesC的特點(diǎn)nesC使用C語言作為其基礎(chǔ)語言,它支持所有的C語言詞法和語法,其獨(dú)有的特色如下:(1)增加了組件(component)和接口(interface)的關(guān)鍵字定義。(2)定義了接口及如何使用接口表達(dá)組件之間關(guān)系的方法。(3)?nesC應(yīng)用程序都是由組件組成的,這些組件之間的連接是通過定義良好的、具有雙向性質(zhì)的接口完成的。(4)結(jié)構(gòu)和內(nèi)容的分離:程序由組件構(gòu)成,它們裝配在一起(“配線/連接”)構(gòu)成完整的程序。(5)根據(jù)接口的設(shè)置說明組件功能。(6)接口有雙向性:它們描述一組接口供給者(指令)提供的函數(shù)和一組被接口的使用者(事件)實(shí)現(xiàn)的函數(shù)。組件通過接口彼此靜態(tài)地相連,這增加了運(yùn)行時(shí)效率,而且允許更好的程序靜態(tài)分析。(7)?nesC基于由編譯器生成完整程序代碼的需求設(shè)計(jì),這考慮到較好的代碼重用和分析。3.?nesC語言規(guī)范(1)?nesC應(yīng)用程序由一個(gè)或多個(gè)組件連接而成。(2)一個(gè)組件可以提供或使用接口:組件中的command接口由組件本身實(shí)現(xiàn);組件中的event接口由調(diào)用者實(shí)現(xiàn);接口是雙向的,調(diào)用command接口必須實(shí)現(xiàn)其event接口。2.2nesC語法2.2.1接口1.接口的定義一個(gè)組件可以提供(provides)接口,也可以使用(uses)接口。提供的接口描述了該組件提供給上一層調(diào)用者的功能,而使用的接口則表示該組件本身工作時(shí)需要的功能。接口是一組相關(guān)函數(shù)的集合,它是雙向的,并且是組件間的唯一訪問點(diǎn)。接口聲明了兩種函數(shù):(1)命令:接口的提供者必須實(shí)現(xiàn)它們。(2)事件:接口的使用者必須實(shí)現(xiàn)它們。2.接口的特點(diǎn)接口的特點(diǎn)如下:(1)接口是雙向的:提供或使用。(2)接口指定了一組命令,其職能由接口的提供者實(shí)現(xiàn)。還指定了一組事件,其職能由該接口的使用者實(shí)現(xiàn)。也就是說,提供了接口的組件必須實(shí)現(xiàn)該接口的命令函數(shù);而使用了某接口的組件必須實(shí)現(xiàn)該接口的事件函數(shù)。(3)如果一個(gè)組件調(diào)用了(call)一個(gè)接口命令,必須實(shí)現(xiàn)該接口的事件。一個(gè)組件可以使用或提供多個(gè)接口,或者同一接口的多個(gè)實(shí)例。3.如何定義接口接口定義規(guī)則如下:(1)接口放在一個(gè)單獨(dú)的文件中(*.nc)。(2)接口的名稱應(yīng)與文件名對(duì)應(yīng)。例如:interface1的接口必須對(duì)應(yīng)于文件名interface1.nc。(3)接口定義描述了一系列函數(shù)原型(command和event)。定義如下:nesC-file:includes-listoptinterface...Interface:Interfaceidentifier{declaration-list}Storage-class-specifier:alsooneofCommandeventasyncSendMsg.nc:interfaceSendMsg{commandresult_tsend(uint16_taddress,uint8_tlength,message_t*msg);eventresult_tsendDone(message_t*msg,result_tsuccess);}在接口標(biāo)識(shí)符后面的聲明列表(declaration-list)中給出了相應(yīng)接口的定義。聲明列表必須由具有命令(command)或事件(event)的存儲(chǔ)類型(storageclass)的函數(shù)定義構(gòu)成,否則會(huì)產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤,可選的async關(guān)鍵字表明此命令或事件可以在中斷處理程序(interrupthandler)中執(zhí)行。從上面的定義可知:接口SendMsg包括一個(gè)命令send和一個(gè)事件sendDone。提供接口SendMsg的組件需要實(shí)現(xiàn)send命令函數(shù),而使用此接口的組件需要實(shí)現(xiàn)sendDone事件函數(shù)。2.2.2組件符合nesC規(guī)范的組件包括模塊(module)和配件(configuration),其語法定義如下:nesC-file:includes-listoptmoduleincludes-listoptconfiguration…module:moduleidentifierspecificationmodule-implementationconfiguration:configurationidentifierspecificationconfiguration-implementation組件名由標(biāo)識(shí)符(identifier)定義,此標(biāo)識(shí)符是全局性的,且屬于組件和接口的類型名字空間。一個(gè)組件可以有兩種范圍:內(nèi)嵌在C全局范圍中的規(guī)范(specification)范圍;內(nèi)嵌在規(guī)范范圍內(nèi)的實(shí)現(xiàn)范圍。一個(gè)組件可以通過includes-list有選擇性地包含C文件。規(guī)范列出了組件提供的或使用的規(guī)范元素,比如接口實(shí)例、命令或事件。一個(gè)組件必須實(shí)現(xiàn)它所提供的命令或使用的事件。一般情況下,命令的邏輯執(zhí)行方向向下,即指向下層硬件組件;而事件的邏輯執(zhí)行方向向上,即指向上層應(yīng)用組件。組件間的交互只能通過組件的規(guī)范元素來溝通。每個(gè)規(guī)范元素都有一個(gè)名、字(接口實(shí)例名、命令名和事件名等),這些名字屬于每個(gè)組件特有的規(guī)范范圍的可變名字空間。規(guī)范的語法定義如下:specification:{uses-provides-list}uses-provides-list:uses-providesuses-provides-listuses-providesuses-provides:uesspecification-element-listpovidesspecification-element-listspecification-element-lista:specification-element{specification-elements}specification-elements:specification-elementspecification-elementsspecification-element一個(gè)組件規(guī)范中可以包含多個(gè)uses和provides命令,多個(gè)被使用(used)或被提供(provided)的規(guī)范元素可以通過使用“{”和“}”符號(hào)在一個(gè)uses或provides命令中指定。完整的接口定義句法是interfaceXasY,這里可以明確定義接口名字為Y。interfaceX是interfaceXasX的簡(jiǎn)寫形式。?如果接口參數(shù)(interface-parameters)被省略,則interfaceXasY定義了對(duì)應(yīng)此組件單一接口的一個(gè)簡(jiǎn)單接口實(shí)例。如果有接口參數(shù),例如,interfaceSendMsgS[uint8_tid],這是一個(gè)參數(shù)化的接口實(shí)例定義,對(duì)應(yīng)此組件的多個(gè)接口中的一個(gè)(八位整數(shù)可以表示256個(gè)值,所以interfaceSendMsgS[uint8_tid]可定義256個(gè)SendMsg類型的接口)。注意,參數(shù)化接口的參數(shù)類型必須是整型。直接包含帶有command或event存儲(chǔ)類型的標(biāo)準(zhǔn)C函數(shù)可以被定義為命令或事件,具體語法定義如下:specification-element:declaration…storage-class-specifier:alsooneofcommandeventasync如果declaration不是一個(gè)有command或event存儲(chǔ)類型的函數(shù)定義,則會(huì)產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤。正如接口定義中說明的那樣,async表明這個(gè)命令或事件可以在中斷處理中執(zhí)行。如果沒有定義接口參數(shù),則命令或事件只是簡(jiǎn)單的命令或事件;如果定義了接口參數(shù),則表示參數(shù)化的命令或參數(shù)化的事件。在這種情況下,接口參數(shù)放在函數(shù)的普通參數(shù)列表前面,將組件K定義中提供的命令(或事件)F稱為K提供的命令(或事件)F;將組件K定義中使用的命令(成事件)F稱為K使用的命令(或事件)F。K提供的命令X.F是指組件K提供的接口實(shí)例X中的命令F;K使用的命令X.F是指組件K使用的接口實(shí)例X中的命令F;K提供的事件X.F是指組件K提供的接口實(shí)例X中的事件F;而K使用的事件X.F是指組件K使用的接口實(shí)例X中的事件F。需要注意的是,由于接口的雙向特性引起事件的被提供和被使用的反向關(guān)系,當(dāng)不涉及被使用/被提供的區(qū)別時(shí),一般簡(jiǎn)單地稱“K的命令a或事件a”。K的命令a或事件a可能是參數(shù)化的,也可能是簡(jiǎn)單形式的,這取決于它對(duì)應(yīng)的規(guī)范元素中的參數(shù)化或簡(jiǎn)單狀態(tài)。組件的兩大組成部分是模塊和配件,且基于nesC編寫的應(yīng)用程序也主要包括模塊文件和配件文件等。為此,下面將對(duì)模塊和配件的定義、組成等進(jìn)行詳細(xì)分析。圖2-1和圖2-2給出了各種術(shù)語在配件和模塊中的具體指代內(nèi)容。2.2.3模塊模塊(modules)是用C語言實(shí)現(xiàn)的組件規(guī)范,它實(shí)際上是組件的邏輯功能實(shí)體。模塊的定義如下:module:moduleidentifierspecificationmodule-implementationmodule-implementation:implementation{ translation-unit}這里translation-unit是一系列C語言的聲明和定義。模塊中translation-unit的頂層聲明屬于模塊的組件實(shí)現(xiàn)范圍,這些聲明可以是任意標(biāo)準(zhǔn)C語言的聲明,定義、任務(wù)的聲明,定義、命令或事件的實(shí)現(xiàn)。translation-unit必須實(shí)現(xiàn)模塊提供接口聲明的全部命令和模塊使用接口聲明的所有事件。下面的C語句正則表達(dá)式定義了這些命令和事件的實(shí)現(xiàn):storage-class-specifier:alsooneofCommandeventasyncdeclaration-specifiers:alsoDefaultdeclaration-specifiersdirect-declarator:alsoIdentifier.identifierdirect-declaratorinterface-parameters(parameter-type-list)簡(jiǎn)單命令或事件的實(shí)現(xiàn)要滿足具有command或event存儲(chǔ)類型的C函數(shù)標(biāo)準(zhǔn)語法。如果async關(guān)鍵字包含在命令或事件的聲明中,則在它的實(shí)現(xiàn)中也必須被包含。具有接口參數(shù)P的參數(shù)化命令或事件的實(shí)現(xiàn)語法滿足具有command或event存儲(chǔ)類型C函數(shù)定義的語法,而且在C函數(shù)定義的普通參數(shù)的前面有以方括號(hào)括起來的參數(shù)P前綴。這些接口參數(shù)聲明P屬于命令或事件的函數(shù)參數(shù)范圍,而且具有與普通函數(shù)參數(shù)一樣的使用范圍。下面的C語句擴(kuò)展定義了命令調(diào)用和事件通知:postfix-expression:postfix-expression[argument-expression-list]call-kindoptprimary(argument-expression-listopt)…call-kind:oneofcallsignalpost關(guān)鍵字:call,signal。一個(gè)簡(jiǎn)單的命令a可以用calla(…)來調(diào)用,而用signala(…)來通知一個(gè)簡(jiǎn)單事件a。一個(gè)有n個(gè)T1,…,Tn類型接口參數(shù)的參數(shù)化命令(或事件)a可以用calla[e1,…en](…)來調(diào)用(相應(yīng)地可以用signala[e1,…en](…)來通知事件)。接口參數(shù)表達(dá)式ei必須符合類型Ti。調(diào)用命令和通知事件后,它們的執(zhí)行是馬上完成的,即call和signal與函數(shù)調(diào)用是相似的。被call和signal表達(dá)式執(zhí)行的實(shí)際命令或事件取決于程序配件中定義的wiring語句,這些wiring語句定義0、1或多個(gè)實(shí)現(xiàn)被執(zhí)行。當(dāng)多于一個(gè)的實(shí)現(xiàn)被執(zhí)行時(shí),稱此模塊的命令或事件有扇出(fan-out)特性。模塊(modules)的具體實(shí)現(xiàn)需要另一個(gè)概念即任務(wù),任務(wù)的定義如下:taskvoid任務(wù)名稱();post任務(wù)名稱();一個(gè)任務(wù)是一個(gè)返回類型為void且無參數(shù)的task存儲(chǔ)類型的函數(shù)。在TinyOS中,任務(wù)是一個(gè)可以被調(diào)度的邏輯實(shí)體,它類似于傳統(tǒng)操作系統(tǒng)中的進(jìn)程/線程概念。一個(gè)任務(wù)可以有一個(gè)預(yù)先聲明,例如taskvoidmyTask()。使用帶post前綴的任務(wù)調(diào)用來提交(post)任務(wù),例如postmyTask()。post將任務(wù)掛入任務(wù)隊(duì)列中,并立即返回;任務(wù)提交成功后,post返回1,否則返回0,post表達(dá)式的類型是unsignedchar。2.2.4配件配件通過連接一系列其他組件來實(shí)現(xiàn)一個(gè)組件規(guī)范,主要用來實(shí)現(xiàn)組件間的相互訪問方式。配件的語法定義如下:configuration:configurationidentifierspecificationconfiguration-implementationconfiguration-implementation:implementation{ component-listconnection-list}component-list列出用來實(shí)現(xiàn)此配件的組件列表,connection-list定義了這些組件是怎樣互相連接以及如何與配件的規(guī)范連接在一起的。這里把配件規(guī)范中的規(guī)范元素稱為外部(external)規(guī)范元素,而把在配件組件中的規(guī)范元素稱為內(nèi)部(internal)規(guī)范元素。1.配件中的組件列表組件列表(component-list)定義了用來實(shí)現(xiàn)配件的組件。這些組件可以在配件中重命名,這樣就可以解決與配件規(guī)范元素的名字相沖突的問題,或簡(jiǎn)化程序編寫,為組件所選的名字屬于組件實(shí)現(xiàn)范圍。組件列表的語法定義如下:component-list:componentscomponent-listcomponentscomponents:componentscomponent-line;component-line:renamed-identifiercomponent-line,renamed-identifierrenamed-identifier:identifieridentifierasidentifier當(dāng)有兩個(gè)組件使用as導(dǎo)致重名時(shí),會(huì)產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤(例如,componentX,YasX),一個(gè)組件始終只有一個(gè)實(shí)例。如果組件K在兩個(gè)不同的配件中被使用,或者在同一個(gè)配件中被使用兩次,程序中也只有一個(gè)實(shí)例。2.連接連接用來把定義的元素(接口、命令、事件等)聯(lián)系在一起,以完成相互之間的調(diào)用。1)連接的語法定義連接的語法定義如下:connection-list:connectionconnection-listconnectionconnection:endpoint=endpointendpoint->endpointendpoint<-endpointendpoint:identifier-pathidentifier-path[argument-expression-list]identifier-path:identifieridentifier-path.identifier連接語句連接兩個(gè)終點(diǎn)(endpoint),一個(gè)終點(diǎn)的identifier-path指明了一個(gè)規(guī)范元素,可選項(xiàng)argument-expression-list定義了接口參數(shù)。如果一個(gè)終點(diǎn)的規(guī)范元素是參數(shù)化的,并且這個(gè)終點(diǎn)沒有確定的參數(shù)值,則這個(gè)終點(diǎn)稱為參數(shù)化的終點(diǎn)。當(dāng)一個(gè)終點(diǎn)有參數(shù)值,且下面任何一種情況為真時(shí),會(huì)產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤:(1)參數(shù)值不全是常量表達(dá)式;(2)這個(gè)終點(diǎn)的規(guī)范元素是非參數(shù)化的;(3)參數(shù)個(gè)數(shù)與規(guī)范元素規(guī)定的參數(shù)個(gè)數(shù)不符;(4)參數(shù)值不在規(guī)范元素的參數(shù)類型范圍內(nèi)。當(dāng)一個(gè)終點(diǎn)的identifier-path不是下面三種情況之一時(shí),也會(huì)產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤:(1)?X:這里X是一個(gè)外部規(guī)范元素的名字。(2)?K.X:這里K是component-listi/:,X是K的一個(gè)規(guī)范元素。(3)?K:這里K是component-list的一個(gè)組件。這種形式用于隱含連接,稍后會(huì)給出相關(guān)分析。值得注意的是,當(dāng)定義了參數(shù)時(shí)這種格式不能使用。2)?nesC中有三種連接語句(1)?endpoint1=endpoint2(equate連接):這是一種包含一個(gè)外部規(guī)范元素的連接。這種連接語句可以有效地使兩個(gè)規(guī)范元素等價(jià)。設(shè)S1是endpoint1的規(guī)范元素,S2是endpoint2的規(guī)范元素,必須滿足下面兩個(gè)條件,否則會(huì)產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤。①?S1是內(nèi)部的,S2是外部的(或者相反),而且S1和S2同時(shí)是被提供的或是被使用的。②?S1和S2都是外部的,而且一個(gè)是被提供的,另一個(gè)是被使用的。(2)?endpoint1->endpoint2:這是一種包含兩個(gè)內(nèi)部規(guī)范元素的連接。Link連接經(jīng)常把endpoint1定義的被使用的規(guī)范元素連接到endpoint2定義的被提供的規(guī)范元素上。如果這兩個(gè)條件不滿足時(shí)會(huì)產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤。(3)?endpoint1<-endpoint2:這種連接等價(jià)于endpoint2->endpoint1。在這三種連接中,被定義的兩個(gè)規(guī)范元素必須是兼容的,即它們必須都是命令,或都是事件,或都是接口實(shí)例。如果它們是命令(或事件),則必須擁有相同的函數(shù)名字:如果是接口實(shí)例,則必須是同一接口類型;如果不滿足上述條件,則會(huì)產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤。3)怎樣用連接語句來表達(dá)在每個(gè)調(diào)用(call)表達(dá)式中的函數(shù)調(diào)用關(guān)系如果一個(gè)終點(diǎn)是參數(shù)化的,則連接的另一個(gè)終點(diǎn)也必須是參數(shù)化的,而且必須擁有相同的參數(shù)類型,否則會(huì)產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤。所有外部規(guī)范元素必須被連接,否則會(huì)產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤,內(nèi)部規(guī)范元素可以不被連接。當(dāng)然,這些內(nèi)部規(guī)范元素也許會(huì)在別的配件中被連接,但當(dāng)模塊有合適的默認(rèn)事件或命令實(shí)現(xiàn)時(shí)不會(huì)被連接。(1)隱式連接。在nesC中有幾種定義連接的方式,如K1<-K2.X等。nesC會(huì)遍歷K1的規(guī)范元素,尋找是否有對(duì)應(yīng)的X規(guī)范元素,如果有,則產(chǎn)生一個(gè)連接;如果沒有,則會(huì)產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤。(2)無參數(shù)化連接的語義??梢杂弥虚g函數(shù)(intermediatefunctions)來定義連接,每個(gè)組件中的命令a或事件a都會(huì)有一個(gè)中間函數(shù)Ia。一個(gè)中間函數(shù)可以是被使用的,也可以是被提供的,每個(gè)中間函數(shù)有與組件規(guī)范中相應(yīng)的命令或事件參數(shù)一致的參數(shù)。一個(gè)配件中的連接語句定義了中間函數(shù)體。為了簡(jiǎn)化起見,可通過擴(kuò)充連接語句“->”來表示(referto)中間函數(shù)的連接關(guān)系,這樣就不必使用連接規(guī)范元素的多個(gè)連接語句,如“=”、“->”等。這里用“I1->I2”來表示I1和I2中間函數(shù)之間的連接關(guān)系。例如配件C定義了下面的中間函數(shù)連接:IC.X.f<-->IM.P.f IM.U.f<-->IM.P.f IC.h2<-->IM.hIC.X.g<-->IM.P.g IM.U.g<-->IM.P.g在配件C的連接I1<-->I2中,其中一個(gè)中間函數(shù)是被調(diào)用者,而另一個(gè)是調(diào)用者。這種連接方式只是簡(jiǎn)單地把對(duì)被調(diào)用者的一個(gè)調(diào)用加到調(diào)用者函數(shù)體中。當(dāng)滿足下面任意一個(gè)條件時(shí),I1(類似地有I2)是被調(diào)用者(對(duì)于包含這個(gè)連接的配件C,對(duì)規(guī)范元素使用內(nèi)部、外部這種術(shù)語):·如果I1對(duì)應(yīng)一個(gè)內(nèi)部規(guī)范元素,而這個(gè)內(nèi)部規(guī)范元素是一個(gè)被提供的命令或事件。·如果I1對(duì)應(yīng)一個(gè)外部規(guī)范元素,而這個(gè)外部

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論