亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        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è)計(jì)人員來規(guī)劃和控制,所以涉及內(nèi)容廣泛,需要有一個(gè)較好的通篇認(rèn)識才能解決好與內(nèi)存有關(guān)的問題。

        1 軟硬件配置

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

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

        對內(nèi)存芯片進(jìn)行選型,首先要弄清楚內(nèi)存控制器的特性,如支持的芯片類型、配置參數(shù)的標(biāo)度方法等,然后選取類型無誤、數(shù)據(jù)手冊方便進(jìn)行參數(shù)轉(zhuǎn)換或計(jì)算的內(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)存時(shí)序的資料。

        這一步工作結(jié)果將具體反映到板級支持包(BSP)的 RomInit.s文件中,如 MPC5200的 BSP里面,由RomInitSdram函數(shù)來實(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類寄存器,可以配置與某個(gè)CS引腳對應(yīng)的地址范圍和操作寬度等,一般也配置成從0開始;對于增強(qiáng)的精簡指令集機(jī)制(ARM)類CPU,做法會有許多種,需要查詢具體的芯片手冊,如S3c2410,則固定CS6和CS7用作SDRAM的片選,地址范圍固定從0x30000000開始。

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

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

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

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

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

        MMU和BAT表項(xiàng)一般在BSP的SysLib.c文件里面。

        對于X86類CPU,還有全局描述符表(GDT)、中斷描述符表(IDT)等內(nèi)存描述符需要初始化,內(nèi)存描述符規(guī)定了一段空間的大小和屬性,組成表格由段寄存器來選取,段寄存器對地址選址的計(jì)算實(shí)際上是通過內(nèi)存描述符翻譯后進(jìn)行的。Vx Works的BSP簡化了該操作,幾個(gè)段寄存器都使用一個(gè)能覆蓋所有地址空間的全功能的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)運(yùn)行,為了提高運(yùn)行速度,往往需要把代碼搬移到內(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í)行。此時(shí)代碼段在RAM_HIGH_ADRS位置,數(shù)據(jù)段緊跟在代碼段后面,BSS段緊跟在數(shù)據(jù)段后面,BSS段后面是中斷使用的堆棧,然后是bootrom_uncmp將要使用的內(nèi)存池,任務(wù)堆棧段會從內(nèi)存池申請。所以,要想讓bootrom_uncmp正常執(zhí)行,需要確保RAM_HIGH_ADRS下面有足夠的空間夠ROM做搬移時(shí)的堆棧,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代碼段大?。玍x Works數(shù)據(jù)段大小”所占的空間要盡量避免與bootrom_uncmp需要使用的空間重疊。

        (4)Vx Works獲得運(yùn)行經(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個(gè)宏有著重要的定位意義,尤其是RAM_LOW_ADRS很大程度上決定了Vx Works的內(nèi)存布局,需要斟酌一個(gè)好的位置以便既保證正常啟動、又不至于造成內(nèi)存浪費(fèi)(太高了會使內(nèi)存池縮?。R?yàn)榧扔绊懘a,也影響鏈接,所以這兩個(gè)宏的修改需要在config.h里面和makefile里面同時(shí)修改并確保一致。

        其它類型組合,如bootrom、bootrom_res、Vx-Works_rom等,結(jié)合編譯鏈接時(shí)產(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í),如果定義了一個(gè)全局變量(指函數(shù)體外的變量)并賦予了初值,則該變量會靜態(tài)占用數(shù)據(jù)段的空間,如果定義了一個(gè)全局變量但沒有賦予初值,則該變量會靜態(tài)占用BSS段的空間,如果定義了一個(gè)函數(shù)體內(nèi)的變量,則該變量會動態(tài)占用堆??臻g,這些編程實(shí)際上是在隱蔽地申請(或釋放)內(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(其實(shí)就是該段內(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ù)是單獨(dú)的內(nèi)存池的使用,實(shí)際上,主內(nèi)存池也是一個(gè)單獨(dú)的內(nèi)存池,其指針是全局變量

        創(chuàng)建一個(gè)新的內(nèi)存池,起始地址是pPool,大小是poolSize,該段內(nèi)存可以是原來系統(tǒng)內(nèi)存池之外的某一段離散的內(nèi)存,也可以是從系統(tǒng)內(nèi)存池里面申請到的一段內(nèi)存。建立了單獨(dú)的內(nèi)存池,可以在該段內(nèi)存里面單獨(dú)申請和釋放內(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)存時(shí)使用空間首先滿足的算法,找到合適的塊,多出來的部分會單獨(dú)形成一個(gè)空塊,釋放內(nèi)存時(shí)會進(jìn)行相鄰空閑內(nèi)存塊的歸并,卻不會做碎片搬移和整理。因此動態(tài)內(nèi)存雖然使用方便,但大量的小內(nèi)存操作偶爾再穿插大內(nèi)存的操作會造成內(nèi)存池的碎片,最終沒有足夠的內(nèi)存使用。而且動態(tài)申請和釋放會帶來時(shí)間上的損失。所以,在應(yīng)用層,需要考慮靜態(tài)和動態(tài)的平衡,考慮到動態(tài)情況下大量相同內(nèi)存操作的優(yōu)化。

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

        如果跟任務(wù)動態(tài)運(yùn)行有關(guān),可以考慮放在任務(wù)的函數(shù)體內(nèi),成為堆棧變量(任務(wù)的堆棧大小在創(chuàng)建任務(wù)時(shí)確定,如果擔(dān)心堆棧緊張,可以考慮對較大的變量只是把指針放在堆棧里面,而指針?biāo)傅膬?nèi)存則動態(tài)申請),不僅是動態(tài)的,而且了實(shí)現(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是一個(gè)實(shí)時(shí)嵌入式操作系統(tǒng),所以從嵌入式的角度來說,內(nèi)存配置工作是必不可少的。從實(shí)時(shí)的角度來說,掌握了通用的內(nèi)存管理函數(shù)后,還需要進(jìn)一步了解這些函數(shù)對實(shí)時(shí)性和安全性的影響,從而規(guī)劃一個(gè)比較穩(wěn)健的內(nèi)存管理系統(tǒng)。

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

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

        猜你喜歡
        堆棧寄存器內(nèi)存
        Lite寄存器模型的設(shè)計(jì)與實(shí)現(xiàn)
        “春夏秋冬”的內(nèi)存
        嵌入式軟件堆棧溢出的動態(tài)檢測方案設(shè)計(jì)*
        分簇結(jié)構(gòu)向量寄存器分配策略研究*
        基于堆棧自編碼降維的武器裝備體系效能預(yù)測
        基于內(nèi)存的地理信息訪問技術(shù)
        高速數(shù)模轉(zhuǎn)換器AD9779/AD9788的應(yīng)用
        一種用于分析MCS-51目標(biāo)碼堆棧深度的方法
        一種可重構(gòu)線性反饋移位寄存器設(shè)計(jì)
        上網(wǎng)本為什么只有1GB?
        www.av在线.com| 国产亚洲欧美精品久久久| 亚州少妇无套内射激情视频| 亚洲福利天堂网福利在线观看 | 亚洲中文字幕精品久久久| 蜜臀av在线观看| 国产精品美女久久久久久久久| 狠狠丁香激情久久综合| av天堂中文亚洲官网| 人妻av中文字幕久久| 亚洲精品国产福利一二区| 亚洲高清中文字幕精品不卡| 亚洲精品456在线播放狼人| 97久久久久人妻精品区一| 中文字幕精品无码一区二区| 亚洲AV秘 片一区二区三区| 沐浴偷拍一区二区视频| 久久久亚洲av成人网站| 日韩黑人欧美在线视频观看| 精品人妻一区二区蜜臀av| 国产日本精品一二三四区| v一区无码内射国产| 偷亚洲偷国产欧美高清| 国产一区二区在线中文字幕 | 久久半精品国产99精品国产| 视频一区二区免费在线观看| 国产av无码专区亚洲精品| 波多野结衣中文字幕久久| 久久久久久国产福利网站| 女同三级伦理在线观看| 影音先锋女人aa鲁色资源| 久久频道毛片免费不卡片| 日韩中文字幕一区二十| 人妻少妇被粗大爽.9797pw| 国产手机在线αⅴ片无码观看| 最新福利姬在线视频国产观看| 亚洲一二三四区免费视频| 欧美一区二区三区激情| 男性一插就想射是因为啥| 亚洲一区二区三区在线看| 亚洲一区二区三区无码久久|