深入理解STM32 HAL库(***)

注:本文的理解,可能是错误的?还是正确的?

两种库函数的对比

标准库(外设)函数:

摘录:STM32标准库:IO接口的操作  https://blog.csdn.net/qq_35827943/article/details/134232143

GPIO_WriteBit(GPIOx,GPIO_Pin,Bitval);
//GPIOx用于选择GPIO外设,可以是GPIOA,GPIOB…
//GPIO_Pin为对应的GPIO管脚,可以形如GPIO_Pin_x(x可以是0-15)
//Bitval为待写入的值,为BIT_SET(相当于1),BIT_RESET(相当于0),为了方便可以直接用(BitAction)(1)或者(BitAction)(0)

HAL 库函数:

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);

什么是 HAL ? 什么是 HAL库?

1. HAL 是Hardware Abstraction Layer的缩写,中文名称是:硬件抽象层。

这是一种设计模式、或编程技术,也是一种源码的组织方法

2. HAL库 是 st公司为了更方便地进行stm32之间的移植而开发的库,通用性很强,在不同的两款stm32芯片之间的移植基本上不需要修改。

3. ST 的标准库和 HAL 库,与 linux OS 的 stdio.h 库,它们在封装形式上,有本质上的区别吗?

3.1. 它们都是将复杂的硬件设置封装在函数的内部了,因此,在本质上,它们都属于 HAL库,即硬件抽象层库。因此说,在封装形式上,它们没有本质上的区别。

3.2. ST 的标准库与 HAL库,实质上,都是一种对硬件进行抽象的函数库。也就是说,单纯从概念上来理解,STM:HAL库,当然应该包含标准库了。

“标准库” 算不算是 “HAL”(硬件抽象层)呢?

用户 app层 ============================

API (直接/间接:硬件驱动)驱动层 ======== 第二级抽象

[ <<<<<<<< ====== LL库 ================ 第一级抽象 ]

硬件层 ===============================

   

说明:

1. “标准库”是对硬件的抽象,所以当然属于“HA”硬件抽象。

2. “层”这个概念,是相对的。相对于用户层、或硬件层而言,“标准库”驱动函数,当然具备了“层”的意思,算是“驱动层”吧?

3. 当在 API 驱动层与硬件层之间,如果再插入一层时,相对于用户层来说,它们都属于“抽象层”。

只不过不同的层,它们抽象的分层的对象、或依据有所不同而已。
但是,从总体上、从宏观的角度上来看,在用户层与硬件层之间,不管这中间插入有多少层,只要它们是为了抽象硬件为目的的,那么,相对于用户层,都可以笼统地视为就是“硬件抽象层”吧?

4. 为什么会这样?

可能是翻译问题,待有时间,再去看看英文原版。

也可能就是英文原版的概念定义存在问题?

标准库 与 HAL库,从概念定义的角度而言,容易让人产生误解

单纯从概念的角度而言,“标准库”与“HAL库”,在概念的外延上,是子集与全集的关系。

不良的概念定义方法,很容易造成人们的误解

