STM32 HAL 是不是应该作为预编译库包含在内

Posted

技术标签:

【中文标题】STM32 HAL 是不是应该作为预编译库包含在内【英文标题】:Should the STM32 HAL be included as a precompiled librarySTM32 HAL 是否应该作为预编译库包含在内 【发布时间】:2019-11-14 23:36:33 【问题描述】:

我有一个用于 STM32L0 的 Keil STM32 项目。我有时(比我想要的更多)必须更改包含路径或全局定义。这将触发对所有代码的完全重新编译,因为它需要“检查”由于这些更改而发生的更改行为。问题是:我不一定要更改 HAL 的相关参数,因此(据我所知)不需要完全重新编译这些文件。这次重新编译需要相当多的时间,因为我包含了我的 STM32L0 的所有 HAL 驱动程序。

创建一个单独的项目,将 HAL 编译为单个库并将其包含在我的主项目中,这是一个好的做法吗? (这当然会针对每个微控制器单独完成,因为它们具有不同的 HAL)。

ps。该问题不一定只对这个特定示例有用,但该示例为该问题提供了一些范围。

pps。对于不熟悉 STM32 HAL 的人。它是程序与底层硬件接口的标准化接口。它在.c.h 文件中提供,而不是在STD/STL 的预编译形式中提供。

更新

以下是我的示例项目中需要管理的定义示例:

STM32L072xx,USE_B_BOARD,USE_HAL_DRIVER, REGION_EU868,DEBUG,TRACE

只有STM32L072xxDEBUG 可用于配置HAL 库,因此当我将TRACE 从已定义更改为未定义时,我不需要重新编译HAL。因此,在我看来,HAL 可以单独管理。

编辑

看到投票结果很接近:我已阅读 don't ask section,我的问题旨在建设性地增加构建 STM32 程序的知识,并找到有关如何更有效地使用 HAL 库的最佳实践。我没有发现任何关于将 HAL 构建为静态库的问题,因此这个问题至少可以说是独一无二的。这个问题也旨在邀请一个丰富的答案,详细说明将 HAL 构建为单独的静态库的利弊。

【问题讨论】:

这是个糟糕的主意。您可以根据自己的喜好创建项目,但您很快就会放弃。 @P__J__ 您能否详细说明该答案(您已将其放入 cmets)?因为这只是一个没有引用的声明,因此对***的知识没有贡献。 正如我告诉你的 - 你可以根据自己的喜好创建一个项目。 IMO 这是一个错误的想法,因为 HAL 驱动程序取决于许多定义。当您更改项目设置时,明智的做法是重建整个 项目。但这取决于你。顺便说一句,您的问题不是关于仅编程的项目组织,它是 100% 基于意见的 - IMO 它是这里的主题 【参考方案1】:

这里的答案是.. 这取决于。正如 cmets 中已经指出的,这取决于您计划如何管理您的项目。以公正的方式回答您的问题:

选项 #1 - 直接在您的项目中使用 HAL 源意味着每次在其(和底层)标头中的任何内容发生更改时都重新构建 HAL,您已经注意到了这一点。它的缺点是构建时间更长。好处 - 你确信你所建造的就是你所得到的。

选项 #2 - 将 HAL 作为预编译的静态库。好处 - 更短的构建时间,坏处 - 您不能再绝对确定您包含的 HAL 库实际上可以按照您的意愿工作。特别是,您需要以某种方式确保所有#defines 与构建库时完全相同。这包括项目范围的定义(DEBUGSTM32L072xx 等),以及 HAL 配置文件中的任何内容(stm32l0xx_hal_conf.h)。

看看您是如何成为 Keil 用户的 - 也许这只是启用多核构建的问题?请参阅此链接:http://www.keil.com/support/man/docs/armcc/armcc_chr1359124201769.htm。 HAL 库并没有那么大,以至于在重建其源文件时应该考虑构建时间。

如果我要表达我的观点和经验 - 就我个人而言,我不会这样做,因为这可能会导致可靠性降低或副作用难以诊断,并且只会随着您添加更多源文件和更多这样的图书馆。更不用说增加更多的人来处理项目并向他们解释他们“在更改给定的头文件集或项目范围的定义时需要记住重建 X 库”。

事实上,对于我工作的代码库,我们也遇到了同样的困境 - 它总共跨越 10k 多个源文件和头文件,其中一些是特定于配置的,其中许多是共享的。它是高度模块化的,允许我们通过配置现有代码(主要是通过一组头文件)快速创建新的东西(硬件和软件方面)。但是,由于此配置是通过标头完成的,因此对其进行更改通常意味着重建项目的大部分。尽管有时构建时间很烦人,但出于上述原因,我们选择不制作静态库。就我个人而言,最好优先考虑可靠性,例如“我知道我在构建什么”。

如果我要提供任何有助于避免在您的项目变大时重建的一般提示:

避免包含所有配置的全局标头。将所有配置集中在一个地方,为这个文件中的每个软件模块创建漂亮的 cmets 和部分通常很诱人。这种方式更容易管理(直到这个文件变得太大),但是由于这个文件很常见,这意味着对其进行的任何更改都会导致完全重建。将此类文件拆分为与项目中每个模块对应的单独标题。

仅在需要的地方包含头文件。我有时会看到一种方法,其中创建的头文件仅“捆绑”其他头文件,并且稍后包含此类头文件。在这种情况下,对这些“较小”的头文件中的任何一个进行更改都会导致必须重新编译所有源文件,包括较大的文件。如果这样的文件不存在,那么只有明确包含该小标题的源代码才需要重新编译。显然这里要画一条线——包括太“低级”的标题也可能不是最好的主意,例如它们可能不应该作为可能随时更改的内部库文件包含在内。

在源文件中包含头文件的优先级高于头文件。如果您有一对自己的 *.c (*.cpp) 和 *.h 文件 - 假设 temp_logger.c/.h 并且您需要 ADC - 那么除非您确实需要在标题中定义一些 ADC(您可能不会),然后将 ADC 头文件包含在您的 temp_logger.c 文件中。稍后,所有使用 temp_logger 函数的文件都不必重新编译,以防 HAL 再次重建。

【讨论】:

很好的答案!我确实知道多核编译,但只是在徘徊,更有经验的人可能会说关于这个“问题”以及利弊是什么。【参考方案2】:

我的意见是肯定的,将 HAL 构建为库。更快的构建时间的好处超过了库过时的风险。在项目早期的某个时间点之后,我很少更改会影响 HAL 的内容。但更快的构建时间带来了很多倍的回报。

我创建了一个多项目工作区,其中一个项目用于 HAL 库,另一个项目用于引导加载程序,第三个项目用于应用程序。当我在开发时,我只重建应用程序项目。当我进行发布构建时,我选择 Project->Batch Build 并重新构建所有三个项目。这样,发布版本始终使用所有最新的代码和构建设置。

此外,在“目标选项”对话框的“输出”选项卡上,取消选中“浏览信息”将大大减少构建时间。

【讨论】:

以上是关于STM32 HAL 是不是应该作为预编译库包含在内的主要内容,如果未能解决你的问题,请参考以下文章

STM32F4 HAL库开发 -- 独立看门狗(IWDG)

STM32F4 HAL库开发 -- 独立看门狗(IWDG)

STM32F4 HAL库开发 -- 独立看门狗(IWDG)

STM32F4 HAL库开发 -- 独立看门狗(IWDG)

STM32F4 HAL库开发 -- 独立看门狗(IWDG)

STM32-HAL库-TIMx学习