![LwIP及其網(wǎng)絡編程應用實例_第1頁](http://file4.renrendoc.com/view10/M03/00/2C/wKhkGWVthqKAFdplAAEoSRbOXcg338.jpg)
![LwIP及其網(wǎng)絡編程應用實例_第2頁](http://file4.renrendoc.com/view10/M03/00/2C/wKhkGWVthqKAFdplAAEoSRbOXcg3382.jpg)
![LwIP及其網(wǎng)絡編程應用實例_第3頁](http://file4.renrendoc.com/view10/M03/00/2C/wKhkGWVthqKAFdplAAEoSRbOXcg3383.jpg)
![LwIP及其網(wǎng)絡編程應用實例_第4頁](http://file4.renrendoc.com/view10/M03/00/2C/wKhkGWVthqKAFdplAAEoSRbOXcg3384.jpg)
![LwIP及其網(wǎng)絡編程應用實例_第5頁](http://file4.renrendoc.com/view10/M03/00/2C/wKhkGWVthqKAFdplAAEoSRbOXcg3385.jpg)
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第九章LwIP及其網(wǎng)絡編程應用實例1整理pptLwIP介紹LwIP(LightWeightInternetProtocol)是瑞典計算機科學院(SwedishInstituteofComputerScience)的AdamDunkels等人開發(fā)的一套用于嵌入式系統(tǒng)的開源TCP/IP協(xié)議棧。LwIP的含義是輕型IP協(xié)議,其實現(xiàn)的重點是在保持TCP協(xié)議主要功能的根底上減少對RAM的占用,這使得LwIP協(xié)議棧非常適合在小型嵌入式系統(tǒng)中使用。2整理pptLwIP介紹LwIP的版本較多,較新的版本通常完善或增加了LwIP的功能。LwIP有如下特點:IP:支持多網(wǎng)絡接口下的IP轉發(fā)ARP:支持ARP協(xié)議ICMP:支持ICMP協(xié)議UDP:支持UDP協(xié)議TCP:支持TCP協(xié)議,包括擁塞控制、RTT估算和快速恢復/快速重傳RawAPI:提供專門的內部回調函數(shù),以提高應用性能SocketAPI:可選的Berkeley-likesocketAPILwIP的較新版本還提供對以下功能或協(xié)議的支持:IPfragment:IP分片DNS:域名解析SNMP:簡單網(wǎng)絡管理協(xié)議DHCP:動態(tài)主機配置協(xié)議PPP:點對點協(xié)議IPv63整理pptLwIP源碼的文件組織LwIP文件目錄的組織結構如下圖,其源代碼全部位于目錄src下。src目錄下一般有5個子目錄LwIP提供的api子目錄、core子目錄、include子目錄和netif子目錄需用戶自己創(chuàng)立的arch目錄。4整理pptLwIP源碼的文件組織每個子目錄包含的某一類相關的文件,簡要說明如下:api目錄應用程序接口文件。arch目錄與硬件和OS有關的文件,包括網(wǎng)絡驅動、移植需要修改的文件。core目錄LwIP的核心代碼,包括ICMP、IP、UDP、TCP等協(xié)議的實現(xiàn)等。include目錄LwIP的包含文件。netif目錄ARP協(xié)議和LwIP網(wǎng)絡設備驅動程序的模板,提供了網(wǎng)絡接口驅動程序的根本框架。5整理pptLwIP的軟件體系結構LwIP的協(xié)議層次:LwIP也是以4層TCP/IP模型為參照來實現(xiàn)TCP/IP協(xié)議族的。每一個協(xié)議作為一個模塊被實現(xiàn),同時還提供了幾個函數(shù)作為協(xié)議的入口點。LwIP并沒有嚴格地按照分層的方式實現(xiàn)協(xié)議族。實際上LwIP使用的是一種比較松散的通訊機制,通過共享內存的方式實現(xiàn)應用層與底層協(xié)議族之間的通訊。LwIP擁有獨特的緩沖機制,使得各層次可以更加有效的重復使用緩沖區(qū)。LwIP盡量防止內存復制,防止了內存復制產生的性能損失。6整理pptLwIP的軟件體系結構與LwIP的協(xié)議層次相匹配,LwIP采用模塊化設計的方法實現(xiàn)。TCP/IP協(xié)議的實現(xiàn)模塊如ARP、IP、ICMP、UDP、TCP等許多相關支持模塊。這些支持模塊包括操作系統(tǒng)模擬層、緩沖與內存管理子系統(tǒng)、網(wǎng)絡接口函數(shù)等。7整理pptLwIP的進程模型TCP/IP協(xié)議族的進程模型指的是采用何種方法把系統(tǒng)分成不同的進程。常見的進程模型有兩種:每一個協(xié)議作為一個獨立的進程協(xié)議棧作為一個內核只占據(jù)一個進程。第一種模型必須符合協(xié)議的每一層,協(xié)議層之間通過指定的方式進行通訊。優(yōu)點較明顯,即每一種協(xié)議都可以獨立參與到系統(tǒng)運行中,其實現(xiàn)的代碼也比較簡單,整個協(xié)議棧的層次脈絡清晰,便于理解和調試。缺點也是顯而易見的,即數(shù)據(jù)跨層傳遞時不得不產生進程切換以及內存復制。這一缺點極大影響了系統(tǒng)的整體性能,尤其對于嵌入式系統(tǒng)來說更是不能忍受的。第二種模型將協(xié)議棧駐留在操作系統(tǒng)內核中,應用程序通過系統(tǒng)調用與協(xié)議棧進行通訊。這種設計可以使用交叉協(xié)議分層技術,各層協(xié)議不必嚴格劃分。這種進程模型的缺點是層次不清,給理解增加了難度。8整理pptLwIP的進程模型LwIP那么采用一種比較靈活的設計方法。它可以將所有的協(xié)議駐留在一個進程,以便獨立于操作系統(tǒng)內核之外。應用程序既可以駐留在LwIP的進程中,也可以使用一個單獨的進程。它也可以根據(jù)協(xié)議層次結構創(chuàng)立多個進程,但各個進程之間只傳送盡可能少的必要信息,而沒有引入額外的內存復制LwIP在協(xié)議層之間切換時,一般只傳遞數(shù)據(jù)緩沖區(qū)的地址,讓需要處理數(shù)據(jù)的協(xié)議層自己去提取。9整理pptLwIP的函數(shù)調用關系為了盡量防止不必要的內存復制,LwIP更多的是采用一種基于回調函數(shù)的設計方法。當數(shù)據(jù)需要處理或跨層傳遞時,通常是通過調用事先已定義好的回調函數(shù)來完成有關操作。優(yōu)點是大大提高了LwIP的整體性能;缺點是使得LwIP的整個軟件體系顯得略微復雜,尤其是函數(shù)之間的調用關系更為繁瑣。為了理清LwIP的函數(shù)調用關系,從兩個不同的方向對這一問題進行分析:從不同的協(xié)議層出發(fā),橫向分析各個層次內的調用關系;從幾種典型的協(xié)議模塊出發(fā),縱向分析各模塊的跨層調用關系。10整理ppt整體調用關系圖給出了LwIP的整體調用關系,根本上涵蓋了LwIP的主要功能模塊和絕大局部的函數(shù)調用。圖中只標注了對LwIP的整個軟件體系起著重要支撐作用的主干函數(shù)11整理ppt協(xié)議層內的調用TCP/IP協(xié)議棧是按功能層組織的,每一層都為上一層提供效勞,并使用下一層提供的效勞。在4層TCP/IP模型中,從下至上依次是網(wǎng)絡接口層、網(wǎng)際層、運輸層和應用層。〔1〕網(wǎng)絡接口層網(wǎng)絡接口層是較高協(xié)議與局域網(wǎng)接口的地方。當主機通過查詢或者中斷方式得知網(wǎng)絡芯片接收到數(shù)據(jù)幀時,LwIP協(xié)議棧對該數(shù)據(jù)幀進行解碼,并判斷數(shù)據(jù)幀的協(xié)議類型:如果是IP協(xié)議,那么將該幀傳遞給上層〔網(wǎng)際層〕的ip_input()函數(shù)進行處理;如果是ARP協(xié)議,那么直接傳給本層的arp_input()函數(shù),該函數(shù)根據(jù)需要決定是否調用arp_replay()進行ARP應答。當上層有數(shù)據(jù)需要通過網(wǎng)絡接口層進行發(fā)送時,當前網(wǎng)絡接口的輸出函數(shù)netif->output()將會被調用,以完成真正的數(shù)據(jù)發(fā)送過程。12整理ppt協(xié)議層內的調用13整理ppt協(xié)議層內的調用〔2〕網(wǎng)際層網(wǎng)際層負責網(wǎng)間尋址〔IP地址〕、數(shù)據(jù)封裝、路由選擇、錯誤處理和診斷等典型協(xié)議有IP協(xié)議和ICMP協(xié)議。當從下層〔網(wǎng)絡接口層〕接收到IP數(shù)據(jù)報時,調用ip_input()函數(shù)進行處理。根據(jù)IP數(shù)據(jù)報的協(xié)議字段,LwIP決定將該數(shù)據(jù)報傳給上層〔運輸層〕還是傳給本層。如果IP凈荷中承載的是ICMP協(xié)議,那么本層的icmp_input()函數(shù)將會調用。當不管是上層還是本層有數(shù)據(jù)需要從網(wǎng)際層發(fā)送出去時LwIP將會調用ip_output()發(fā)送數(shù)據(jù),或者先調用ip_route()找到一個適宜的網(wǎng)絡接口再調用ip_output_if()發(fā)送數(shù)據(jù)。實際上ip_output()也是通過先調用ip_route()再調用ip_output_if()來實現(xiàn)的14整理ppt協(xié)議層內的調用15整理ppt協(xié)議層內的調用〔3〕運輸層運輸層負責在網(wǎng)際設備之間運輸數(shù)據(jù),以可靠或不可靠的方式進行。TCP和UDP。當下層〔網(wǎng)際層〕有數(shù)據(jù)傳給運輸層時LwIP會根據(jù)數(shù)據(jù)類型的不同〔是TCP還是UDP〕調用該層的tcp_input()或者udp_input()。經過一定處理后,LwIP將數(shù)據(jù)由tcp_receive()或udp_input()提交給上層〔應用層〕,一般會調用事先注冊的接收函數(shù)。當上層需要發(fā)送數(shù)據(jù)時LwIP選擇調用tcp_write()或者udp_send()對數(shù)據(jù)進行處理最后通過tcp_output()或udp_send()將數(shù)據(jù)交給下層。16整理ppt協(xié)議層內的調用17整理ppt協(xié)議層內的調用〔4〕應用層用戶的應用運行在應用層,該層使用戶可以根據(jù)自己的需要對數(shù)據(jù)進行處理。用戶需要發(fā)送數(shù)據(jù)時由LwIP根據(jù)數(shù)據(jù)類型〔TCP或UDP〕調用下層〔運輸層〕對應的發(fā)送函數(shù)。應用層并不需要直接關注數(shù)據(jù)是怎樣發(fā)送出去的。用戶接收的數(shù)據(jù)一般由LwIP調用下層的接收函數(shù)送達,此后用戶可以根據(jù)實際情況實現(xiàn)應用程序。18整理ppt典型模塊的跨層調用對于某一個協(xié)議來說它一般只隸屬于某一個層次〔ARP除外〕。但往往會有其它層次調用該協(xié)議的有關函數(shù)而該協(xié)議一般也會主動調用其它層次的有關函數(shù)。
〔1〕IP模塊LwIP的較早期版本實現(xiàn)了IP層大局部的根本功能,能夠發(fā)送、接收以及轉發(fā)信息包。接收信息包由網(wǎng)絡設備驅動調用ip_input()函數(shù)開始處理。完成對IP版本字段及包頭長度的初始完整性檢查同時還要計算和驗證包頭校驗和函數(shù)檢查目的地址是否與網(wǎng)絡接口的IP地址相符以確定信息包是否到達預定主機。如果一個到達的信息包被發(fā)現(xiàn)已經到達了目的主機,那么由協(xié)議字段來決定信息包應該傳送到哪一個上層協(xié)議。19整理ppt典型模塊的跨層調用外發(fā)的信息包由ip_output()函數(shù)處理,該函數(shù)使用ip_route()函數(shù)查找適當?shù)木W(wǎng)絡接口來傳送信息包。當外發(fā)的網(wǎng)絡接口確定后,信息包傳給以外發(fā)網(wǎng)絡接口為參數(shù)的ip_output_if()函數(shù)。所有的IP包頭字段被填充,并且計算IP包頭校驗和。IP信息包的源及目標地址作為參數(shù)被傳遞給ip_output_if()函數(shù)。傳輸層協(xié)議UDP與TCP在計算傳輸層校驗和的時候需要擁有目標IP地址,因此一些傳輸層函數(shù)可能會直接直接調用ip_route()函數(shù)確定接口。這樣這些函數(shù)在外發(fā)數(shù)據(jù)前就沒有必要再對網(wǎng)絡接口鏈表進行檢索,而是直接調用ip_output_if()函數(shù)外發(fā)數(shù)據(jù)。20整理ppt典型模塊的跨層調用如果沒有網(wǎng)絡接口的地址與到達的信息包的目標地址相同,信息包應該被轉發(fā)。由ip_forward()函數(shù)完成。TTL字段值被減少,當減為0的時候,將會給IP信息包的最初發(fā)送者發(fā)送ICMP錯誤信息,并拋棄該信息包。因為IP包頭被改變,因此需要調整IP包頭校驗和。最后,信息包被轉發(fā)到適當?shù)木W(wǎng)絡接口。21整理ppt典型模塊的跨層調用〔2〕ICMP模塊ICMP信息包由ip_input()函數(shù)收到后,轉交給icmp_input()函數(shù)對ICMP包頭解碼,然后進行適當?shù)膭幼?。如果需要對回送請求進行應答,那么調用ip_output()函數(shù)發(fā)送應答報文。某些ICMP消息被傳遞給上層協(xié)議,由傳輸層的特定函數(shù)處理。ICMP目標不可到達消息可以由傳輸層發(fā)送,特別是UDP如udp_input()就可以調用icmp_dest_unreach()函數(shù)完成這項工作。icmp_dest_unreach()最后也會調用ip_output()發(fā)送ICMP報文。22整理ppt典型模塊的跨層調用23整理ppt典型模塊的跨層調用〔3〕UDP模塊當一個UDP數(shù)據(jù)包到達時IP層調用udp_input()函數(shù)將數(shù)據(jù)包移交給udp_input()。如果需要的話,LwIP會在這里對UDP校驗和進行檢查。為了找到匹配的UDPPCB,LwIP會對UDPPCB全局鏈表進行線性搜索。如果當前鏈表中存在匹配的UDPPCB,那么其recv函數(shù)會被調用。發(fā)送數(shù)據(jù)的過程由應用程序調用udp_send()函數(shù)發(fā)起。為了計算校驗和,該函數(shù)會調用ip_route()確定網(wǎng)絡接口,因為該接口地址將在校驗和的計算過程中用到。最后,信息包被移交給ip_output_if()函數(shù)傳送。24整理ppt典型模塊的跨層調用25整理ppt典型模塊的跨層調用〔4〕TCP模塊TCP處理比UDP處理要復雜得多與TCP輸入相關的函數(shù)tcp_input()tcp_process()tcp_receive()與TCP輸出有關的函數(shù)tcp_write()tcp_enqueue()tcp_output()26整理ppt典型模塊的跨層調用27整理ppt典型模塊的跨層調用TCP數(shù)據(jù)的發(fā)送過程一般是由應用層發(fā)起。應用層調用tcp_write(),而tcp_write()再調用tcp_enqueue()。tcp_enqueue()函數(shù)會在必要時將數(shù)據(jù)分割成適當大小的TCP段,然后把這些TCP段放到所屬連接的傳輸隊列中。這時tcp_output()函數(shù)會判斷接收器窗口是否擁有足夠大的空間,阻塞窗口是否也足夠大,如果條件滿足,就調用ip_route()找到一個適宜的接口,再調用ip_output_if()完成發(fā)送過程。即使當時不能發(fā)送也不要緊,這是因為LwIP設置了定時器函數(shù)tcp_tmr(),該函數(shù)每隔固定時間就會被調用一次。tcp_tmr()會對當前連接的傳輸隊列進行分析,并根據(jù)需要調用tcp_output()執(zhí)行數(shù)據(jù)發(fā)送操作。28整理ppt典型模塊的跨層調用TCP數(shù)據(jù)的接收過程由網(wǎng)絡接口層發(fā)起。網(wǎng)絡接口層將數(shù)據(jù)包傳遞給ip_input()函數(shù),該函數(shù)驗證IP頭后移交TCP段給tcp_input()函數(shù)。tcp_input()函數(shù)主要完成兩項工作初始完整性檢查〔也就是校驗和驗證與TCP選項解析判定這個TCP段屬于哪個TCP連接。接著,這個TCP段到達tcp_process()函數(shù)。tcp_process()函數(shù)實現(xiàn)了TCP狀態(tài)機,任何必要的狀態(tài)轉換都在這里實現(xiàn)。當該TCP所屬的連接正處于接受網(wǎng)絡數(shù)據(jù)的狀態(tài)時,tcp_receive()函數(shù)將被調用。最后,tcp_receive()函數(shù)將數(shù)據(jù)傳給上層的應用程序,完成接收過程。如果收到一個ACK應答確認數(shù)據(jù),說明接收器同意接收更多的數(shù)據(jù),此時tcp_output()函數(shù)將會被調用。29整理pptLwIP的內存管理LwIP的包緩沖區(qū)pbufpbuf是LwIP信息包的內部表示。pbuf結構既支持動態(tài)內存分配以保存信息包內容,又支持讓信息包數(shù)據(jù)駐留在靜態(tài)存儲區(qū)。多個pbuf可以通過一個鏈表結構鏈接成一個pbuf鏈,從而使一個信息包穿越多個pbuf。pbuf的內部結構定義為structpbuf{structpbuf*next; //指向下一個pbufvoid*payload; //指向實際的數(shù)據(jù)負載u16_ttot_len; //pbuf鏈的數(shù)據(jù)負載總長度u16_tlen; //該pbuf的數(shù)據(jù)負載長度u16_tflags; //pbuf的類型標志u16_tref; //pbuf被引用的次數(shù)};30整理pptLwIP的內存管理pbuf結構包括兩個指針,兩個長度字段,一個標志字段和一個引用計數(shù)字段。next指針指向pbuf鏈中下一個pbuf的位置;payload指針指向pbuf中數(shù)據(jù)負載的開始位置len字段包含pbuf中數(shù)據(jù)內容的長度;tot_len字段包含當前pbuf的長度與在這個pbuf鏈中隨后的所有pbuf的len字段之和flags字段標識pbuf的類型;ref字段指出pbuf被引用的次數(shù)。pbuf有四種類型PBUF_RAMPBUF_ROMPBUF_REFPBUF_POOL31整理pptPBUF_RAM類型的pbufPBUF_RAM在事先劃分好的內存堆棧中分配,用于存放應用程序動態(tài)產生的數(shù)據(jù)。圖示的是一個PBUF_RAM類型的pbuf實例,其實際的數(shù)據(jù)負載存放在由協(xié)議棧管理的存儲區(qū)中。既然PBUF_RAM類型的pbuf用于應用程序發(fā)送的數(shù)據(jù)被動態(tài)生成的情況,那么在這種情況下pbuf系統(tǒng)不僅為應用數(shù)據(jù)分配內存,還應給為這些數(shù)據(jù)預置的包頭分配內存。pbuf系統(tǒng)不可能預先知道為這些數(shù)據(jù)預置什么樣的包頭,因而考慮最壞的情況。32整理pptPBUF_ROM/PBUF_REF類型的pbufPBUF_ROM類型的pbuf的payload指針指向不由協(xié)議棧管理的外部存儲區(qū)如應用程序管理的存儲器為用戶數(shù)據(jù)分配的緩存。由于由應用程序交付的數(shù)據(jù)不能被改動因此就需要動態(tài)地分配一個PBUF_RAM來裝載協(xié)議的首部然后將PBUF_RAM(首部)添加到PBUF_ROM(數(shù)據(jù))的前面。這樣就構成了一個完整的數(shù)據(jù)分組〔pbuf鏈〕33整理pptPBUF_ROM/PBUF_REF類型的pbuf34整理pptPBUF_ROM/PBUF_REF類型的pbuf圖中的PBUF_ROM還可以是PBUF_REF,二者的特性非常相似,都可以實現(xiàn)數(shù)據(jù)的零拷貝,但是當發(fā)送數(shù)據(jù)需要排隊時就表現(xiàn)出PBUF_REF的特性了。例如待發(fā)送的分組需要在ARP隊列中排隊,假設這些分組中有PBUF_ROM類型的pbuf,那么直到分組被處理之前,被引用的應用程序的這塊存儲區(qū)域都不能另作它用。但如果是PBUF_REF類型的pbuf,LwIP那么會在數(shù)據(jù)分組排隊時為PBUF_REF類型的pbuf分配緩存(PBUF_POOL或PBUF_RAM),并將引用的應用程序的數(shù)據(jù)拷貝到分配的緩存中。這樣應用程序中被引用數(shù)據(jù)的存儲區(qū)域就能被釋放。35整理pptPBUF_POOL類型的pbufPBUF_POOL是具有固定容量的pbuf,其容量大小通過宏定義來指定。在協(xié)議棧管理的內存中初始化了一個pbuf池,具有相同尺寸的pbuf都是從這個pbuf池中分配得到。一般使用多個PBUF_POOL鏈接成一個鏈表,用于存儲數(shù)據(jù)分組36整理pptPBUF_POOL類型的pbuf37整理pptPBUF_POOL類型的pbufPBU_POOL主要用于網(wǎng)絡設備驅動層由于分配一個pbuf的操作可以快速完成,所以PBUF_POOL非常適合用于中斷處理。一般來說,收到的pbuf是PBUF_POOL類型,發(fā)送出的pbuf是PBUF_ROM或PBUF_RAM類型。不同類型的pbuf擁有各自的特點和不同的使用目的,因此只有正確選用,才能最好地發(fā)揮LwIP的特性。38整理pptLwIP的內存管理LwIP的內存區(qū)域主要用于裝載待接收和發(fā)送的網(wǎng)絡數(shù)據(jù)分組。當接收到分組或者有分組要發(fā)送時,LwIP協(xié)議棧為這些分組分配緩存;在接收到的分組交付給應用程序或者分組己經發(fā)送完畢后,LwIP協(xié)議棧對分配的緩存進行回收利用。協(xié)議棧分配的緩存必須能容納各種大小的報文例如從僅僅幾個字節(jié)的ICMP應答報文到幾百個字節(jié)的TCP分段報文。39整理pptPBUF_RAM的內存管理LwIP協(xié)議棧首先從系統(tǒng)內存中開辟一塊連續(xù)的靜態(tài)存儲區(qū)域該區(qū)域的大小可以事先通過宏定義指定。協(xié)議棧將該區(qū)域作為PBUF_RAM的專用區(qū)域所有與PBUF_RAM有關的內存操作都被限制在該區(qū)域內,從而確保了協(xié)議棧不會因非法訪問系統(tǒng)內存的其它區(qū)域而擾亂其它程序的正常運行。40整理pptPBUF_RAM的內存管理為了方便內存管理,協(xié)議棧定義了一個比較小的結構體mem,并將該結構體置于內存分配塊的頂部來保存內存分配記錄。該結構體擁有三個成員變量,分別為兩個“指針〞和一個標志,其中next與prev分別指向內存的下一個和上一個分配塊,used標志標示該內存塊是否已被分配。next和prev并不是真正的指針,它們本質上是數(shù)組的下標,并沒有直接指向真正的地址。41整理pptPBUF_RAM的內存管理〔1〕初始化使用PBUF_RAM內存之前,需對PBUF_RAM的專用內存區(qū)域進行初始化工作,即對該區(qū)域進行一定的格式設置。LwIP協(xié)議棧在該區(qū)域的頭部和尾部各設置了一個mem結構以協(xié)助管理內存,如下圖。在頭部的mem結構中,next指向尾部mem,prev指向該區(qū)域的起始處,used(=0)說明該mem結構后面的區(qū)域尚未使用;在尾部的mem結構中,next和prev均指向該mem自身,used(=1)說明該mem結構后面無可用的內存。在該區(qū)域的末尾處,協(xié)議棧預留了對齊空間,其主要目的是防止操作過程中因對齊而導致的對該專用區(qū)域之外的存儲空間的越界訪問。42整理pptPBUF_RAM的內存管理43整理pptPBUF_RAM的內存管理〔2〕分配PBUF_RAM內存塊分配內存時首先根據(jù)所申請分配的大小來搜索所有未被使用的內存分配塊搜索到的最先滿足條件的內存塊將分配給申請者。第一次分配時只要申請分配的大小沒有超出限制,便會在PBUF_RAM專用存儲區(qū)域的開頭分配所需要的內存44整理pptPBUF_RAM的內存管理經過屢次的內存分配和釋放操作后,PBUF_RAM存儲區(qū)中會存在多個大小不一的未使用塊。此時如果需要分配一個新的內存塊,有可能搜索到的第一個空閑內存塊空間不夠。在這種情況下,內存管理機制會繼續(xù)往后搜索未使用塊,直到搜索到足夠大的空閑內存塊或搜索到存儲區(qū)的末尾。45整理pptPBUF_RAM的內存管理〔3〕釋放PBUF_RAM內存塊對不再利用的內存塊,需要進行回收,以便下次需要分配內存塊時重新使用?;厥諆却鎵K時,管理該內存塊的mem結構的used標志將被清零,以說明該內存塊已不再被使用,可以重新對其進行分配46整理pptPBUF_RAM的內存管理為了防止內存碎片的產生,每回收一個內存塊后,其上一個與下一個分配塊的used標志將會被檢查:如果它們中的任何一個還未被使用〔used=0〕,那么這個內存塊將被合并到一個更大的未使用內存塊中。只有經過了以上操作后,釋放內存的工作才算是已經完成。47整理pptPBUF_RAM的內存管理合并相鄰空閑塊的一個例如。48整理pptPBUF_RAM的內存管理〔4〕調整PBUF_RAM內存塊大小在內存的使用過程中,有時希望調整已分配的內存塊的大小。根據(jù)調整的方向〔減小/增大〕不同,處理的機制也不一樣。調整前先對騰出的內存塊大小進行預算:如果該值小于mem結構的長度加內存塊的最小長度〔即無法另行分配一個最小長度的內存塊〕,那么調整不被執(zhí)行。調整時將在騰出的內存塊開頭置以一個新的mem結構以對其進行管理,該mem結構的used標志為0,表示可以對其進行分配使用。同釋放內存時一樣,與新的內存塊相鄰的內存塊的used標志同樣會被檢查,以防止碎片產生。49整理pptPBUF_RAM的內存管理給出了減小既定內存塊大小的示意圖。50整理pptPBUF_RAM的內存管理增大既定內存塊的大小時所采取的機制與上述操作大為不同。如果希望將某內存塊的大小調整為newsize,那么處理過程是先分配一塊大小為newsize的空閑內存塊,然后將原內存塊的內容復制到新內存塊中,最后再釋放原內存塊。51整理pptPBUF_ROM/PBUR_REF的內存管理對于PBUF_ROM/PBUF_REF,LwIP協(xié)議棧同樣為其開辟了一塊連續(xù)的存儲區(qū)域。協(xié)議棧定義了結構體memp以協(xié)助PBUF_ROM/PBUF_RAM的內存管理。該結構體只有一個成員next,為指向下一個相同結構的存儲區(qū)的指針。PBUF_ROM/PBUF_REF類型存儲區(qū)域初始化后的結構示意圖,多個pbuf在內存中以鏈表的形式存在。該種類型pbuf的操作方法可以參考鏈表的一般操作方法。52整理pptPBUF_POOL的內存管理PBUF_POOL類型的pbuf同樣擁有自己專用的存儲區(qū)域,該區(qū)域通過預先從系統(tǒng)內存中分配而得。區(qū)域大小由PBUF_POOL類型的pbuf個數(shù)和每個pbuf的緩沖區(qū)大小等參數(shù)共同決定,這些參數(shù)都可以事先通過宏定義指定。對PBUF_POOL類型的內存管理,LwIP協(xié)議棧并沒有額外引入類似PBUF_RAM的mem結構或是PBUF_ROM的memp結構,而是直接采用pbuf結構對其進行管理。53整理pptPBUF_POOL的內存管理PBUF_POOL存儲區(qū)域的結構如下圖,對該類型pbuf的操作與普通鏈表的操作并無不同。每個PBUF_POOL的數(shù)據(jù)緩沖區(qū)都緊跟在pbuf結構后面,并且大小相同。這點與PBUF_ROM不同,因為PBUF_ROM的數(shù)據(jù)緩沖區(qū)不在LwIP協(xié)議棧管理的區(qū)域,并且大小不盡相同。54整理pptLwIP移植無RTOS時的移植LwIP既可以在無RTOS〔RealTimeOperatingSystem,實時操作系統(tǒng)〕的環(huán)境下運行,也可以很方便地移植到RTOS之上。移植過程中對于LwIP核心模塊沒必要也不建議進行修改,而真正的工作是結合實際的軟硬件環(huán)境,針對與移植密切相關的相關文件與相關函數(shù)進行定制。55整理pptLwIP移植移植函數(shù)為了將LwIP移植到特定的開發(fā)平臺上,需要完成與網(wǎng)絡接口有關的底層函數(shù)。這些底層函數(shù)集中在\src\netif\ethernetif.c文件中。建議將“ethernet〞替換成能更好地描述所選網(wǎng)絡接口的詞匯,如華中科技大學瑞薩高級嵌入式控制器實驗室自行開發(fā)的RenesasM16C/62P嵌入式開發(fā)平臺采用的網(wǎng)絡芯片是CS8900A,該文件便用cs8900if.c文件進行了替代。文件中但凡用ethernet命名的函數(shù),也一律用cs8900進行了替代。LwIP提供的ethernetif.c文件給出了網(wǎng)絡接口驅動的整體框架,用戶需要自己完成的函數(shù)主要有3個,分別是底層初始化函數(shù)low_level_init()底層輸入函數(shù)low_level_input()底層輸出函數(shù)low_level_output()。56整理ppt無RTOS時的移植〔1〕底層初始化函數(shù)low_level_init()原型為staticvoidlow_level_init(structnetif*netif);該函數(shù)用來對網(wǎng)絡接口進行初始化,任何與初始化網(wǎng)絡接口有關的操作都可以在該函數(shù)內實現(xiàn)。如對網(wǎng)絡接口有關參數(shù)進行配置,或是完成網(wǎng)絡芯片硬件上所需的初始化操作等。〔2〕底層輸入函數(shù)low_level_input()函數(shù)原型為staticstructpbuf*low_level_input(structnetif*netif);該函數(shù)為到達的數(shù)據(jù)包分配pbuf〔通常是一個pbuf鏈〕,并將數(shù)據(jù)包從網(wǎng)絡接口傳入至pbuf鏈中。數(shù)據(jù)具體接收過程的實現(xiàn)與網(wǎng)絡接口硬件有關。將數(shù)據(jù)裝載至pbbuf時,需對pbuf結構的各字段進行正確填充,使其形成邏輯上的pbuf鏈57整理ppt無RTOS時的移植通常,為收到的數(shù)據(jù)分配的pbuf是PBUF_POOL類型,因為分配一個PBUF_POOL可以很快完成。〔3〕底層輸出函數(shù)low_level_output()函數(shù)原型為:staticerr_tlow_level_output(structnetif*netif,structpbuf*p);該函數(shù)實現(xiàn)真正的的數(shù)據(jù)包發(fā)送過程當需要發(fā)送數(shù)據(jù)包時,數(shù)據(jù)包裝載在事先已分配好的pbuf〔鏈〕中。LwIP將pbuf作為參數(shù)傳入給該函數(shù),由該函數(shù)負責將數(shù)據(jù)包發(fā)送至指定的網(wǎng)絡接口中。數(shù)據(jù)具體發(fā)送過程的實現(xiàn)同樣與網(wǎng)絡接口硬件有關。58整理ppt無RTOS時的移植幾個定時器函數(shù)在LwIP的移植過程中,注意有幾個定時器函數(shù)必須每隔固定時間就調用一次。具體采用什么機制實現(xiàn)這一操作并無限制etharp_tmr()tcp_fasttmr()tcp_slowtmr()這些函數(shù)的運行間隔周期可以通過宏定義指定,各函數(shù)的具體定義可在LwIP提供的源碼中找到。59整理pptLwIP在uC/OS-II下的移植為了方便LwIP在RTOS下的移植,屬于操作系統(tǒng)的函數(shù)調用及數(shù)據(jù)結構并沒有在代碼中直接使用,而是用操作系統(tǒng)模擬層來代替對這些函數(shù)的使用。操作系統(tǒng)模擬層使用統(tǒng)一的接口提供定時器、進程同步及消息傳遞機制等諸如此類的系統(tǒng)效勞原那么上,移植LwIP只需針對目標操作系統(tǒng)修改模擬層實現(xiàn)即可。60整理pptLwIP在uC/OS-II下的移植模擬層主要實現(xiàn)以下4大功能:定時與超時處理LwIP可以為某一線程注冊假設干個超時處理函數(shù),當超時時限溢出時便會調用一個已注冊的函數(shù)。進程同步進程同步機制為多個進程之間的同步操作提供支持,一般可以用信號量來實現(xiàn)。如果選用的RTOS不支持信號量,那么可以使如條件變量等其它根本的同步方式來模擬。消息傳遞消息傳遞機制可通過一種稱作郵箱的抽象方法來實現(xiàn)。郵箱有兩種根本操作:向郵箱投遞(post)一那么消息和從郵箱中提取(fetch)一那么消息線程管理對LwIP協(xié)議棧的線程進行管理和維護,主要指創(chuàng)立線程。61整理ppt移植相關文件與函數(shù)移植過程中需要創(chuàng)立或修改的源文件和頭文件位于目錄src/arch之下目錄組織結構如下圖:62整理ppt移植相關文件與函數(shù)頭文件主要是一些宏定義,包括數(shù)據(jù)類型的定義和有關結構的封裝等;而主要的功能函數(shù)均在sys_arch.c源文件中實現(xiàn)。此外,sys.c和sys.h兩個文件雖無需作任何修改,但與以上文件〔尤其是sys_arch.c〕關聯(lián)緊密,有助于更好地理解LwIP在RTOS下的移植實現(xiàn)。LwIP在設計時就考慮到了將來的RTOS移植問題。為了適應不同的操作系統(tǒng),LwIP并沒有在代碼中使用針對某個特定RTOS的系統(tǒng)調用和數(shù)據(jù)結構,而是提供操作系統(tǒng)模擬層作為LwIP和RTOS的一個接口。為了理解LwIP在RTOS下的移植實現(xiàn)過程,選用嵌入式實時操作系統(tǒng)uC/OS-II為例,對LwIP在uC/OS-II下的移植進行說明。uC/OS-II是專為嵌入式應用設計的實時內核,關于其詳細信息可參考其官網(wǎng)://micrium/page/home。實現(xiàn)LwIP在uC/OS-II下的移植,其主要工作就是結合LwIP和uC/OS-II的特點,對操作系統(tǒng)模擬層進行修改和定制,使LwIP和uC/OS-II無縫連接。63整理ppt移植相關文件與函數(shù)根據(jù)LwIP源碼提供的sys_arch.txt文件,需要實現(xiàn)的函數(shù)有:voidsys_init(void)被調用來初始化操作系統(tǒng)模擬層。sys_sem_tsys_sem_new(u8_tcount)創(chuàng)立并返回一個新的信號量,參數(shù)count指定信號量的初始狀態(tài)。voidsys_sem_free(sys_sem_tsem)刪除一個信號量。voidsys_sem_signal(sys_sem_tsem)發(fā)出一個信號量。u32_tsys_arch_sem_wait(sys_sem_tsem,u32_ttimeout)等待一個信號量,該操作會阻塞調用該函數(shù)的線程。sys_mbox_tsys_mbox_new(void)創(chuàng)立一個空的郵箱。voidsys_mbox_free(sys_mbox_tmbox)刪除一個郵箱。64整理ppt移植相關文件與函數(shù)voidsys_mbox_post(sys_mbox_tmbox,void*msg)向指定的郵箱發(fā)送一那么消息。u32_tsys_arch_mbox_fetch(sys_mbox_tmbox,void**msg,u32_ttimeout)從郵箱中提取一那么消息,該操作同樣會阻塞調用該函數(shù)的線程。structsys_timeouts*sys_arch_timeouts(void)返回指向當前線程的sys_timeouts結構的指針。LwIP的每個線程都有自己的超時等待屬性,每個線程都分配了一個超時等待的數(shù)據(jù)結構sys_timeout,并把這個數(shù)據(jù)結構存放于鏈表sys_timeouts中。該函數(shù)的作用是通過查詢來獲得一個指向當前線程使用的sys_timeouts結構的指針。sys_thread_tsys_thread_new(void(*thread)(void*arg),void*arg,intprio)創(chuàng)立一個新的LwIP線程。65整理ppt超時處理的實現(xiàn)如前所述,LwIP的每個線程都有自己的超時等待屬性。為了順利理解LwIP的這一機制,先引入與之相關的幾種數(shù)據(jù)結構。sys_timeout是線程的超時等待數(shù)據(jù)結構,其內部結構定義如下:structsys_timeout{structsys_timeout*next; //指向鏈表中的下一個sys_timeoutu32_ttime; //超時時限〔ms〕sys_timeout_handlerh; //超時處理函數(shù)void*arg; //超時處理函數(shù)的參數(shù)};其中sys_timeout_handler是指向超時處理函數(shù)的指針,其定義為typedefvoid(*sys_timeout_handler)(void*arg);多個sys_timeout可以鏈接成一個鏈表,如下圖:66整理ppt超時處理的實現(xiàn)sys_timeouts是sys_timeout鏈表的表頭,它只包含一個元素,即指向sys_timeout結構的指針,其定義如下:structsys_timeouts{structsys_timeout*next; //指向鏈表第一個sys_timeout};加上sys_timeouts結構后,LwIP線程的超時等待鏈表結構如下圖:67整理ppt超時處理的實現(xiàn)68整理ppt超時處理的實現(xiàn)timeoutlist將一個sys_timeouts結構和優(yōu)先級聯(lián)系在一起,這樣便于根據(jù)當前優(yōu)先級查找對應的sys_timeouts鏈表,其定義如下:structtimeoutlist{structsys_timeoutstimeouts; //超時等待鏈表INT8Uprio; //優(yōu)先級};每個線程都有一個對以的timeoutlist結構,通過該結構的timeouts元素可以定位超時等待列表的表頭,從而確定該線程的所有超時處理函數(shù),69整理ppt超時處理的實現(xiàn)LwIP在RTOS上的移植過程中需要實現(xiàn)的與超時處理有關的函數(shù)是sys_arch_timeouts()?!?〕移植函數(shù)sys_arch_timeouts()sys_arch_timeouts()函數(shù)的作用是通過查詢機制,獲取指向當前線程的sys_timeouts結構的指針,相當于定位超時等待鏈表的表頭。函數(shù)的原型如下:structsys_timeouts*sys_arch_timeouts(void);該函數(shù)外表上沒有參數(shù),但實際上調用該函數(shù)的線程有自己的優(yōu)先級,因此可以利用當前線程的優(yōu)先級充當函數(shù)的隱含參數(shù)。這樣處理帶來的限制是一個線程不能通過調用該函數(shù)來獲取另一個線程的sys_timeouts結構,但這一般不會引起什么問題。70整理ppt超時處理的實現(xiàn)sys_timeouts結構和當前線程的優(yōu)先級一起封裝在timeoutlist結構中。為了存儲線程的timeoutlist結構,在sys_arch.c文件中定義了一個timeoutlist數(shù)組:staticstructtimeoutlisttimeoutlist[LWIP_MAX_TASKS];LWIP_MAX_TASKS是最大的LwIP線程數(shù),可以事先進行配置。每次調用sys_thread_new()創(chuàng)立一個新的線程時,都會依序取出一個數(shù)組元素,用當前線程的優(yōu)先級對數(shù)組元素的prio字段進行填充。sys_arch_timeouts()函數(shù)通過線性搜索的方法對數(shù)組元素進行遍歷,直到發(fā)現(xiàn)某個數(shù)組元素的prio字段與當前優(yōu)先級相同為止,而該數(shù)組元素的timeouts字段正是我們需要的目標。71整理ppt超時處理的實現(xiàn)72整理ppt超時處理的實現(xiàn)〔2〕相關函數(shù)sys_timeout()sys_timeout()函數(shù)用以向當前線程增加一個超時處理函數(shù),其原型如下:voidsys_timeout(u32_tmsecs,sys_timeout_handlerh,void*arg);sys_timeouts()函數(shù)首先從內存中申請一塊空間,以存放一個sys_timeout結構。如申請成功那么利用函數(shù)的實參對結構的各字段進行填充。要向當前線程注冊一個超時處理函數(shù),sys_timeouts()會通過sys_arch_timeouts()函數(shù)獲取當前線程的sys_timeouts結構。73整理ppt超時處理的實現(xiàn)第一次調用sys_timeout()注冊一個超時處理函數(shù)時,直接將sys_timeout結構鏈接在當前線程的sys_timeouts結構即可,如下圖:74整理ppt超時處理的實現(xiàn)應用程序可能會屢次注冊超時處理函數(shù)或刪除超時處理函數(shù),這樣處理后一個線程的sys_timeouts鏈表中可能會同時存在多個sys_timeout結構。在這種情況下,向線程添加一個超時處理函數(shù)略微復雜,因為sys_timeout結構必須插入到鏈表的恰當位置。實際上如果一個線程有多個超時處理函數(shù),LwIP會按照鏈表的邏輯順序依次結算。這里所謂恰當?shù)奈恢?,就是比較當前鏈表節(jié)點的超時時限和待插入節(jié)點的超時時限,保證插入該節(jié)點后不會影響原有任一節(jié)點的超時等待屬性。75整理ppt超時處理的實現(xiàn)如下圖,假設當前線程已注冊3個超時處理函數(shù),對應有3個sys_timeout結構,其超時時限分別是time1=100,time2=40,time3=80?,F(xiàn)要注冊一個超時時限為time4=160的超時處理函數(shù)。為了確定恰當?shù)牟迦胛恢?,可以沿著鏈表逐次推算超時時限,分析過程如下:1time1<time4→next4在next1之后2time1+time2<time4→next4在next2之后3time1+time2+time3>time4→next4在next3之前經以上步驟,next4的位置已經確定,即位于next2和next3之間。注意插入next4節(jié)點后,next4節(jié)點及緊挨在next4后面的next3節(jié)點的time屬性值需做對應調整,調整后的結果如下圖:76整理ppt超時處理的實現(xiàn)77整理ppt超時處理的實現(xiàn)如果新節(jié)點next4的超時時限time4取其它值,那么可能會出現(xiàn)一些特殊情況。time4<time1,即新節(jié)點的time值比第一個節(jié)點還小。這種情況直接將next4節(jié)點插入到next1節(jié)點之前,并調整time1=time1-time4即可。78整理ppt超時處理的實現(xiàn)time4=time1+time2,即新節(jié)點的time值等于前面假設干節(jié)點他time之和。這種情況next4將插入到next2的后面。next4節(jié)點的time值調整為0,而與next4相鄰的next2節(jié)點和next3節(jié)點那么無需調整time屬性。線程在依序處理超時等待函數(shù)過程中,一旦執(zhí)行完next2節(jié)點的超時處理函數(shù)h2(arg2),會立即執(zhí)行next4節(jié)點的超時處理函數(shù)h4(arg4)。time4>time1+time2+time3,即新節(jié)點的time值大于現(xiàn)有所有節(jié)點time之和。這種情況next4節(jié)點將插入到最后,并調整time4=time4-time1-time2-time3,next4=NULL。79整理ppt超時處理的實現(xiàn)〔3〕相關函數(shù)sys_untimeout()sys_untimeout()函數(shù)與sys_timeout()函數(shù)的作用恰好相反,用以刪除當前線程某一指定的超時處理函數(shù)。函數(shù)原型如下:voidsys_untimeout(sys_timeout_handlerh,void*arg);與sys_timeout()相比,sys_untimeout()函數(shù)同樣會調用sys_arch_timeouts()獲取當前線程的sys_timeouts鏈表結構。函數(shù)通過一種簡單的線性搜索的方法,從表頭開始遍歷,直到找到一個超時處理函數(shù)h和參數(shù)arg均符合的sys_timeout結構。將該結構所在的節(jié)點從鏈表中刪除,并調整緊挨其后的節(jié)點〔如果有的話〕的超時時限屬性,最后釋放該結構占用的內存。80整理ppt超時處理的實現(xiàn)假設某一線程的超時處理函數(shù)鏈表如下圖:81整理ppt超時處理的實現(xiàn)如果線程希望刪除h2處理函數(shù),即執(zhí)行sys_untimeout(h2,arg2);next2節(jié)點將從原鏈表中刪除,同時next3節(jié)點的time3將會調整為time3=time3+time2。調整后的狀態(tài)為:82整理ppt超時處理的實現(xiàn)但如果線程不是要刪除h2處理函數(shù),而是要刪除最后一個超時處理函數(shù),即執(zhí)行sys_untimeout(h3,arg3);這種情況next3節(jié)點從鏈表中刪除后,沒有后續(xù)節(jié)點需要調整超時時限屬性。結果如下:83整理ppt超時處理的實現(xiàn)〔4〕超時處理函數(shù)的使用在等待信號量或等待消息的過程中,LwIP會對超時等待鏈表中的超時處理函數(shù)進行處理。對一個線程來講,要么通過調用sys_sem_wait()等待一個信號量,要么通過調用sys_mbox_fetch()等待一那么消息,至少要采取一種方法阻塞當前線程,否那么注冊的超時處理函數(shù)將無法正常執(zhí)行。鑒于郵箱結構比信號量結構占用更多的資源,因此通常通過永久等待一個信號量來實現(xiàn)線程阻塞。如需每隔一定周期就執(zhí)行一次某函數(shù),那么必須在超時處理函數(shù)中重新注冊自己。例如需要每隔250ms就執(zhí)行一次tcp_tmr(),通??梢圆捎孟旅娴姆绞綄崿F(xiàn)://向當前線程注冊一個超時處理函數(shù)sys_timeout((u32_t)OS_TICKS_PER_SEC/4,(sys_timeout_handler)TCP_Timer,NULL);……//如需周期執(zhí)行tcp_tmr〔〕,那么需在TCP_Timer〔〕中重新注冊自己voidTCP_Timer(void*p_arg){ tcp_tmr();//每隔250ms執(zhí)行一次 sys_timeout((u32_t)OS_TICKS_PER_SEC/4,(sys_timeout_handler)TCP_Timer,NULL);}84整理ppt進程同步的實現(xiàn)進程同步機制是任務之間通信的一種重要方式,通??梢杂尚盘柫繉崿F(xiàn)。uC/OS-II對信號量有較全面的支持,因此移植過程中比較方便實現(xiàn)。uC/OS-II實現(xiàn)了信號量和互斥型信號量,這里采用uC/OS-II的信號量實現(xiàn)。由于uC/OS-II支持信號量的各種操作,并且可以滿足LwIP對信號量的要求,因此只需對相關結構和函數(shù)進行重新封裝即可。85整理ppt進程同步的實現(xiàn)函數(shù)sys_sem_wait()
該函數(shù)是由LwIP應用程序調用的用來等待一個信號量的函數(shù),但它會在等待信號量的過程中對當前線程的超時等待函數(shù)進行處理。函數(shù)原型如下:
voidsys_sem_wait(sys_sem_tsem)該函數(shù)首先調用sys_arch_timeouts()獲取當前線程的超時等待函數(shù)鏈表,以對超時等待鏈表中的超時處理函數(shù)依次結算。真正實現(xiàn)等待一個信號量的過程由sys_arch_sem_wait()完成。現(xiàn)仍以下面的超時等待鏈表為例,分析sys_sem_wait()在等待信號量過程中對超時處理函數(shù)的處理。86整理ppt進程同步的實現(xiàn)1執(zhí)行sys_arch_sem_wait(sem,time1)。如超時溢出那么說明在time1時間內一直未成功等到信號量,此時執(zhí)行超時處理函數(shù)h1(arg1),同時將next1節(jié)點從鏈表中刪除,并轉到步驟2。如在time1時間內成功等到信號量,那么不管實際消耗的等待時間是多少,LwIP一律認為消耗時間為1ms,并調整time1=time1-1,此時轉到步驟4。2執(zhí)行sys_arch_sem_wait(sem,time2)。只有在time1時限耗盡的情況下,才會執(zhí)行sys_arch_sem_wait(sem,time2)。與1類似,如未等到信號量那么執(zhí)行h2(arg2)并轉到步驟3,否那么調整time2=time2-1并轉到步驟4。87整理ppt進程同步的實現(xiàn)3調用sys_arch_sem_wait(sem,time3)。只有在next3節(jié)點前面的所有節(jié)點的超時時限均已耗盡的情況下,才會執(zhí)行sys_arch_sem_wait(sem,time3)。由于next3已經是最后一個節(jié)點,因此不管成功等到信號量與否,均會轉到步驟4。4sys_sem_wait()函數(shù)返回或作永久等待。如果成功等到了信號量,sys_sem_wait()函數(shù)返回。但如果超時等待鏈表中所有超時時限均已耗盡且所有超時處理函數(shù)均已執(zhí)行后,仍未等到信號量,那么sys_sem_wait()會調用sys_arch_sem_wait(0)一直等到信號量有效為止。88整理ppt進程同步的實現(xiàn)一種特殊情況是當前線程超時等待鏈表為空,也就是沒有超時等待函數(shù)。sys_sem_wait()會直接調用sys_arch_sem_wait(0)做永久等待。另一種情況是在等待信號量的過程中發(fā)現(xiàn)某一節(jié)點的超時時限time=0。說明該節(jié)點的超時時限已經耗盡,需立即執(zhí)行節(jié)點對應的超時處理函數(shù)h(arg)。注意time=0與sys_timeouts鏈表為空是截然不同的:time=0只是說明該節(jié)點的超時時限已耗盡sys_timeouts為空那么意味著當前線程沒有任何函數(shù)需要做超時等待。89整理ppt消息傳遞的實現(xiàn)消息傳遞是任務之間通信的另一種重要方式,通常使用一種稱為郵箱的抽象方法來實現(xiàn)。郵箱有兩種根本的操作:郵遞(post)〔發(fā)送一那么消息〕操作不會阻塞進程提取(fetch)〔等待一那么消息〕操作可能會阻塞進程。uC/OS-II提供了消息郵箱和消息隊列兩種機制,區(qū)別是消息郵箱一次只能處理一那么消息,而消息隊列可以存儲多那么消息。為了使LwIP更好地運作,采用uC/OS-II的消息隊列實現(xiàn)LwIP所需的消息傳遞機制。90整理ppt線程管理的實現(xiàn)在線程管理方面,LwIP只提供了創(chuàng)立線程的操作。由于uC/OS-II沒有采用“線程〞這一概念,而是采用“任務〞的概念,LwIP的線程管理實際上是通過uC/OS-II的任務管理機制實現(xiàn)的。每個線程都有自己的超時等待屬性。為了區(qū)別不同線程的超時等待屬性,在創(chuàng)立線程的過程中會將優(yōu)先級prio填入到一個timeoutlist結構的prio成員中,如下圖:91整理ppt線程管理的實現(xiàn)由于uC/OS-II中每個任務都具有唯一的優(yōu)先級,因此prio可以作為LwIP線程的一個標識,以區(qū)分不同的線程。實際上sys_arch_timeouts()正是通過這一標識來定位當前線程的超時等待鏈表的。92整理pptLwIP網(wǎng)絡編程應用實例為了對LwIP的移植和應用進行測試和驗證,以一個具體的應用實例來說明LwIP網(wǎng)絡編程的一般方法。目的是設計和實現(xiàn)一個簡單的嵌入式WEB效勞器,該WEB效勞器可以響應來自瀏覽器的HTTPGET請求,并在發(fā)送請求的瀏覽器上顯示一個小型頁面。93整理ppt實驗平臺準備硬件平臺的一個最根本要求是提供對以太網(wǎng)接口的支持。選用的是華中科技大學瑞薩高級嵌入式控制器實驗室自主研發(fā)制作的RenesasM16C/62P嵌入式開發(fā)平臺。該平臺采用瑞薩科技(RENESAS)的M16C/62P單片機作為主控制器,通過集成一塊CS8900A網(wǎng)絡芯片來實現(xiàn)網(wǎng)絡數(shù)據(jù)收發(fā)功能。94整理ppt實驗平臺準備軟件平臺最重要的局部是開發(fā)環(huán)境。采用Renesas的High-performanceEmbeddedWorkshop進行編程開發(fā)。為了方便調試,華中科技大學瑞薩高級嵌入式控制器實驗室開發(fā)了專門針對RenesasM16C/62P單片機的監(jiān)控程序。通過該監(jiān)控程序,將用戶應用程序下載至ROM或者RAM,可以實現(xiàn)調試功能95整理ppt嵌入式WEB效勞器的設計瀏覽器訪問WEB效勞器所使用的是HTTP協(xié)議??蛻簟瞁EB效勞器〕通過HTTP協(xié)議向效勞器發(fā)送請求效勞器根據(jù)HTTP協(xié)議對客戶端發(fā)來的請求進行解碼,并對其作出應答。HTTP使用TCP作為運輸層,客戶在向效勞器發(fā)送請求之前,要先與效勞器的IP地址在端口80〔HTTP的知名端口〕建立一個連接。效勞器在端口80偵聽進入的連接,并接受和處理客戶的請求。由于只是對LwIP協(xié)議棧進行測試和驗證,因此設計的WEB效勞器只對客戶端的GET請求作出應答,而對其它請求一概不予理會。96整理ppt嵌入式WEB效勞器的設計瀏覽器與WEB效勞器交互的示意圖。圖中瀏覽器運行在PC機〔或支持瀏覽器的其它設備〕上,WEB效勞器運行在RenesasM16C/62P嵌入式開發(fā)平臺上,二者通過網(wǎng)絡進行連接。所有的數(shù)據(jù)交互過程受TCP/IP協(xié)議族的制約。97整理ppt嵌入式WEB效勞器的實現(xiàn)在進行了必要的初始化工作后,翻開TCP的80端口并對該端口進行偵聽。一旦客戶發(fā)起請求,那么效勞器接受并解析該請求。如果請求正確,那么效勞器將相應的頁面內容發(fā)送給客戶端,而客戶端〔通常是瀏覽器〕將該頁面直觀地顯示出來。至此,一次完整的交互過程已完成。效勞器或者繼續(xù)偵聽更多的請求,或者主動關閉。98整理ppt主流程圖99整理ppt主要程序的實現(xiàn)〔1〕HTTP主線程HTTP的主線程首先注冊一個新的TCP連接,并將其綁定到80端口。隨后該連接進入偵聽的狀態(tài),一旦接受到客戶發(fā)起的連接請求,那么調用process_connection()函數(shù)進行處理。主要程序代碼如下:staticvoidd_thread(void*arg){ structnetconn*conn,*newconn;
/*CreateanewTCPconnectionhandle.*/ conn=netconn_new(NETCONN_TCP);100整理ppt主要程序的實現(xiàn)
/*Bindtheconnectiontoport80onany localIPaddress.*/ netconn_bind(conn,NULL,80);
/*PuttheconnectionintoLISTENstate.*/ netconn_listen(conn);
/*Loopforever.*/ while(1) { /*Acceptanewconnection.*/ newconn=netconn_accept(conn); if(newconn!=NULL) { /*Processtheincommingcon
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 某公司項目立項申請報告模板
- 冷飲售賣合同范本
- 儀器租賃押金合同范本
- 借利息合同范本
- 代銷費用結算合同范本
- 企業(yè)加工印花合同范本
- 2025年中國新型動力電池行業(yè)市場調研分析及投資戰(zhàn)略規(guī)劃報告
- 中國電網(wǎng)合同范例
- 刻字瓷像合同范本
- 買個合同范例
- 電子線檢驗標準
- 建筑施工安全員理論考核試題與答案
- 人教版七年級歷史下冊教學計劃(及進度表)
- 建筑工程節(jié)后復工自查表
- 華萊士標準化體系
- 快捷smt全自動物料倉儲方案
- keysight眼圖和抖動噪聲基礎知識與測量方法
- TPU材料項目可行性研究報告寫作參考范文
- 試用期考核合格證明表
- 鍋爐補給水陰陽混床操作步序表
- 2005年第4季度北京住房租賃指導價格
評論
0/150
提交評論