在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 教你輕松控制uClinux 嵌入式開(kāi)發(fā)過(guò)程

            教你輕松控制uClinux 嵌入式開(kāi)發(fā)過(guò)程

            作者: 時(shí)間:2012-04-19 來(lái)源:網(wǎng)絡(luò) 收藏

            恰當(dāng)?shù)膬?nèi)存分配

              除了提供跟普通Linux一樣的內(nèi)存分配器之外,還提供另一個(gè)可選的。普通Linux中缺省的內(nèi)存分配器是使用“2的冪”的分配方法,這樣可以快速找到符合要求的內(nèi)存區(qū)域。不幸的是,在下這種方法可能會(huì)帶來(lái)令人痛苦的結(jié)果。

              為了理解這一問(wèn)題帶來(lái)的結(jié)果,尤其是大的內(nèi)存分配,我們舉例說(shuō)明。試想一個(gè)應(yīng)用程序要求33KB的內(nèi)存空間進(jìn)行裝載。如果使用“2的冪”的分配方法,就必須分配64KB(2的6次方)內(nèi)存空間,多余的31KB內(nèi)存空間不能被利用上。在中,這種浪費(fèi)是不能接受的。為了解決這個(gè)問(wèn)題,專門為 uClinux內(nèi)核設(shè)計(jì)了可選的內(nèi)存分配器。不同的內(nèi)核版本,這個(gè)可選的內(nèi)存分配器不同,一般是page_alloc2和kmalloc2。

              page_alloc2能解決缺省的分配方法造成的浪費(fèi)問(wèn)題。雖然它也是使用“2的冪”的分配方法,但它是按頁(yè)(每頁(yè)4096字節(jié),即4KB)分配的,分配的內(nèi)存大小如果已經(jīng)滿足了要求,則只是將當(dāng)前的一頁(yè)分配出去,其它的就不再分配。在前面的例子中,如果使用這種方法,就只是分配36KB (≥33KB,且為整頁(yè))即可,這樣就能節(jié)省28KB的空間。

              page_alloc2還采取了一些避免內(nèi)存碎片的方法。它將所有的兩頁(yè)(8KB)或更少的內(nèi)存需求從空閑內(nèi)存開(kāi)始部分向上分配,所有大的內(nèi)存需求從剩余內(nèi)存的末尾部分開(kāi)始向下分配。這樣防止了網(wǎng)絡(luò)緩存等的臨時(shí)分配,避免了內(nèi)存碎片的出現(xiàn)。

              一旦開(kāi)發(fā)者理解了內(nèi)核內(nèi)存分配的區(qū)別,應(yīng)用程序中就會(huì)出現(xiàn)變化。

              1.沒(méi)有動(dòng)態(tài)棧的問(wèn)題

              在使用虛擬內(nèi)存的Linux上,當(dāng)一個(gè)應(yīng)用程序試圖沖銷棧頂單元時(shí),會(huì)被標(biāo)記異常,同時(shí)系統(tǒng)會(huì)映射新的內(nèi)存到棧頂以便讓棧增長(zhǎng)。在 uClinux下,由于必須在編譯階段給棧分配好內(nèi)存,所以不會(huì)有這樣的增長(zhǎng)。當(dāng)出現(xiàn)莫名其妙的崩潰或者新移植的應(yīng)用程序出現(xiàn)怪異行為時(shí),開(kāi)發(fā)者首先應(yīng)該考慮到的是給棧分配的內(nèi)存大小問(wèn)題。缺省情況下,uClinux為棧分配4KB的內(nèi)存空間,開(kāi)發(fā)者可以用下面提到的方法之一來(lái)增加棧的空間。

             ◆ 應(yīng)用程序build之前

              應(yīng)用程序build之前,可以在Makefile文件中增加以下兩行代碼:

              FLTFLAGS = -s

              export FLTFLAGS

              ◆ 應(yīng)用程序build之后

              應(yīng)用程序build之后,可以運(yùn)行以下命令:

              flthdr -s executable

              其中,stacksize 就是為棧增加的內(nèi)存空間。

              2.沒(méi)有動(dòng)態(tài)堆的問(wèn)題

              堆是C語(yǔ)言中malloc及相關(guān)函數(shù)分配內(nèi)存的區(qū)域。在有虛擬內(nèi)存的Linux上,應(yīng)用程序可能通過(guò)動(dòng)態(tài)堆在運(yùn)行過(guò)程中改變進(jìn)程的大小。這個(gè)功能是通過(guò)在底層使用sbrk()和brk()系統(tǒng)調(diào)用來(lái)實(shí)現(xiàn)的。sbrk()是在進(jìn)程的末尾增加內(nèi)存空間,所以調(diào)用sbrk()能夠使應(yīng)用程序獲得額外的內(nèi)存。

              brk()可以把任意位置設(shè)置為進(jìn)程空間的末尾,因此,可以通過(guò)調(diào)用brk()減少或增加內(nèi)存空間的占用。由于uClinux不能實(shí)現(xiàn)brk()和sbrk(),它采用了一個(gè)全局的內(nèi)存池,就是內(nèi)核的空閑內(nèi)存池。使用全局內(nèi)存池的方法有一些優(yōu)點(diǎn)。

              首先,此方法只會(huì)給進(jìn)程分配使用時(shí)真正需要的內(nèi)存。其次,內(nèi)存用完后就會(huì)被歸還給全局內(nèi)存池,而且可以利用已經(jīng)存在的內(nèi)核中的分配器來(lái)分配內(nèi)存,這樣可以減少應(yīng)用程序的代碼量。但這個(gè)方法是有缺陷的,比如,一個(gè)失控的進(jìn)程可以用完系統(tǒng)全部的可用內(nèi)存。

              新手普遍會(huì)遇到丟失內(nèi)存的問(wèn)題。系統(tǒng)會(huì)顯示大量的可用內(nèi)存,但是應(yīng)用程序卻不能得到。這正是由于內(nèi)存碎片的存在,uClinux幾乎不可能完全利用內(nèi)存,現(xiàn)有的解決方法中都存在這個(gè)問(wèn)題。這個(gè)問(wèn)題可用一個(gè)例子很好地說(shuō)明。

              假設(shè)一個(gè)系統(tǒng)有500KB的空閑內(nèi)存,為了裝載一個(gè)應(yīng)用程序需要分配100KB的空間。大家可能覺(jué)得這個(gè)需要肯定能得到滿足,然而,應(yīng)該知道,必須有 100KB連續(xù)的內(nèi)存空間才能滿足這個(gè)需要。如果有500KB的空閑空間,但是最大的連續(xù)內(nèi)存塊的大小只有80KB,這樣是沒(méi)有辦法分配給這個(gè)應(yīng)用程序的。造成這種情況有很多原因。上面講到的page_alloc2內(nèi)核分配器有一個(gè)配置選項(xiàng)可以用來(lái)識(shí)別這個(gè)問(wèn)題,在內(nèi)核源代碼page_alloc2.c 文件中可以獲得更多的信息。

              經(jīng)常有人會(huì)問(wèn)為什么不能進(jìn)行內(nèi)存的碎片整理,以便實(shí)現(xiàn)剛才的例子中的要求?原因是uClinux沒(méi)有虛擬內(nèi)存,所以不能移動(dòng)程序正在使用的內(nèi)存。在使用虛擬內(nèi)存的情況下,只要重新定位就能實(shí)現(xiàn)內(nèi)存的移動(dòng),從而實(shí)現(xiàn)內(nèi)存碎片的整理。

              在沒(méi)有虛擬內(nèi)存的情況下,由于程序經(jīng)常會(huì)引用已經(jīng)分配給它的內(nèi)存區(qū)域,這樣,如果移動(dòng)程序的內(nèi)存,程序就會(huì)崩潰。在uClinux下,現(xiàn)在還沒(méi)有解決這個(gè)問(wèn)題的辦法。開(kāi)發(fā)者需要自己注意這個(gè)問(wèn)題,如果有可能的話,盡量使用小的內(nèi)存塊。

              掌控進(jìn)程和應(yīng)用程序

              1.進(jìn)程

              有虛擬內(nèi)存的Linux和uClinux的另一個(gè)區(qū)別在于后者沒(méi)有fork()系統(tǒng)調(diào)用。這就要求開(kāi)發(fā)者在移植時(shí)對(duì)使用了fork()的應(yīng)用程序做一些工作。uClinux下惟一的選擇是使用vfork()。盡管vfork()與fork()有很多共同點(diǎn),但是它們之間的區(qū)別影響很大。

              對(duì)于不熟悉fork()和vfork()的人來(lái)說(shuō),這兩個(gè)系統(tǒng)調(diào)用都是允許將一個(gè)進(jìn)程分裂成一個(gè)父進(jìn)程和一個(gè)子進(jìn)程。當(dāng)一個(gè)進(jìn)程調(diào)用 fork()時(shí),子進(jìn)程是父進(jìn)程的一個(gè)完全拷貝,但是它不共享父進(jìn)程的任何東西,并且能夠單獨(dú)執(zhí)行,就和父進(jìn)程一樣。vfork()調(diào)用就不同了,首先,父進(jìn)程被掛起直到子進(jìn)程調(diào)用exec(),或者子進(jìn)程退出才能繼續(xù)。

              由此可見(jiàn),這個(gè)系統(tǒng)調(diào)用是用來(lái)啟動(dòng)一個(gè)新的應(yīng)用程序。其次,子進(jìn)程在vfork()返回后直接運(yùn)行在父進(jìn)程的??臻g,并使用父進(jìn)程的內(nèi)存和數(shù)據(jù)。這意味著子進(jìn)程可能破壞父進(jìn)程的數(shù)據(jù)結(jié)構(gòu)或棧,造成失敗。

              為了避免這些問(wèn)題,需要確保一旦調(diào)用vfork(),子進(jìn)程就不從當(dāng)前的??蚣苤蟹祷?,并且如果子進(jìn)程改變了父進(jìn)程的數(shù)據(jù)結(jié)構(gòu)就不能調(diào)用exit函數(shù)。子進(jìn)程還必須避免改變?nèi)謹(jǐn)?shù)據(jù)結(jié)構(gòu)或全局變量中的任何信息,因?yàn)檫@些改變都有可能使父進(jìn)程不能繼續(xù)。



            關(guān)鍵詞: uClinux 嵌入式開(kāi)發(fā)

            評(píng)論


            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