程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> .Net Micro Framework 模擬器詳解---內存配置

.Net Micro Framework 模擬器詳解---內存配置

編輯:關於.NET

摘要:對嵌入式設備來說,存儲空間的大小無疑是一個很重要的參數,但是調試的時候我們通常無法方便地對不同內存大小的設備進行測試。這時候使用模擬器是一個很 好的選擇,本文介紹了如何在.Net Micro Framework中通過代碼和XML配置文件兩種方式來配置模擬器的Memory(包括Ram和Flash Memory)。並使得模擬器具有持久存儲的能 力。

在.Net Micro Framework中,提供了MemoryManager 類型(見Microsoft.SPOT.Emulator.Memory命名空間)來描述和模擬RAM和FLASH。不過這個類型本身並不直接提供屬性 和方法來對模擬器的存儲空間進行配置,而是提供了以下兩個屬性:RamManager和FlashManager 。這兩個屬性同屬於微軟提供的模擬器組件(Emulator Components)。它們 都是由Memorymanager跟據你的配置動態創建的。你可以在Emulator的配置文件裡面來完成RAM和FLASH的配置,這我們將在後文討論。

Random Access Memory (RAM)

前面提到的MemoryManager.RamManager是一個同名類型(RamManager)的屬性,對於RamManager類型,唯一你可以設置(set)的屬性就是Size,它表示了RAM的大小, 單位是byte。在配置文件裡面,你需要先在”<Types>”的標簽區域內將MemoryManager 和RamManager標簽添加進來,這就像C#代碼中的using一樣,使得 EmulatorComponents內的MemoryManager 和RamManager標簽能被模擬器的配置引擎解析出來。下面的XML代碼演示了如何在配置文件裡以一個16進制數0x2000000來設置32兆 的RAM:

<?xml version="1.0" encoding="utf-8"?>
<Emulator>
<Types>
<MemoryManager>Microsoft.SPOT.Emulator.Memory.MemoryManager</MemoryManager>
<RamManager>Microsoft.SPOT.Emulator.Memory.RamManager</RamManager>
</Types>
<EmulatorComponents>
<MemoryManager>
<RamManager type="RamManager">
<Size format="HexNumber">2000000</Size>
</RamManager>
</MemoryManager>
</EmulatorComponents>
</Emulator>

需要注意的是,模擬器的RAM默認情況下只有1Mbyte

之前我嘗試在帶有VGA(640x480)的LCD模擬器上嘗試顯示大圖的時候,Visual Studio 會拋出以下異常:

Failed allocation for 51205 blocks, 614460 bytes

在System.OutOfMemoryException 中第一次偶然出現的 “Microsoft.SPOT.Graphics.dll”類型的異常

未處理的“System.OutOfMemoryException”類型的異常出現在Microsoft.SPOT.Graphics.dll 中。

在我把模擬器的內存配置為32兆之後就不再出現這個問題了。這是因為模擬器默認的RAM大小為1024kb.而我的圖片640*480*16/8=bmp600kb+圖片77kb+應用用程 序大小已經超過了RAM的分配限制。

FLASH

和RamManager類似,FlashManager同樣以MemoryManager的一個屬性的方式供開發人員來配置。相對RAM來說FLASH的 存儲區域顯得不是那麼單純。FLASH的存儲單位(包括讀和寫)是扇區 (sector)。由一個或多個扇區構成了功能不同的段(block),用來存放不同的內容。而通常我們說的一 個分區(partition)又是由一個或多個段構成的,不過Micro Framework設備的Flash目前均只有一個分區(暫時只支持一個分區), 所以即將推出的MF文件系統(.Net MF 3.0 feature)和Windows Mobile一樣,都將只有一個根目錄索引,而不會和Windows一樣還有盤符之類的標識。FlashManager類用來管理sector,在Emulator.config中,每一對 FlashSector標簽都對應著這樣的一個結構:

public struct FlashSector
{
public uint Length;//sector的長度
public FlashSectorUsage Usage;//sector的用處
public FlashSectorPartition Partition;//分區
public FlashSectorBlock Block;//段
public FlashSector(uint length,
FlashSectorUsage usage,
FlashSectorPartition partition,
FlashSectorBlock block);
public FlashSector(uint length,
FlashSectorUsage usage,
FlashSectorPartition partition);
}

和RamManager不同的是,對FlashManager來說,Size屬性是不需要制定的,因為它的存儲空間大小會由你配置的Sectors自動計算出來,除了Size之外它還具有以 下可以設置的屬性:

• bool IsReadOnly

• uint MaxSectorEraseTime

• uint MaxWordWriteTime

FLASH的第一個sector必須 將Partition和Block設為Start(或者StartEnd, 如果該sector為Partition或Block包含的唯一sector)。最後一個sector必須將Partition和Block配置為End。總之,Start 和End總是成對存在的,表示一個sector是某個分區或者段的開始和結束。 否則在構造模擬器的時候Visual Studio會拋出異常,例如:

