【问题标题】:Simulating multiple instances of an embedded processor模拟嵌入式处理器的多个实例
【发布时间】:2012-02-07 01:35:37
【问题描述】:

我正在开展一个项目,该项目需要多个设备进行通信,每个设备都带有嵌入式 (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;` 将向 TCP 端口发送“读取端口 0xF89”命令,获取响应,处理接收到的值,然后发送带有结果的“写入端口 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 实例用于前端,另一个用于模拟逻辑,有没有办法安排事情,以便一个启动代码会自动启动另一个代码?

我并不特别致力于任何单一的模拟方法;虽然很高兴知道是否有某种方法可以稍微改进上述内容,但我也想知道任何其他可以更好地工作的替代方法。

【问题讨论】:

  • 这里的问题是什么? SO 是一个问答网站,而不是“请讨论”网站,您必须缩小您的问题范围。
  • @LasseV.Karlsen:我添加了一些更明确的问题。抱歉,如果我在一个 SO 问题页面中问了太多问题,但我真的不知道哪些问题会得到最有用的回答;如果有一个好的方法,例如使用 appdomains 解决我的问题,这将减少我知道如何从同一个 VS2010 实例中的同一个源文件创建一个 DLL 的多个副本。

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


【解决方案1】:

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

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

【讨论】:

  • 有什么好的方法可以运行 16 个主应用程序代码副本并能够与它们一起使用调试器吗?我能想到的唯一方法是让每个应用程序实例成为 C++ 类的实例,但这似乎有点棘手。
【解决方案2】:

我见过的处理多个指令集/处理器实例的模拟器就是这样设计的。有一种结构通常包含一整套寄存器,并且这些结构的新指针或数组用于将它们相乘成处理器的多个实例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-05
    • 2011-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    相关资源
    最近更新 更多