在尝试提高我的嵌入式软件技能(在过程 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 方法已发展为以下内容:
adc_driver_api_t
、uart_driver_api_t
、i2c_driver_api_t
等)。这些 API 不使用任何芯片/编译器扩展或包含,但通常遵循语言标准 (C89/C99)。 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;
.这些实现使用芯片/编译器扩展或根据需要包含。 const adc_driver_api_t *
进行初始化实现和 API 所需的任何其他内容(可能是 adc channel )。组件和 ADC 驱动程序实现都将在程序初始化中被初始化并连接在一起,例如main()
的顶部msp430_adc12_driver_set_result_alignment()
可以在系统初始化期间调用。 我发现这种方法允许以独立于硬件的方式在 HAL 之上构建组件,因此我可以轻松地在不同平台上重用组件。它还允许编写、调试组件并对组件进行脱靶单元测试,并为 HAL 提供测试替身。
关于c - 如何构建嵌入式软件的源代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31565858/