c - 如何构建嵌入式软件的源代码

标签 c embedded software-design

在尝试提高我的嵌入式软件技能(在过程 C 中,使用 C++11 特性)时,我想了解为嵌入式系统构建/打包源代码的最佳方法。

我正在构建没有 RTOS 的小型系统(在具有 1-k4k RAM 内存的单个微 Controller 上)。为了能够在目标环境之外调试我的软件,我想在我的主机上模拟我的系统。

我发现在 board support package 中存储有关处理器及其内部设备(RAM、ROM、计时器等)的信息是标准的。 .

但在我的嵌入式项目中,我还使用了其他外部设备(按钮、LED、LCD、伺服器、IO 多路复用器等),它们使用 PCB 连接到微 Controller 。特定应用 PCB 上的源代码抽象层的标准方式/标准名称是什么?

我搜索了有关实时系统工程的书籍(David Simon 的 An Embedded Software Primer、Jim Cooling 的实时系统软件工程和 LaPlante 的实时系统:设计和分析),但找不到很好的代码引用嵌入式系统中的结构化。

最佳答案

根据wikipedia entry for BSP ,其目的是提供特定操作系统所需的板卡支持(不仅仅是微)。因此,对于相同的硬件,不同的操作系统可能需要不同的 BSP,所以我认为这不是您所追求的术语。

您所描述的就是我所说的硬件抽象层/HAL,我相信这是一个很常见的名称。原则上,这个名称可以包括整个 PCB,也可以只包括 MCU。

HAL 中的重要部分是抽象。一个好的抽象将使其易于替换,例如如果您想测试基于 HAL 脱靶构建的代码。它还将使将该代码移植到不同的硬件平台变得更加容易。

我发现许多供应商提供的库在这方面存在不足:您可以调用函数而不是直接修改或读取寄存器,但函数调用通常直接对应于寄存器。也就是说,他们的库可能隐藏在与芯片接口(interface)所需的编译器扩展的抽象后面,但仅此而已。因此,我倾向于不将供应商提供的库用作 HAL,但可能会使用它来实现一个(或者直接访问寄存器)

HAL 的最佳结构取决于您的设计目标。您已经声明了能够脱靶调试应用程序的一个目标。您还表示您不打算运行操作系统。您可能计划支持单个 MCU 或 MCU 系列,或来自不同供应商的多个 MCU。您可能正在计划一个单板设计,或基于一个通用平台的多个定制板。这些都会影响 HAL 设计中的设计选择。

我经常从事不使用 RTOS 的项目。通常,硬件继承了一个或多个旧设计的某些方面,并具有一些新的东西。新的东西可以是小的或大的变化(包括不同的 MCU 或 MCU 系列)。

在这种情况下,我的 HAL 方法已发展为以下内容:

  • 为 HAL 中的每个组件定义一个 API(通常是指向函数的结构,例如 adc_driver_api_tuart_driver_api_ti2c_driver_api_t 等)。这些 API 不使用任何芯片/编译器扩展或包含,但通常遵循语言标准 (C89/C99)。
  • 给定平台的 HAL 为这些提供了实现,例如msp430_adc12_driver , msp430_adc10_driver , pic18_adc12_driver , avr_adc_driver等都实现了adc_driver_api_t接口(interface)使用各自平台上可用的不同外设。每个实现都会在实现头文件中公开一个已实现驱动程序的 const 全局实例,例如(使用 C)extern const adc_driver_api_t msp430_adc12_driver; .这些实现使用芯片/编译器扩展或根据需要包含。
  • 使用 HAL 获取 ADC 读数的组件将使用 const adc_driver_api_t * 进行初始化实现和 API 所需的任何其他内容(可能是 adc channel )。组件和 ADC 驱动程序实现都将在程序初始化中被初始化并连接在一起,例如main() 的顶部
  • 我尝试保持 HAL API 精简。例如,某些外设可能允许您将 12 位结果放在 16 位寄存器的高 12 位或低 12 位。我不允许通过 HAL API 进行配置,但可能会提供一个函数来直接在实现 HAL API 的模块中进行设置,因此在 msp430_adc12_driver.h 中可能有一个函数 msp430_adc12_driver_set_result_alignment()可以在系统初始化期间调用。

  • 我发现这种方法允许以独立于硬件的方式在 HAL 之上构建组件,因此我可以轻松地在不同平台上重用组件。它还允许编写、调试组件并对组件进行脱靶单元测试,并为 HAL 提供测试替身。

    关于c - 如何构建嵌入式软件的源代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31565858/

    相关文章:

    c - 解锁然后立即锁定互斥锁/信号量。不好的做法还是有办法做到这一点?

    c - 与 LPC1786 的串行通信

    java - 如何重构只将请求转发给DAO的服务方法?

    java - 跟踪 Java Swing 应用程序中未保存的更改

    c++ - 重定向和调用 fopen() 后没有串行输出

    java - API 的传统包结构

    将基数 20 转换为 int

    c - 如何用C关闭GTK窗口

    c++ - Windows (Visual C) 是否有 unistd.h 的替代品?

    embedded - 用于嵌入式系统的 PCI Express 驱动程序