大家思考一下:

  •  “HAL库”是“标准库”吗?No. 是吧?
  •  “标准库”是“HAL库”吗?同样是 No. 是吧?
  • 从实现硬件抽象这种功能上来看:实质上,“标准库”是“HAL库”的一个子集。假如将“标准库”理解为“公猪”,那么,“HAL库”就是“猪”了。问题是:

  • “猪”是“公猪”吗?==  “HAL库”是“标准库”吗?No. 是吧?
  • “公猪”是“猪”吗?==  “标准库”是“HAL库”吗?假如也是 No.!那么,“公猪”真的不是“猪”吗?
  • 在逻辑推理中,若 A属于 B,则 A是 B。
    “标准库”属于一种“HAL库”吗?或者说,“标准库”属于一种硬件抽象层库”吗?

    综上所述:ST 中文译本的这种概念定义方法,很容易让人误解,从而得出一个的伟大结论,那恐怕就是?猪”不是“公猪”同样的,“公猪”也不是“猪”!!!!!!Very Good!

    这样的概念定义方法,是容易造成误解的,以为“标准库”不属于采用“HAL”方式进行封装的库。这会让初学者一头雾水,

    Why,一种纠正方法?

    CMX库:与 CubeMX一起配合使用的硬件抽象层函数库。而不应该直接定义为“HAL库”。

    这样,“标准(外设)库”与 CMX库,都属于 HAL库,这样理解,就可以理顺思维了吧?

    公猪和母猪,都是猪。

    STM:标准库 与 HAL库的本质区别

    1. 标准库:全称为“标准外设库”,它只是对 ST MCU的标准外设进行了封装。需要用户手工配置工程。

    2. HAL库:除了包含标准库的功能,也就是对标准外设的配置进行了封装之外;还集成了对 RTOS、GUI图形库,以及其他各种有有用的算法库等等。

    3. HAL库,可以与 cubeMX配合使用的,从而可以自动生成基础代码,避免手工配置工程。这样做有更多的好处,比如:省时省力。

    4. 在切换不同的ST MCU芯片时, cubeMX的使用,可使得切换不同的 MCU芯片,就像玩游戏一样简单。

    相比标准库,HAL库的函数名称,为什么会显得比较怪异呢?

    从 M1—M3—M4—-M7—-,Arm 内核功能不断增强,使得原来 Arm只是用来做简单的 MCU用途,到现在足以媲美早期、近期的计算机性能,这就使得了现在的 Arm CPU可以运行更加复杂的程序了。比如:复杂的 GUI,RTOS,Linux OS等等。

    由于历史问题,简短、醒目的库函数名称,已经被标准库所占用了。
    如果库函数继续采用标准库中的命名的话,那么,就会在客户端造成混乱,甚至在原厂端也会造成混乱。标准库也不可能说淘汰就淘汰,因为旧的 MCU产品,有些还是很长命的。

    HAL库的函数名称,不是最佳的,但也不是最差的

    最佳的已经被标准库占用了。

    也许用户可以给 HAL库函数取一个更加简洁的、容易理解的名字。但是,这存在问题:

  • 不通用,难以形成企业、或跨企业的规范。这是 ST所不希望看到的;CMSIS这是ARM希望看到的。
  • 无法与 cubeMX配合使用。
  • HAL库的名称太长了,难看,习惯成自然吧?
  • 因此,尽管 HAL库函数的名称比较长,不尽人意。不过,由于软件最终是写入 MCU中,对多大多数最终产品的卖点,不会产生任何的影响,因此,这又有什么所谓呢?

    要知道,假如要自己来给库函数命名的话,在一个公司里,不同的程序员的命名风格,肯定是有所不同的,最后就变成了库函数的名称,眼花缭乱。

    HAL库只是一种函数库而已,这意味着:

  • 只要是函数库,它不可能无所不包。<< 可能用户还需要自己增加所需的函数。
  • 只要是函数库,它不可能无所不能。<< 可能用户还需要自己增加、或修改所需的函数。
  • 函数库,只要是人写的,就不可能没有 Bug。<< 可能用户还需要自己修改 Bug。
  • 注:无所不包与无所不能,还是有区别的。
    比如,虽然包含了某个库函数,但是,由于这个库函数的精度太粗糙了,无法达到用户的要求,因而,用户需要重写这个函数;甚至需要更换 MCU、或其他的外围硬件。

    ARM CMSIS 与 STM HAL 库的函数命名规则,都属于企业性质的规范

    遵守这些规范,则可使得大家的交流,障碍会少很多,而不是到处都是不同的方言。

    ARM CMSIS:主要是给芯片商和编译器厂家遵循的,当然用户在用到内核级编程时也会需要。

    STM HAL 库的函数命名规则:主要是给 STM 社区的企业规范。

    对于 arm 的其他 MCU厂家,如 STM的竞争对手来说,一般有其他厂家的规范。

    除非有特别情况的发生,比如做到完全兼容;但是,想要做到完全兼容的话,代价可能会很大,因为这会存在专利问题,技术问题,成本问题等等。

    在有些应用场景里,采用寄存器编程,可以得到速度快的好处

    比如:

    在 TFT LCD显示场景:

    正点原子在 LCD驱动的课程里,实验测试得到的效果。在同等条件下,寄存器编程的显示速度明显优于 HAL库编程。

    甚至,在有些应用场景里,某些代码块,还可能需要采用汇编编程,才能满足在速度上,以及其他方面的一些特别的需求。

    在电机控制场景:

    HAL 库函数不一定能够及时反应、或及时控制电机的变化,需要采用寄存器,甚至是汇编语言来编程。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 深入理解STM32 HAL库(***)

    发表评论