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

.Net Micro Framework 模擬器詳解 – 基本原理

編輯:關於.NET

摘要:虛擬儀器(VI)技術在很多高成本的工業項目中扮演著越來越重要的角色,在電子產品的開發中,各種模擬器也為廣大開發者方提供了便利,提高了生產力。本文介 紹了微軟最新的嵌入式開發框架.Net Micro Framework的模擬器。闡述了模擬器的啟動過程,鏈接組件和注冊信息等基本工作過程和原理。

.Net MF模擬器簡介

.Net MF模擬器是一個.Net MF CLR的Windows 版的運行環境。運行時的核心部分(執行引擎,類型系統和GC等)和基礎類庫都和在實際設備上跑的MF一樣。兩者不同之 處在於HAL層(Hardware Abstract Layer)。模擬器的HAL層並不是實際的硬件設備驅動,而是由Windows提供的驅動代替。這裡充分體現了MF的架構中層與層之間高度分離的 作用,為模擬的真實性和准確性提供了基礎。

下圖說明了.Net Micro Framework模擬器的邏輯結構

模擬器組件(Emulator Components)是模擬器的組成元素,通過它們你可以開發出自定 義的硬件模擬器,這裡MVP劉洪峰有些不錯的自定義模擬器的例子:

Ø.Net Micro Framework研究—模擬器改造

Ø.Net Micro Framework研究—帶IO的模擬器

Ø.Net Micro Framework研究—帶AD的模擬器

Ø.Net Micro Framework研究—帶I2C總線的模擬器

配置引擎(Configuration Engine)用於在運行時把組件裝配在一起。它使用XML來描述硬件模型的各種配置參數。

啟動過程

在調試的時候,我們只需要在 項目屬性中選擇模擬器作為部署目標。在部署的時候,模擬器會自動被調用並運行我們的程序,但是這個過程掩蓋了模擬器啟動的細節。.Net Micro Framework的模擬器也 就是一個.Net(通常是Windows Form)應用程序,只不過模擬器加入了組件(Component)和XML配置文件(Emulator.config)的內容。當模擬器啟動的時候:

1. 加載默認 組件

模擬器的LoadDefaultComponents()虛方法被調用,它通過調用一系列的RegisterComponent方法來創建模擬器默認的基本組件。您也通過配置文件 (Emulator.config)對這些默認組建進行配置,替換或者刪除。在代碼裡面我們也可以通過Emulator類的一系列屬性來訪問這些默認組件。

2.讀取配置文件

默認的組件被構造完畢之後,Emulator的配置引擎會去讀取XML配置文件(Emulator.config)。配置文件中描述的組件會被按要求創建並注冊。此時調用了Emulator類的 Configure(System.Xml.XmlReader reader)方法來從XML配置文件中解析類型。

3.安裝組件

經過前兩步,所有組件都已經配置完畢了。這時候系統會去調用 Emulator和自定義組件類的SetupComponent方法來組裝之前創建好的組件。

4.初始化組件

在所有組件安裝完畢以後,Emulator類和EmulatorComponent類的 InitializeComponent方法會被調用,來對各個組件進行初始化。

5.加載.Net Micro Framework的程序集

6.運行模擬器

在實際的開發過程中,一般來 說,除非是要開發自己的模擬器組件,否則Configure, SetupComponent和InitializeComponent是不需要程序員在代碼裡面調用的。

注冊組件

通過編程注冊 模擬器組件需要調用RegisterComponent方法。前面已經提到,模擬器的配置引擎在會在config階段調用該方法。實際上在調用LoadDefaultComponents()的時候實際上就是在 內部調用了RegisterComponent方法。使用reflector我們可以看到它的內容如下:

protected virtual void LoadDefaultComponents()
{
  this.RegisterComponent(new Hal());
  this.RegisterComponent(new ComPortCollection());
  this.RegisterComponent(new GpioCollection());
  this.RegisterComponent(new SpiBus());
  this.RegisterComponent(new MemoryManager());
  this.RegisterComponent(new TimingServices());
  this.RegisterComponent(new I2cBus());
  this.RegisterComponent(new SerialPortCollection());
  this.RegisterComponent(new NamedPipeServer());
}

實際上LoadDefaultComponents()就是在為默認的組件進行注冊。

如果是手動注冊,需要注意的是,如果一個組件包含於另一個組件那麼子組件注冊的同 時需要提供父組件給RegisterComponent的一個重載方法。在調用UnregisterComponent移除組件的時候,所有鏈接到它的子組件都會被自動刪除。例如MemoryManager組件, 它有兩個子組件RamManager 和 FlashManager。當我們移除MemoryManager時,RamManager 和 FlashManager也會被移除。

訪問已注冊組件

已注冊的模擬器組 件可以通過Emulator類的FindComponentById方法來訪問。我們經常會調用這個函數來對指定的組件進行初始化。例如在SDK提供的SampleEmulator中我們可以看到這樣一個 函數:

    /**//// <summary>
    /// Helper method to initialize buttons.
    /// </summary>
    /// <param name="button">The button to be initialized.</param>
    /// <param name="componentId">
    /// The string identifying the button,
    /// found in the config file
    /// </param>
    /// <param name="key">The key that this button should respond to.</param>
    private void InitializeButton(Button button, string componentId, Keys key)
    {
      button.Port = _emulator.FindComponentById(componentId) as Gpio.GpioPort;
      button.Key = key;
    }

FindComponentById還有一個比較常用的用途就是用於在初始化的時候檢查必備的組件。例如以下代碼所示:

public override void 

InitializeComponent()
{
base.InitializeComponent();
//以下兩行代碼即檢查了模擬器是否有名為“Pin_Down”的組件
//同時也檢查了該組件的類型是不是GpioPort
if (FindComponentById("Pin_Down") as GpioPort == null)
throw new Exception("The component 'Pin_Down' is required by the emulator.");
// 啟動UI線程
Thread uiThread = new Thread(StartForm);
uiThread.Start();
}

好了,今天暫且寫到這裡,關於模擬器還有很多值得探討的地方,歡迎有興趣的朋友與我交流。

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