在嵌入式和非嵌入式代码之间维护单一代码库

Maintaining a single codebase between embedded and non-embedded code

我正在从事一个涉及微控制器编程的机器人研究项目。我希望能够最大程度地将软件测试与硬件测试分离开来。这既是为了提高开发速度,也是为了让我在将代码放到机器人上之前更容易地单元化 test/simulate 代码。因此,例如,我可能会编写一个 "MyRobot" 库。然后我可以将这个库包含在嵌入式代码和我的非嵌入式 simulation/testing 代码中。在运行时,我会提供函数指针来读取(在嵌入式情况下)或模拟(在模拟中)传感器数据并将其馈送到库中。

看来我需要做的就是在编译时生成两个库:一个用于嵌入式代码,一个用于非嵌入式代码。

我的问题是这是否 feasible/if 有更好的方法 it/if 有任何我应该注意的陷阱。

提前致谢!

考虑到你被 C 困住了,它不是一种面向对象的语言,我会去一个有一些内部逻辑的库,甚至 #ifdefs(如果性能是必须的),比如:

bool turnOn()
{
   #ifdef DEV
       printf ("Turned On\n");
       return true;
   #endif

   #ifdef PROD
      return robot_command_turnOn();
   #endif
}

bool turnOn()
{
   if (inProduction())
      return robot_command_turnOn();

   printf ("Turned On\n");
   return true;
}

甚至更好:

bool turnOn()
{
   printf ("Turned On\n");

   if (!inProduction())
        return true;

  return robot_command_turnOn();
}

有几种方法可以做到这一点。在我看来,我不会选择两个库,因为我需要保持同步函数签名和版本,这可能会很麻烦。

秘诀是为您的硬件(以防机器人)构建一个 接口库 并开发包含所有可能交互的库,以便保持硬件的抽象级别层。该接口库可以控制您是否正在测试该单元(使用上面 inProduction() 之类的函数)并在允许的情况下将命令发送到硬件。

使用像 C++ 这样的面向对象的语言,您可以使用模式来帮助您:即:接口模式工厂模式 等。

这是嵌入式系统开发中的常见情况,您创建两个库的方法通常是推荐的解决方案。将低级硬件与嵌入式系统固件中的软件分离被认为是最佳实践。

您提到的库通常称为 "Hardware Abstraction Layer" 或 HAL。 HAL 的 API(应用程序编程接口)可以在一个名为 hal.h 的头文件中提供。软件中需要访问硬件的每个源模块都将在源文件顶部包含以下行:

#include "hal.h"

像这样设计系统的好处包括:

  • 模块化。如果您需要更改时序,例如读取传感器的 UART 或 SPI 接口,您只需更改 HAL 库,即使您的代码中可能有多个位置读取该传感器。
  • 便携性。如果您以后需要将您的项目迁移到不同的微控制器,只需更改 HAL 层。
  • 封装。硬件的细节隐藏在 HAL 层中,这允许您的其他软件在更高的抽象级别上运行。如果您使用的是微控制器制造商提供的提供寄存器地址、I/O 端口等的设备库,您可以将对该库的引用封装在您的 HAL 库中,这样您的应用程序代码就不需要对它的了解。
  • 可测试性。这是您问题的主要焦点。您可以在不同的平台(例如Windows)上编写一个可以运行的特殊版本的HAL层来测试您的应用软件。这个特殊版本不需要包含微控制器制造商提供的设备库,因为当你在测试环境中 运行ning 时,微控制器不存在,所以它的寄存器和 I/O 端口不存在不需要被您的软件访问。

对于您的两种情况,正如您所建议的,您将创建两个版本的 HAL 库:包含嵌入式硬件上 运行 代码的标准版本,以及模拟硬件,用于以受控方式测试您的软件。您可以将标准库命名为 hal.lib(可能根据您的开发环境使用不同的扩展名),并将模拟库命名为 hal_simulated.lib。两者将具有相同的界面,如 hal.h 中所述。也就是说,两个库都将包含 hal.h 中声明的所有函数,例如 void halInit()int halReadProximitySensor()

假设您的 IDE 支持 ReleaseDebug 配置,您可以为名为 SW_Test 的软件测试创建第三个配置。此配置将与您的 Debug 配置重复,除了 hal_simulated.lib 将链接到项目而不是标准 hal.lib.

另见

Hardware Abstraction (Wikipedia)