模拟嵌入式处理器的多个实例

时间:2012-01-10 16:26:40

标签: vb.net visual-studio dll embedded simulation

我正在开展一个需要多个设备的项目,每个设备都有一个嵌入式(ARM)处理器进行通信。我在过去发现的一个开发方法,只需要一个嵌入式处理器的项目就是使用Visual Studio开发代码,分为三个部分:

  1. 主要应用程序代码(在非托管C / C ++中[见注释])
  2. 在Visual Studio下运行的I / O模拟代码(C / C ++)
  3. Visual Studio被指示不构建的嵌入式I / O代码(C)在目标系统上运行。以前这段代码是针对PIC的;对于我将来迁移到ARM的大多数未来项目。

为嵌入式编译器/链接器提供第1部分和第3部分中的代码,可生成可在目标系统上运行的hex文件。运行第1部分和第2部分可生成可在PC上运行的代码,具有更好的调试工具和更精确的I / O行为控制(例如,我可以使模拟代码比我更容易引入某些类型的随机打嗝在真实硬件上引起控制性打嗝。)

目标代码用C语言编写,但仿真环境使用C ++来模拟I / O寄存器。例如,我有一个PortArray数据结构;嵌入式编译器的头文件包含像unsigned char LATA @ 0xF89;这样的行,我的模拟头文件包含#define LATA _IOBIT(f89,1),后者又调用一个访问I / O对象的合适属性的宏,所以像这样的语句LATA |= 4;将读取模拟的锁存器,"或"读取值为4,并写入新值。为了使这项工作,目标代码必须在C ++和C下编译,但这不是一个问题。最大的烦恼可能是enum类型(在C中表现为整数,但必须在C ++中哄骗)。

以前,我使用了两种方法使模拟互动:

  1. 编译DLL并将其与目标应用程序和模拟代码链接,并在与其交互的同一项目中使用VB代码。
  2. 将目标应用程序代码和一些模拟代码编译到带有Visual Studio实例的EXE,并使用Visual Studio的第二个实例进行模拟UI。让这两个程序通过TCP进行通信,因此几乎所有的程序都是真实的" I / O逻辑在模拟程序中。例如,前面提到的`LATA | = 4;`将发送"读端口0xF89"命令到TCP端口,获取响应,处理接收到的值,并发送"写入端口0xF89"命令结果。

我发现后一种方法在某些情况下运行速度比前者慢一点,但它似乎更方便调试,因为我可以暂停执行非托管模拟代码,同时模拟UI保持响应。实际上,为了一次模拟单个目标设备,我认为后一种方法非常有效。我的问题是我应该如何最好地模拟多个目标设备(例如16个)。

我遇到的困难是弄清楚如何让每个模拟实例获得自己的全局变量集。如果我要编译成EXE并为每个模拟目标设备运行一个EXE实例,那就行了,但我不知道在这样做的同时保持调试器支持的任何实用方法。另一种方法是安排目标代码,以便在通过#include将一个模块连接在一起时编译所有内容。出于模拟目的,可以将所有内容包装到单个C ++类中,并将全局变量转换为类实例变量。这将更加面向对象,但我真的不喜欢强制所有应用程序代码存在于一个编译和链接模块中。

如果代码可以加载DLL的多个实例,每个实例都有自己的一组全局变量,那么可能是理想的。我不知道该怎么做,但是,我也不知道如何使事情与调试器交互。我并不认为所有模拟目标设备实际上同时执行代码是非常必要的。模拟实例使用协作式多任务处理是完全可以接受的。如果有某种方法可以找出全局变量的内存范围,那么就可以进行“任务 - 切换”操作。方法交换先前运行的实例使用的所有全局变量,并交换适用于正在切换的实例的内容。虽然我知道如何在嵌入式上下文中执行此操作,但是,我'我不知道如何在PC上做到这一点。

修改

我的问题是:

  1. 是否有更好的方法允许在VS2010调试器中暂停和检查模拟逻辑,同时保持模拟器前端的响应式UI,而不是在单独的实例中运行模拟器前端和模拟器逻辑VS2010,如果模拟逻辑必须用C编写,模拟前端必须用托管代码编写?例如,有没有办法告诉调试器,当一个断点被命中时,应该允许一些或所有其他线程继续运行,而碰到断点的线程暂停?
  2. 如果大部分模拟逻辑必须与用C编写的嵌入式系统源代码兼容(这样可以在VS2010下编译和运行相同的源文件用于模拟目的,然后由用于真实硬件的嵌入式系统编译器,有没有办法让VS2010调试器与嵌入式设备的多个模拟实例进行交互?假设性能不太可能是一个问题,但实例的数量将足够大,因此在没有任何方法自动化该过程的情况下,为每个实例创建单独的项目可能会很烦人。我可以想到三种有些可行的方法,但不知道如何使它们中的任何一种都能很好地工作。如果可行的话,还有一种更好的方法,但我不知道如何使其发挥作用。
    1. 将所有模拟代码包装在单个C ++类中,以便目标系统中的全局变量成为类成员。我倾向于这种方法,但它似乎要求将所有内容编译为单个模块,这会令目标系统代码的设计烦恼。有没有什么好方法可以让代码访问类实例成员就像它们是全局变量一样,而不需要使用这些实例的所有函数都是同一模块的成员?
    2. 为每个模拟实例编译一个单独的DLL(例如,如果我想运行多达16个实例,我将在项目中包含16个DLL,它们共享相同的源文件)。这可能有效,但项目配置的每次更改都必须重复16次。真的很难看
    3. 将模拟逻辑编译为EXE,并运行该EXE的适当数量的实例。这可能会有效,但我不知道有什么方便的方法可以设置一个对所有实例都通用的断点。是否可以将多个EXE的运行实例连接到单个调试器实例?
    4. 加载DLL的多个实例,使每个实例获得自己的全局变量,同时仍可在调试器中访问。如果可能的话,这将是最好的,但我不知道如何做到这一点。可能吗?怎么样?我从未使用过AppDomains,但我的直觉表明这可能对我有用。
  3. 如果我使用一个VS2010实例用于前端,另一个用于模拟逻辑,有没有办法安排事情,以便在一个中启动代码将自动启动另一个中的代码?

我并不特别致力于任何单一的模拟方法;虽然可能很高兴知道是否有某些方法可以略微改善上述情况,但我也想知道任何其他可能更好的替代方法。

2 个答案:

答案 0 :(得分:1)

我认为您仍然需要运行16个主应用程序代码副本,但是基于TCP的I / O模拟器可以为每个进入的TCP连接保留一组不同的寄存器/状态。 / p>

而不是一堆全局变量,将它们放入包含单个设备的I / O状态的单个结构中。为每个套接字生成一个新线程,或者只保留一个活动套接字列表,并为每个套接字专用一个状态结构实例。

答案 1 :(得分:0)

我已经看到处理指令集/处理器的多个实例的模拟器就是这样设计的。通常有一个结构包含一组完整的寄存器,并使用新指针或这些结构的数组将它们乘以处理器的多个实例。