• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      Vx Works的內(nèi)存配置和管理

      2012-04-25 05:52:02殷戰(zhàn)寧
      艦船電子對抗 2012年3期
      關(guān)鍵詞:堆棧寄存器內(nèi)存

      殷戰(zhàn)寧,劉 琳

      (中國電子科技集團(tuán)公司51所,上海 201802)

      0 引 言

      對于一般編程人員尤其是Windows等通用平臺的編程人員來說,內(nèi)存配置基本上只要考慮全局變量、局部變量(堆棧變量)的合理安排,內(nèi)存管理基本上只是使用 Malloc、Free等編程接口。但對于Vx Works嵌入式操作系統(tǒng)而言,由于內(nèi)存芯片選型、內(nèi)存的地址空間分配[1]、中央處理器(CPU)級內(nèi)存管理硬件初始化、映像文件的地址定位、內(nèi)存的靜態(tài)和動態(tài)占用、內(nèi)存碎片對系統(tǒng)穩(wěn)定性的影響等諸多內(nèi)容都由設(shè)計人員來規(guī)劃和控制,所以涉及內(nèi)容廣泛,需要有一個較好的通篇認(rèn)識才能解決好與內(nèi)存有關(guān)的問題。

      1 軟硬件配置

      1.1 CPU和內(nèi)存芯片選型

      內(nèi)存需要相關(guān)的內(nèi)存控制器來操作,以便能保證內(nèi)存訪問的時序、刷新等操作。內(nèi)存控制器有些CPU自帶,如 MPC5200帶雙倍速率(DDR)控制器、同步動態(tài)隨機(jī)存儲(SDRAM)控制器,PPC860通過用戶可編程機(jī)制(UPM)來控制隨機(jī)存儲器(RAM)、S3c2410帶SDRAM控制器等;有些CPU不帶內(nèi)存控制器,如X86類型,需要橋片來對內(nèi)存進(jìn)行時序控制。

      對內(nèi)存芯片進(jìn)行選型,首先要弄清楚內(nèi)存控制器的特性,如支持的芯片類型、配置參數(shù)的標(biāo)度方法等,然后選取類型無誤、數(shù)據(jù)手冊方便進(jìn)行參數(shù)轉(zhuǎn)換或計算的內(nèi)存,合適的選型可以降低參數(shù)配置的難度,提高內(nèi)存的訪問效率。

      由于內(nèi)存參數(shù)配置是主板上電后立即就要做的事情,所以,順利與否以及穩(wěn)定與否,極大地影響隨后的代碼重定位等工作;通過硬件仿真器來調(diào)試主板,工作也往往是從配置和測試內(nèi)存開始的。摘錄MPC5200內(nèi)存配置寄存器2的部分位定義,如圖1所示。

      可以看到該寄存器的設(shè)置牽涉到tRCD、tRP、tRFC等內(nèi)存片的參數(shù)。內(nèi)存片MT48LC32M8A2的數(shù)據(jù)手冊如表1所示。

      表1 MT48LC32M8A2內(nèi)存數(shù)據(jù)表

      圖1 MPC5200配置寄存器2的部分定義

      可以看到CPU寄存器配置值的參數(shù)很方便就從內(nèi)存手冊里查到。如果選型不合適,則需要進(jìn)行參數(shù)的換算,參數(shù)的具體關(guān)系可以參看專業(yè)介紹內(nèi)存時序的資料。

      這一步工作結(jié)果將具體反映到板級支持包(BSP)的 RomInit.s文件中,如 MPC5200的 BSP里面,由RomInitSdram函數(shù)來實現(xiàn)內(nèi)存配置,其重要配置就有:

      完成配置后,再通過內(nèi)存控制器的Command寄存器等啟動Refresh,使能操作。

      X86的Vx Works由于有基本輸入輸出系統(tǒng)(BIOS)完成了內(nèi)存的配置,所以在RomInit.s里面看不到類似的過程,其它類型CPU的主板基本上都需要該操作。

      1.2 CPU和內(nèi)存地址分配

      內(nèi)存的地址對不同的CPU可以有不同的分配方法,對于X86體系,內(nèi)存一般從地址0開始,跳過A、B段(顯示內(nèi)存),C、D段(卡式設(shè)備內(nèi)存空間),E、F段(BIOS空間)后,繼續(xù)從0x100000連續(xù)分配。對于CPU命令架構(gòu)()類CPU,則一般有CSx類寄存器,可以配置與某個CS引腳對應(yīng)的地址范圍和操作寬度等,一般也配置成從0開始;對于增強的精簡指令集機(jī)制(ARM)類CPU,做法會有許多種,需要查詢具體的芯片手冊,如S3c2410,則固定CS6和CS7用作SDRAM的片選,地址范圍固定從0x30000000開始。

      此類寄存器的設(shè)置也需要在RomInit.s里面設(shè)置好。

      1.3 CPU級內(nèi)存管理硬件初始化

      CPU一般都有存儲器管理單元(MMU)、塊地址翻譯(BAT)等硬件機(jī)制來對內(nèi)存空間分段或分頁管理,對不同的段頁配置不同的虛實地址對應(yīng)關(guān)系、讀寫屬性、Cache屬性、保護(hù)屬性等。這部分操作Vx Works開發(fā)人員無需直接訪問寄存器,只需填寫用來配置MMU或BAT的結(jié)構(gòu)數(shù)組,如MMU配置:

      該配置器就描述了一段內(nèi)存的虛地址、實地址、大小、屬性使能、屬性等;主內(nèi)存地址空間一般都配置為不做虛實轉(zhuǎn)換、可寫、可Cache等。該表項會由Usr MmuInit函數(shù)里面讀取并配置到MMU,而且也可以通過Sys Mmu Map Add等維護(hù)函數(shù)做增刪。

      BAT表一般用于CPU命令架構(gòu)(PPC)類寄存器,可以定義代碼段、數(shù)據(jù)段、段大小、Cache屬性等,可以與MMU組合使用,也可以單獨使用,相關(guān)的BSP也提供結(jié)構(gòu)數(shù)組進(jìn)行維護(hù)。

      MMU和BAT表項一般在BSP的SysLib.c文件里面。

      對于X86類CPU,還有全局描述符表(GDT)、中斷描述符表(IDT)等內(nèi)存描述符需要初始化,內(nèi)存描述符規(guī)定了一段空間的大小和屬性,組成表格由段寄存器來選取,段寄存器對地址選址的計算實際上是通過內(nèi)存描述符翻譯后進(jìn)行的。Vx Works的BSP簡化了該操作,幾個段寄存器都使用一個能覆蓋所有地址空間的全功能的GDT進(jìn)行工作。

      對于Cache使能否,一般還會有針對所有的Cache、代碼 Cache、數(shù)據(jù) Cache、一級 Cache、二級Cache等不同的硬件開關(guān),可能會在RomInit.s,Sys Alib.s通過匯編來操作,也可以在UsrInit,Usr-Root函數(shù)里面通過CacheEnable等函數(shù)來操作,需要檢查確認(rèn)。

      1.4 映像文件的地址定位

      一般而言,CPU上電后先是在只讀存儲器(ROM)(或Flash等)內(nèi)運行,為了提高運行速度,往往需要把代碼搬移到內(nèi)存去繼續(xù)執(zhí)行,數(shù)據(jù)相關(guān)段(Data、沒有初值的全局變量符號(BSS)段)則需指向內(nèi)存區(qū)域并得到正確的初始化,堆棧段也需要指向內(nèi)存,段與段之間需要滿足一定的定位關(guān)系,比如不互相重疊等。

      以最常用的bootrom_uncmp+ Vx Works啟動組合為例:

      (1)上電后執(zhí)行在只讀存儲器(ROM)里面的bootrom_uncmp映像,初始化CPU、內(nèi)存控制器等,堆棧底設(shè)置在宏RAM_HIGH_ADRS決定的位置(棧頂朝地址低端)。

      (2)ROM 里 面 的 程 序 會 把 ROM 里 面 的bootrom_uncmp映像拷貝到起始位置是RAM_HIGH_ADRS的內(nèi)存區(qū)域,然后跳轉(zhuǎn)到內(nèi)存來繼續(xù)執(zhí)行。此時代碼段在RAM_HIGH_ADRS位置,數(shù)據(jù)段緊跟在代碼段后面,BSS段緊跟在數(shù)據(jù)段后面,BSS段后面是中斷使用的堆棧,然后是bootrom_uncmp將要使用的內(nèi)存池,任務(wù)堆棧段會從內(nèi)存池申請。所以,要想讓bootrom_uncmp正常執(zhí)行,需要確保RAM_HIGH_ADRS下面有足夠的空間夠ROM做搬移時的堆棧,RAM_HIGH_ADRS上面有足夠空間存放代碼、數(shù)據(jù)和用來做內(nèi)存申請。

      (3)內(nèi)存里面bootrom_uncmp的執(zhí)行會下載Vx Works,把Vx Works映像拷貝到起始位置是RAM_LOW_ADRS的內(nèi)存區(qū)域,然后跳到該內(nèi)存繼續(xù)執(zhí)行。為了確保bootrom_uncmp拷貝 Vx-Works期間不會發(fā)生Vx Works覆蓋bootrom_uncmp的現(xiàn)象,“RAM_LOW_ADRS+Vx Works代碼段大小+Vx Works數(shù)據(jù)段大小”所占的空間要盡量避免與bootrom_uncmp需要使用的空間重疊。

      (4)Vx Works獲得運行經(jīng)過再次初始化后,代碼段在RAM_LOW_ADRS位置,數(shù)據(jù)段緊跟在代碼段后面,BSS段緊跟在數(shù)據(jù)段后面,BSS段后面是中斷使用的堆棧,然后是WDB專用的內(nèi)存池,然后是Vx Works將要使用的內(nèi)存池,堆棧會先設(shè)置在RAM_LOW_ADRS開始朝下生長以滿足usr Root啟動前的使用,然后會設(shè)置到靠近系統(tǒng)內(nèi)存頂端以滿足usr Root的使用并利于回收到內(nèi)存池,以后的任務(wù)堆棧就是從內(nèi)存池里面申請。

      可以看到RAM_HIGH_ADRS和RAM_LOW_ADRS 2個宏有著重要的定位意義,尤其是RAM_LOW_ADRS很大程度上決定了Vx Works的內(nèi)存布局,需要斟酌一個好的位置以便既保證正常啟動、又不至于造成內(nèi)存浪費(太高了會使內(nèi)存池縮?。?。因為既影響代碼,也影響鏈接,所以這兩個宏的修改需要在config.h里面和makefile里面同時修改并確保一致。

      其它類型組合,如bootrom、bootrom_res、Vx-Works_rom等,結(jié)合編譯鏈接時產(chǎn)生的map文件或符號表文件,同樣可以做出類似的分析。

      根據(jù)地址定位關(guān)系可以大概知道內(nèi)存池的起始位置,通過map文件或符號表文件來看,一般是BSS段的結(jié)束 +I(xiàn)SR_STACK_SIZE + WDB_STACK_SIZE,而內(nèi)存池的結(jié)束位置由Sys Mem-Top函數(shù)決定,一般來說是 LOCAL_M(jìn)EM_LOCAL_ADRS+LOCAL_M(jìn)EM_SIZE- USER_RESERVED_M(jìn)EM。

      2 接口函數(shù)

      接口函數(shù)主要是指創(chuàng)建內(nèi)存池、動態(tài)申請和釋放內(nèi)存的函數(shù),但需要額外說明的是,當(dāng)書寫C/C++源碼時,如果定義了一個全局變量(指函數(shù)體外的變量)并賦予了初值,則該變量會靜態(tài)占用數(shù)據(jù)段的空間,如果定義了一個全局變量但沒有賦予初值,則該變量會靜態(tài)占用BSS段的空間,如果定義了一個函數(shù)體內(nèi)的變量,則該變量會動態(tài)占用堆棧空間,這些編程實際上是在隱蔽地申請(或釋放)內(nèi)存。下面列舉常用的針對內(nèi)存池的接口函數(shù)。

      2.1 第1類函數(shù)

      第1類函數(shù)是主內(nèi)存的參數(shù)設(shè)置和使用:

      設(shè)置內(nèi)存池的屬性,包括:

      MEM_ALLOC_ERROR_LOG_FLAG

      當(dāng)內(nèi)存分配出錯則打出log信息:

      MEM_ALLOC_ERROR_SUSPEND_FLAG

      當(dāng)任務(wù)內(nèi)存分配出錯,則把任務(wù)掛起(除非任務(wù)設(shè)置了VX_UNBREAKABLE屬性):

      MEM_BLOCK_ERROR_LOG_FLAG

      當(dāng)內(nèi)存釋放出錯則打出log信息:

      MEM_BLOCK_ERROR_SUSPEND_FLAG

      當(dāng)任務(wù)內(nèi)存釋放出錯,則把任務(wù)掛起(除非任務(wù)設(shè)置了VX_UNBREAKABLE屬性):

      申請大小為nBytes的內(nèi)存,返回該內(nèi)存的ptr(其實就是該段內(nèi)存的起始地址):

      釋放已申請的一段內(nèi)存,傳入該段內(nèi)存的ptr(起始地址)作為參數(shù):

      申請elemSize*elem Num大小的內(nèi)存,該段內(nèi)存會被清0:

      申請size的內(nèi)存,內(nèi)存起始地址滿足alignment的要求。

      2.2 第2類函數(shù)

      第2類函數(shù)是單獨的內(nèi)存池的使用,實際上,主內(nèi)存池也是一個單獨的內(nèi)存池,其指針是全局變量

      創(chuàng)建一個新的內(nèi)存池,起始地址是pPool,大小是poolSize,該段內(nèi)存可以是原來系統(tǒng)內(nèi)存池之外的某一段離散的內(nèi)存,也可以是從系統(tǒng)內(nèi)存池里面申請到的一段內(nèi)存。建立了單獨的內(nèi)存池,可以在該段內(nèi)存里面單獨申請和釋放內(nèi)存,而不影響其它的內(nèi)存。返回值是內(nèi)存池指針:

      內(nèi)存池partId的參數(shù)配值,含義同 memOptionsSet:

      在partId的內(nèi)存池里面申請nBytes的內(nèi)存:

      釋放已申請的pBlock內(nèi)存回partId的內(nèi)存池:

      在partId里面申請nBytes的內(nèi)存,內(nèi)存起始地址滿足alignment的要求。

      2.3 第3類函數(shù)

      第3類函數(shù)是內(nèi)存池的維護(hù)函數(shù):增加一段新的內(nèi)存給主內(nèi)存池:

      增加一段新的內(nèi)存給內(nèi)存池partId:

      察看主內(nèi)存池的信息列表:

      察看內(nèi)存池partId的信息列表。

      3 應(yīng)用優(yōu)化

      Vx Works申請內(nèi)存時使用空間首先滿足的算法,找到合適的塊,多出來的部分會單獨形成一個空塊,釋放內(nèi)存時會進(jìn)行相鄰空閑內(nèi)存塊的歸并,卻不會做碎片搬移和整理。因此動態(tài)內(nèi)存雖然使用方便,但大量的小內(nèi)存操作偶爾再穿插大內(nèi)存的操作會造成內(nèi)存池的碎片,最終沒有足夠的內(nèi)存使用。而且動態(tài)申請和釋放會帶來時間上的損失。所以,在應(yīng)用層,需要考慮靜態(tài)和動態(tài)的平衡,考慮到動態(tài)情況下大量相同內(nèi)存操作的優(yōu)化。

      頻繁申請和釋放的內(nèi)存建議改成靜態(tài)的方式,以避免時間上的損失,如果不想使用全局?jǐn)?shù)組或結(jié)構(gòu)這樣的方式,也可以使用動態(tài)方式申請下來一塊內(nèi)存,然后進(jìn)行強制類型轉(zhuǎn)換。

      如果跟任務(wù)動態(tài)運行有關(guān),可以考慮放在任務(wù)的函數(shù)體內(nèi),成為堆棧變量(任務(wù)的堆棧大小在創(chuàng)建任務(wù)時確定,如果擔(dān)心堆棧緊張,可以考慮對較大的變量只是把指針放在堆棧里面,而指針?biāo)傅膬?nèi)存則動態(tài)申請),不僅是動態(tài)的,而且了實現(xiàn)了任務(wù)與任務(wù)的隔離。

      Vx Works上的網(wǎng)卡驅(qū)動就是采用這樣的方式來管理接收和發(fā)送緩沖:通過動態(tài)方式申請下來一塊內(nèi)存,建立不同大小的cluster的數(shù)組,并為cluster設(shè)置管理屬性,然后建立申請和釋放cluster的函數(shù)。

      動態(tài)的大量相同內(nèi)存操作建議自己建立一套機(jī)制來管理,如通過message queue的協(xié)助來管理。

      4 結(jié)束語

      Vx Works是一個實時嵌入式操作系統(tǒng),所以從嵌入式的角度來說,內(nèi)存配置工作是必不可少的。從實時的角度來說,掌握了通用的內(nèi)存管理函數(shù)后,還需要進(jìn)一步了解這些函數(shù)對實時性和安全性的影響,從而規(guī)劃一個比較穩(wěn)健的內(nèi)存管理系統(tǒng)。

      [1]王金剛,高偉,蘇琪.Vx Work程序員指南[M].北京:清華大學(xué)出版社,2003.

      [2]周戶平,張楊.Vx Work程序員速查手冊[M].北京:機(jī)械工業(yè)出版社,2005.

      猜你喜歡
      堆棧寄存器內(nèi)存
      Lite寄存器模型的設(shè)計與實現(xiàn)
      “春夏秋冬”的內(nèi)存
      嵌入式軟件堆棧溢出的動態(tài)檢測方案設(shè)計*
      分簇結(jié)構(gòu)向量寄存器分配策略研究*
      基于堆棧自編碼降維的武器裝備體系效能預(yù)測
      基于內(nèi)存的地理信息訪問技術(shù)
      高速數(shù)模轉(zhuǎn)換器AD9779/AD9788的應(yīng)用
      一種用于分析MCS-51目標(biāo)碼堆棧深度的方法
      一種可重構(gòu)線性反饋移位寄存器設(shè)計
      上網(wǎng)本為什么只有1GB?
      泰宁县| 资源县| 杂多县| 宁波市| 新丰县| 崇信县| 维西| 阜新| 凭祥市| 海宁市| 大余县| 万州区| 洛宁县| 张家口市| 乌什县| 松滋市| 大庆市| 托克逊县| 城口县| 南乐县| 玉树县| 翁牛特旗| 永州市| 五河县| 乌苏市| 司法| 孝义市| 若尔盖县| 东乌珠穆沁旗| 茌平县| 郎溪县| 海安县| 博野县| 泸水县| 通城县| 山阴县| 思南县| 玉山县| 通化县| 清远市| 安乡县|