.Net Micro Framework 模拟器详解 – 基本原理

使用.Net Micro Framework 模拟器 – 基本原理

 

摘要:虚拟仪器(VI)技术在很多高成本的工业项目中扮演着越来越重要的角色,在电子产品的开发中,各种模拟器也为广大开发者方提供了便利,提高了生产力。本文介绍了微软最新的嵌入式开发框架.Net Micro Framework的模拟器。阐述了模拟器的启动过程,链接组件和注册信息等基本工作过程和原理。

Keywords

.Net Micro Framework, Hardware Emulator, Start Up, Component, Registry

 

.Net MF模拟器简介

 

.Net MF模拟器是一个.Net MF CLRWindows 版的运行环境。运行时的核心部分(执行引擎,类型系统和GC)和基础类库都和在实际设备上跑的MF一样。两者不同之处在于HAL(Hardware Abstract Layer)。模拟器的HAL层并不是实际的硬件设备驱动,而是由Windows提供的驱动代替。这里充分体现了MF的架构中层与层之间高度分离的作用,为模拟的真实性和准确性提供了基础。

下图说明了.Net Micro Framework模拟器的逻辑结构

 

模拟器组件(Emulator Components)是模拟器的组成元素,通过它们你可以开发出自定义的硬件模拟器,这里MVP刘洪峰有些不错的自定义模拟器的例子:

 

Ø .Net Micro Framework研究模拟器改造 
http://blog.csdn.net/yefanqiu/archive/2007/10/31/1860020.aspx

Ø .Net Micro Framework研究IO的模拟器
http://blog.csdn.net/yefanqiu/archive/2007/12/30/2005462.aspx

Ø .Net Micro Framework研究AD的模拟器
http://blog.csdn.net/yefanqiu/archive/2007/12/31/2006197.aspx

Ø .Net Micro Framework研究I2C总线的模拟器
http://blog.csdn.net/yefanqiu/archive/2007/12/31/2006370.aspx

 

配置引擎(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, SetupComponentInitializeComponent是不需要程序员在代码里面调用的。

 

 

注册组件

 

通过编程注册模拟器组件需要调用RegisterComponent方法。前面已经提到,模拟器的配置引擎在会在config阶段调用该方法。实际上在调用LoadDefaultComponents()的时候实际上就是在内部调用了RegisterComponent方法。使用reflector我们可以看到它的内容如下:

 

protected   virtual   void  LoadDefaultComponents()
ExpandedBlockStart.gifContractedBlock.gif
{
    
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中我们可以看到这样一个函数:

 

ExpandedBlockStart.gif ContractedBlock.gif         /**/ /// <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)

ExpandedBlockStart.gifContractedBlock.gif        
{

            button.Port 
= _emulator.FindComponentById(componentId) as Gpio.GpioPort;

            button.Key 
= key;

        }


 

FindComponentById还有一个比较常用的用途就是用于在初始化的时候检查必备的组件。例如以下代码所示:

 

public   override   void  InitializeComponent()

ExpandedBlockStart.gifContractedBlock.gif
{

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();

}

 

好了,今天暂且写到这里,关于模拟器还有很多值得探讨的地方,欢迎有兴趣的朋友与我交流。

 

参考资料:

 

MS .Net Micro Framework team Windows Embedded blog From china MVP 刘洪峰的blog .Net MF国内的资源站点Winbile.Net(正在改版) Windows Embedded 在博客园的团队blog [书籍]Embedded Programming with the .Net Micro Framework [书籍]Expert .Net Micro Framework

 

 

Enjoy !

 

黄季冬

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值