CMSIS vs HAL vs 标准外设库

电器工程 手臂 stm32 stm32f4 cmsis
2022-01-17 05:49:05

所以我从 PIC 切换到 ARM,我买了一个 STM32F4 发现板。到目前为止,我知道要对其进行编程,您可以直接访问内存中的所有寄存器(显而易见的方式),并且您可以使用 3 个主要库来让您的生活更轻松。现在我的问题是,这 3 个(CMSIS、HAL、Std Peripherals Lib)中的哪一个是最低级别的?IE。开销较小的那个。我的目标是了解控制器的内部工作原理,而不是让我的生活更轻松(只是一点点),所以我想知道其中哪些更接近核心,而无需使用汇编。

4个回答

绝对是CMSIS。它不完全是一个库,它主要包含各种寄存器的定义。

这正是一个人需要轻松访问微控制器的寄存器,以实现他/她自己的 HAL。它没有开销,因为您只需访问寄存器。

请记住,与其他两个不同,CMSIS 是由 ARM 而不是 ST 定义的。这意味着用于各种微控制器的各种 CMSIS 库非常相似,这极大地有助于便携性。

此外,CMSIS 更简单,因此(IMO)它是最通用、最可靠的,可能有更少(或没有)错误。我使用过的各种 mcu 的一些 hal 库因其错误而臭名昭著。

另一方面,CMSIS 需要你做更多的工作。然而,这是我个人的选择,因为我更愿意花时间创建符合我需求的高质量库,并了解芯片的工作原理,而不是仅仅花时间学习另一个新库。

要了解它是如何工作的,您不想使用上述任何一种。从 st 获取 arm 交叉编译器和文档,完成。开始编码。这些芯片通常很容易编程。该文档告诉您哪些寄存器中的哪些位做什么。

任何/所有这些库都旨在消除您的理解/负担/工作,并使其感觉就像只是调用 API 一样的应用程序编程体验。这是很多人想要的。您可以使用这些库的所有源代码来帮助理解,但随着您的进步,您会发现库中的漏洞和问题,有时是非常可怕的代码。代码拼凑在一起,一般地编写,大致从一个芯片移植到另一个芯片,也许支持您的芯片没有的功能等。而且它们都有过多的开销。10 到 100 倍于任务的代码,当然很多代码可能会优化掉,但为什么一开始就存在呢?

无论您是自己使用还是使用其中一个库,您仍然应该查看您使用的库的源代码,看看您是否对它们正在做的事情感到满意,是否有意义,是否与芯片文档匹配等。出错了,您可能不得不像您一样深入研究他们的东西才能找出原因。

请注意,芯片文档也不完美,这是乐趣的一部分。

我不明白为什么在关于裸机编程的讨论中会出现汇编。您只需很少的组装就可以过关。对于这些 cortex-m 芯片,从技术上讲,您只需要这么多的 asm 即可启动:

.globl _start
_start:
.word 0x20001000
.word main

您不能依赖数据或 bss,也不能以最少的 asm 从 main 返回。但这就是最简单的裸机所需的所有组件。现在,如果您想进行中断,则需要向量表中的更多条目。更多.word 行。我推荐更多 asm,但可能多 10 或 20 行。

这通常是我使用的所有 asm。

.cpu cortex-m0
.thumb
.thumb_func
.global _start
_start:
stacktop: .word 0x20001000
.word reset
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.thumb_func
reset:
    bl notmain
    b hang
.thumb_func
hang:   b .
.align
.thumb_func
.globl PUT16
PUT16:
    strh r1,[r0]
    bx lr
.thumb_func
.globl PUT32
PUT32:
    str r1,[r0]
    bx lr
.thumb_func
.globl GET32
GET32:
    ldr r0,[r0]
    bx lr
.thumb_func
.globl GET16
GET16:
    ldrh r0,[r0]
    bx lr
.thumb_func
.globl dummy
dummy:
    bx lr
.end

是的,它说 cortex-m0 但这是我的 m4 代码的实际引导程序。我更喜欢这是拇指而不是拇指 2。我只是将这段代码从一个 cortex-m 重用到另一个,根据需要更改堆栈指针地址,因此它适用于 m0、m3 和 m4。我还没有m7,也没有研究太多。

启用 fpu 可能需要更多的 asm 行,因为需要特定的指令。但关键是不要混淆低级编程和asm。C 具有配置芯片以及编写应用程序所需的内容。您正在谈论的库是用 C 而不是 asm 编写的,因此显然它们也不需要使用 asm。

如果您想了解内部工作原理,请编写自己的代码。除了作为参考之外,不要使用这些库。有时,仅仅破解它比尝试通读他们的代码更容易。(不仅是 ST,还有所有的供应商。其中一个供应商有一行代码非常惊人,我用它作为面试问题,不打算在这里发布)。

ST 肯定,但其他供应商也一样,为了省电,芯片的各个部分都有时钟启用,所以在你进入并尝试闪烁 LED 之前,你需要找到那个 gpio 块的启用位,看看它是否出来启用重置,如果没有启用它,则在没有时钟启用的情况下与该 gpio 逻辑通信,它只是挂起处理器,因为它正在等待来自永远不会响应的逻辑的响应。他们并不总是告诉你这些使能。一旦启用,他们有时会引导您完成某些特定外围设备的初始化。ST 文档非常好。来自微芯片,它的文档成绩很差,你不应该有问题。

到目前为止,我一直使用 CMSIS 定义并喜欢直接使用寄存器。同时,我在几个项目中使用了 HAL 库。它对代码运行时间有相当大的影响,所以我退出了它。尽管 CMSIS 符合我的兴趣,但这些天我将成为libopencm3的粉丝。它就像LLST 提供的库。然而,它涵盖了更多的微控制器,即使在 ST 系列中:

libopencm3 项目(以前称为 libopenstm32)旨在为各种 ARM Cortex-M3 微控制器创建一个免费/libre/开源固件库,包括 ST STM32、东芝 TX03、Atmel SAM3U、NXP LPC1000 等。

请注意:

尽管名称如此,libopencm3 也支持其他 ARM Cortex“相关”微控制器,例如 Cortex-M0 或 Cortex-M4/Cortex-M4F 微控制器。

您可以在此处找到支持的微控制器列表

我都使用了,只是裸机寄存器访问和 std 外围库。我发现处理寄存器更容易。此外,如果您使用的是调试器,您可以查看寄存器并确认它们包含您将它们编程为的内容。我认为您也确实以这种方式了解了更多有关芯片操作的信息。