值得一提的是FlashSector 的Usage 屬性,它是FlashSectorUsage枚舉類型,它的可用 成員如下表:

  成員名稱 描述   Application 指明當前的sector用來存放application code.   Bootstrap 指明當前的sector用來存放 bootstrap code.   Code 指明當前的sector用來 存放 common language runtime (CLR) code.   Config 指明當前的sector用來存放配置信 息.   Deployment 指明當前的sector用來存放 client application code.   Log 指明當前的 sector用來存放操作記錄.   StorageA 指明當前的sector用來存放 programmer-defined data.   StorageB 指明當前的sector用來存放 programmer-defined data.

這些描述信息都將被.Net Micro Framework用於優化和校驗程序。對應的XML配置文件(Emulator.config)如下:

首先在”<Types>”標簽內加入以下兩行聲明:

<FlashManager>Microsoft.SPOT.Emulator.Memory.FlashManager</FlashManager>
<FlashSector>Microsoft.SPOT.Emulator.Memory.FlashSector</FlashSector>

然後就可以在<MemoryManager>中進行配置了:

Code

<FlashManager type="FlashManager">
<FlashSectors>
<FlashSector>
<Length format="HexNumber">10000</Length>
<Usage>Bootstrap</Usage>
<Partition>Start</Partition>
<Block>StartEnd</Block>
</FlashSector>
  
<FlashSector>
<Length format="HexNumber">10000</Length>
<Usage>Config</Usage>
<Partition>None</Partition>
<Block>StartEnd</Block>
</FlashSector>
  
<FlashSector>
<Length format="HexNumber">10000</Length>
<Usage>Code</Usage>
<Partition>None</Partition>
<Block>StartEnd</Block>
</FlashSector>
  
<FlashSector>
<Length format="HexNumber">10000</Length>
<Usage>Deployment</Usage>
<Partition>None</Partition>
<Block>StartEnd</Block>
</FlashSector>
  
<FlashSector>
<Length format="HexNumber">10000</Length>
<Usage>Log</Usage>
<Partition>None</Partition>
<Block>StartEnd</Block>
</FlashSector>
  
<FlashSector>
<Length format="HexNumber">10000</Length>
<Usage>StorageA</Usage>
<Partition>None</Partition>
<Block>StartEnd</Block>
</FlashSector>
  
<FlashSector>
<Length format="HexNumber">10000</Length>
<Usage>StorageB</Usage>
<Partition>End</Partition>
<Block>StartEnd</Block>
</FlashSector>
</FlashSectors>
</FlashManager>

注意這裡實際上模擬器的FlashSector總的大小是1024kb,可以參 考:

http://www.cnblogs.com/yefanqiu/archive/2008/04/18/1160636.html

真正的模擬Flash – 持久存儲

實際上在前面提到的Flash並不是嚴 格意義上的Flash,畢竟只是模擬。而模擬器本身又是一個在PC機的內存中運行的一個程序,在你關閉了模擬器之後,你存在模擬器的Flash中的數據還是會丟失。不過我們 在.Net Micro Framework的SDK中可以找到一個叫”EWRSampleEmulator”的Sample,它在”Microsoft .NET Micro Framework"Samples"ExtendedWeakReferences”目錄下。這個Sample模擬器在關閉時會將Flash中的內容寫到一個本地文件裡面去。在模擬器下一次啟動的 時候,會從這些存在PC機上的數據文件去初始化模擬器,從而模擬Flash持久存儲數據的特征。下面我們通過一個繼承自FlashManager的類看看它是如何實現這個持久存儲的 過程的:

public class PersistentFlashManager : FlashManager
  {
    //定義保存flash文件的路徑
    private readonly string flashPath;
    public PersistentFlashManager()
    {
      //以.flash為後綴初始化flash保留文件路徑
      string emulatorPath =
      Assembly.GetEntryAssembly().GetModules()[0].FullyQualifiedName;
      this.flashPath = Path.ChangeExtension(emulatorPath, ".flash");
    }
    /**//// <summary>
    /// 在初始化模擬器的Flash組件時
    /// 讀取本地保留的Flash文件(如果有的話)
    /// </summary>
    public override void InitializeComponent()
    {
      base.InitializeComponent();
      if (File.Exists(this.flashPath))
      {
        using (FileStream stream = File.OpenRead(this.flashPath))
        {
          if (stream.Length == this._size)
            stream.Read(this._memory, 0, (int)this._size);
        }
      }
    }
    /**//// <summary>
    /// 在寫入到本地文件後再卸載Flash組件
    /// </summary>
    public override void UninitializeComponent()
    {
      using (FileStream stream = File.OpenWrite(this.flashPath))
        stream.Write(this._memory, 0, (int)this._size);
      base.UninitializeComponent();
    }
}

使用這個類配置模擬器的時候,需要在“<Types>”標簽裡面先聲明這個類以及它所在的程序集名稱。簡單來說就是把配置文件默認的 FlashManager聲明:

<FlashManager>Microsoft.SPOT.Emulator.Memory.FlashManager</FlashManager>

用類似:

<FlashManager>MyNameSpace.PersistentFlashManager,

MyAssemblyName</FlashManager>

替換掉即可。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved