关于STM32 HAL的质量和性能

13

我即将开始一个基于经典STM32L4产品的新项目。 我对ARM开发有着丰富的经验,但对STM32并不熟悉。 我想知道STmicro提供的STM32 HAL和低级驱动程序(在STM32Cube软件包中)的质量和性能如何。 我想收集开发者在这个主题上的经验和反馈。 基本上,我想知道你们是否满意这段代码,或者相反地,如果你遇到了一些问题,是否有人为某些原因开发了自己的驱动程序等等... 谢谢!


3
供应商提供的库的质量通常是一般般的,你只需要自己查看代码(简单地浏览一下即可确定答案)。性能比较差,通常编写以覆盖多种芯片系列,非常臃肿,执行的代码中有一部分不适用于你的芯片,并且没有完全进行 if-then-else 判断。一般而言,不特指任何一个芯片供应商。 - old_timer
1
作为专业人士,你应该能够使用库或不使用库,选择下一个项目的路径时,你应该定期尝试每个供应商的解决方案以及仅阅读手册。你拥有所选择的代码库,你的老板不会在意因为你想节省时间而使用别人的代码而导致他们必须吃掉10,000个单位的损失,这是你的责任,你拥有它,你要审视并拥有这些库。 - old_timer
1
我发现直接阅读手册并编写寄存器比尝试让库正常工作更容易。有时候你必须深入他们的代码以找到手册中的错误,但是当你在那里时,你会发现你真的很高兴没有使用库...再次泛泛地说...ST文档相当不错,虽然不是最好的(非常接近),但绝对不是最差的。 - old_timer
4个回答

16

出于多种原因,我不喜欢HAL:

  1. 它会让伪开发人员产生一种错误的感觉,即他们无需知道其硬件是如何工作的。
  2. 学习HAL所需的时间可能比理解硬件工作方式所需的时间更长(通常如此)。
  3. 开销非常大。
  4. 存在许多错误。

但另一方面,我使用HAL(实际上是由我进行了深度修改),来控制两个外设USB和以太网。因为编写代码需要太多时间。但正如我之前所写的,我知道它如何在硬件/底层上工作,并对其进行了修改,以符合我的喜好。


是的,你说得对!像USB和以太网这样的外设太复杂了,无法从头开始编写驱动程序。但我真的不明白为什么有人要用HAL来控制GPIO、UART、SPI和其他简单的外设。如果使用自己的驱动程序,你就可以完全掌控外设。 - vlk
谢谢您的回答。您能详细说明第三点和第四点吗? - Guillaume Petitjean
1
关于第一点,这不正是 HAL 的一般目的吗? :) - Guillaume Petitjean
在编程中,为了创建抽象层,通常需要增加一些开销,而直接配置外设寄存器所需的代码量更少,速度也更快。 - vlk
经常情况下,为了理解使用HAL配置外设,你还需要研究外设的数据手册,而不仅仅是HAL文档。我的观点是这是无用的,最好直接访问简单的外设。 - vlk
显示剩余2条评论

11

在从小型8位微控制器转换到ARM后,我立即开始使用STM32上的HAL库,并获得了一个或多个令人满意的体验,但如前所述,它会带来一些额外开销,以及一些文档不足的功能,可能会导致某些混淆。

然而,使用HAL相比手写代码的一个重要优点是其提供的抽象层次。当我需要从一种类型的STM32切换到另一种类型时,这非常有用;同时也有助于快速启动。我在一些非常不同的STM32微控制器类型/系列(L0,L1,F1,F4,F7)上使用了相似的代码,它实际上大部分时间都能工作。使用HAL库使过渡变得比较容易,不像需要了解特定微控制器的确切内存映射和寄存器布局时那样痛苦...

话虽如此,我需要承认,当涉及到现代嵌入式软件时,我仍然是一名新手,并且在进行了大约2年的不同基于STM32的项目原型工作(业余和专业)后仍在学习。例如,我仍然需要了解更多关于提供的LL代码的内容。

通过以不同的软件背景进入嵌入式领域,使用HAL级别代码而不是在正确的顺序中操纵不同寄存器的单个位,并考虑所有不同的限制以使基本的UART / SPI / I2C通信工作,为我带来了很大的便利。在我看来,STM32 HAL处于纯手写代码和mbed(例如C++ /供应商无关抽象层)之间的中间地带。 - 它将复杂的东西变得可控,以便像我这样的普通软件开发人员可以处理它。这也带来了一些折衷,正如其他人所提到的那样...

毕竟,STM32 HAL还充当一种锅炉板代码库,有时比某些情况下的晦涩参考手册更易于阅读/理解。 - 使用STM32CubeMX生成的HAL代码总是使我在启动时间上更加顺利,当我需要快速测试新板时。它还可以帮助尝试和测试各种功能。当需要手动优化性能关键部分时,稍后仍然可以进行,例如在设置项目后甚至是增量调整STM32CubeMX代码时。您可以将手写代码与HAL代码混合使用。

自2016年以来,一些问题已被确认:

缺乏良好的文档(代码文件中的注释)和干净的示例代码(过于具体,且文档不完善)。

  • 复杂混乱的代码,有时效率较低。

  • 拼写错误。


  • 但需要注意的是,你将Hal与木棍和石头进行比较,当然Hal比没有好,但与假设的正常工作的硬件抽象层(如Rust所做的)相比仍然很差。 - Spyros Mourelatos

    6
    我个人不太喜欢HAL库,原因如下:
    1. 在我的控制器中占用大量内存,我真的没有足够的空间来容纳引导程序和应用程序,这里还需要添加两个HAL开销(一个在引导程序中,另一个在应用程序中)。
    2. 它在内部使用中断(我非常确定它会这样做)。
    3. 它并不是无错误的,我曾尝试过版本1.0,但遭遇了可怕的失败。
    4. 调试很痛苦,你永远不知道bug是出现在你的应用程序中还是出现在HAL中。

    我喜欢ST的标准外设库,它只是一个汇编到C的转换器,非常容易使用。


    #2 是不正确的。#3 有没有任何软件是没有 bug 的?你设定了一个很高的标准。#4 这是任何人代码的情况。 - Tarick Welling
    1
    @TarickWelling 你的应用程序可能容忍出现错误。但是在BSP中出现错误会让你在调试时感到非常不舒服。你只有一种方法可以使用你的外设,而且必须正确。 - Dheeraj Kumar
    @Tarick Welling 至少大多数软件都有最起码的良心,当出现漏洞时,他们会在关闭问题之前修补它。我曾经使用一个旧版本的hal和I2c协议工作得非常好的f1,但是当我更新到1.8版本时,Hal就崩溃了。我去他们的github上看看是否有人提出了这个问题。因为没有任何相关的开放问题,我很担心自己做错了什么。这些白痴为一个遇到同样问题的人制作了一个热修复程序,然后关闭了问题,好像什么都没发生一样。[证明] (https://github.com/STMicroelectronics/STM32CubeF1/issues/6) - Spyros Mourelatos
    1
    @DheerajKumar 我并不是说别人代码中的错误(特别是像BSP这样的核心代码)不会让人感到糟心和沮丧,但有错误是不可避免的事情。而且,我非常不同意外设只能以一种方式使用的概念。以DMA为例,它非常复杂,可以做很多事情,因此编程很困难。 - Tarick Welling
    @TarickWelling 我同意Tarick的观点,只是想说BSP中的错误成本比应用程序高得多。此外,外设有不同的配置,但某个用户可能希望以单一方式使用它,例如DMA,我可能更喜欢16位,而您可能更喜欢8位,这取决于程序的性质。我们都在用不同的方式表达同样的事情 :) - Dheeraj Kumar
    显示剩余2条评论

    0

    我喜欢HAL和Cube,但你必须阅读驱动程序并准备好承受痛苦。 我曾经像那些唱衰者一样摇晃位,你可以选择自己的毒药。 在我的情况下,如果我使用HAL,我可以骗一个真正的程序员来维护我的代码。不用再说了,我支持HAL。 请注意,Cube只是创建了一个大致可行的东西。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接