<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

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

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

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

恰當的內存分配

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

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

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

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

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

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

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

 ◆ 應用程序build之前

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

  FLTFLAGS = -s

  export FLTFLAGS

  ◆ 應用程序build之后

  應用程序build之后,可以運行以下命令:

  flthdr -s executable

  其中,stacksize 就是為棧增加的內存空間。

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

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

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

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

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

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

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

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

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

  1.進(jìn)程

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

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

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

  為了避免這些問(wèn)題,需要確保一旦調用vfork(),子進(jìn)程就不從當前的??蚣苤蟹祷?,并且如果子進(jìn)程改變了父進(jìn)程的數據結構就不能調用exit函數。子進(jìn)程還必須避免改變全局數據結構或全局變量中的任何信息,因為這些改變都有可能使父進(jìn)程不能繼續。



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

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>