HAL庫(kù)的框架結(jié)構(gòu)
1 初始HAL庫(kù)
1.1 CMSIS簡(jiǎn)介
基于Cortex系列芯片采用的內(nèi)核都是相同的,區(qū)別主要為核外的片上外設(shè)的差異,這些差異卻導(dǎo)致軟件在同內(nèi)核,不同外設(shè)的芯片上移植困難。為了解決不同的芯片廠商生產(chǎn)的Cortex微控制器軟件 的兼容性問(wèn)題,ARM與芯片廠商建立了CMSIS標(biāo)準(zhǔn)(Cortex MicroController Software Interface Standard)。
Cortex微控制器軟件接口標(biāo)準(zhǔn)(Cortex Microcontroller Software Interface Standard)是ARM和一些編譯器廠家以及半導(dǎo)體廠家共同遵循的一套標(biāo)準(zhǔn),是由ARM提出,專(zhuān)門(mén)針對(duì)CORTEX-M系列的標(biāo)準(zhǔn)。在該標(biāo)準(zhǔn)的約定下,ARM和芯片廠商會(huì)提供一些通用的API接口來(lái)訪問(wèn)CORTEX內(nèi)核以及一些專(zhuān)用外設(shè),以減少更換芯片以及開(kāi)發(fā)工具等移植工作所帶來(lái)的金錢(qián)以及時(shí)間上的消耗。
以下是ARM官網(wǎng)關(guān)于CMSIS的架構(gòu)圖

可見(jiàn),CMSIS層位于硬件層與操作系統(tǒng)或用戶(hù)層之間,提供了與芯片生產(chǎn)商無(wú)關(guān)的硬件抽象層,可以為接口外設(shè)、實(shí)時(shí)操作系統(tǒng)提供簡(jiǎn)單的處理器軟件接口,屏蔽了硬件差異,這對(duì)軟件的移植是有極大的好處的。STM32的庫(kù),就是按照CMSIS標(biāo)準(zhǔn)建立的。
1.2 HAL庫(kù)簡(jiǎn)介
ST 為了方便用戶(hù)開(kāi)發(fā) STM32芯片開(kāi)發(fā)提供了三種庫(kù):
- 標(biāo)準(zhǔn)外設(shè)庫(kù) :Standard Peripheral Libraries F0/F1/F3/F2/F4/L1目前已停止維護(hù)。
- HAL庫(kù):Hardware Abstraction Layer 全系列兼容,ST目前主推的庫(kù),具有強(qiáng)兼容性、易移植性,但效率較低。
- LL庫(kù):Low Layer 全系列兼容,與HAL庫(kù)捆綁發(fā)布,輕量級(jí)、效率高,但不匹配部分復(fù)雜外設(shè)。
三種庫(kù)比較:
1.3 MCU固件包
STM32微控制器各個(gè)產(chǎn)品系列都有獨(dú)立的MCU固件包,HAL庫(kù)屬于MCU固件包的一部分。

MCU固件包文件結(jié)構(gòu):

- Drivers:文件夾下是官方的CMSISI庫(kù),HAL庫(kù),板載外設(shè)驅(qū)動(dòng)。

- CMSIS:由ARM公司提供的Cortex微控制器軟件接口標(biāo)準(zhǔn),包括Cortex內(nèi)核寄存器定義、啟動(dòng)文件等。
- STM32F1xx_HAL_Driver:STM32微控制器片內(nèi)外設(shè)的HAL庫(kù)驅(qū)動(dòng)文件stm32f1xx_hal_ppp.h,stm32f1xx_hal_ppp.c。
- BSP:基于HAL庫(kù)開(kāi)發(fā)的官方開(kāi)發(fā)板的板級(jí)支持包,提供指示燈、按鍵等外圍電路的驅(qū)動(dòng)程序,用于適配ST官方的開(kāi)發(fā)板(可參考)。
- Middleware:中間件,包含ST官方的STemWin、 STM32_Audio、STM32_USB_Device_Library、STM32_USB_Host_Library;也有第三方的fatfs文件系統(tǒng)等等。


- Projects:文件夾下是用驅(qū)動(dòng)庫(kù)寫(xiě)的針對(duì)官方發(fā)行demo板的例子和工程模板。

- Templates:各集成開(kāi)發(fā)環(huán)境的工程模板。
- Examples:針對(duì)MCU片內(nèi)外設(shè)的簡(jiǎn)單例程,如GPIO、UART等。
- Applications:針對(duì)單個(gè)中間件的應(yīng)用例程。
- Demonstations:針對(duì)多個(gè)中間件的綜合應(yīng)用例程。
- Utilities:實(shí)用的公用組件比如LCD_LOG實(shí)用液晶打印調(diào)試信息。
1.4 HAL庫(kù)框架結(jié)構(gòu)
HAL庫(kù)文件夾結(jié)構(gòu)

Src(Source):外設(shè)驅(qū)動(dòng)源碼,Inc(Include):外設(shè)驅(qū)動(dòng)源碼頭文件。
HAL庫(kù)文件介紹:
- stm32f1xx_hal.c, stm32f1xx_hal.h
HAL庫(kù)初始化、系統(tǒng)滴答、HAL庫(kù)延時(shí)等相關(guān)函數(shù) - stm32f1xx_hal_conf.h
HAL庫(kù)的用戶(hù)配置文件,用于裁剪HAL庫(kù)、配置晶振參數(shù)等 - stm32f1xx_hal_def.h
包含HAL庫(kù)通用的枚舉類(lèi)型數(shù)據(jù)和宏定義 - stm32f1xx_hal_cortex.h, stm32f1xx_hal_cortex.c
內(nèi)核通用函數(shù)定義和聲明,如NVIC、MPU、系統(tǒng)軟復(fù)位、Systick等,其實(shí)主要是對(duì)core_cm3.h 文件的相關(guān)函數(shù)再次封裝。 - stm32f1xx_hal_ppp.c, stm32f1xx_hal_ppp.h
某任意外設(shè)驅(qū)動(dòng)源碼,PPP表示任意外設(shè) - stm32f1xx_hal_ppp_ex.c, stm32f1xx_hal_ppp_ex.h
主要是存放外設(shè)的擴(kuò)展(特殊)功能的驅(qū)動(dòng)源碼,PPP表示任意外設(shè) - stm32f1xx_II_ppp.c, stm32f1xx_II_ppp.h
LL庫(kù)驅(qū)動(dòng)源碼,在部分STM32F1xx_hal_ppp.c 或stm32f1xx_hal_ppp_ex.c中會(huì)被調(diào)用
HAL庫(kù)API函數(shù)和變量命名規(guī)則:
- stm32f1xx_hal_ppp .(c/h)
- 函數(shù)名:HAL_PPP_Function
- 外設(shè)句柄:PPP_HandleTypeDef
- 外設(shè)工作參數(shù)初始化結(jié)構(gòu)體:PPP_InitTypeDef
- 配置參數(shù)結(jié)構(gòu)體:PPP_ YyyyConfTypeDef
- stm32f1xx_hal_ppp_ex .(c/h)
- 函數(shù)名:HAL_PPPEx_Function
- 外設(shè)句柄:無(wú)
- 外設(shè)工作參數(shù)初始化結(jié)構(gòu)體:PPP_InitTypeDef
- 配置參數(shù)結(jié)構(gòu)體:PPP_ YyyyConfTypeDef
- 初始化/反初始化函數(shù):
- HAL_PPP_Init(),HAL_PPP_DeInit()
- 外設(shè)讀寫(xiě)函數(shù):
- HAL_PPP_Read(),
- HAL_PPP_Write(),
- HAL_PPP_Transmit(),
- HAL_PPP_Receive()
- 控制函數(shù):
- HAL_PPP_Set (),
- HAL_PPP_Get ()
- 狀態(tài)和錯(cuò)誤:
- HAL_PPP_GetState (),HAL_PPP_GetError ()
HAL庫(kù)對(duì)寄存器位操作的相關(guān)宏定義:
- __HAL_PPP_ENABLE_IT( HANDLE , INTERRUPT )
使能外設(shè)中斷 - __HAL_PPP_DISABLE_IT( HANDLE , INTERRUPT )
禁用外設(shè)中斷 - __HAL_PPP_GET_IT ( HANDLE , __ INTERRUPT __)
獲取外設(shè)某一中斷源 - __HAL_PPP_CLEAR_IT ( HANDLE , __ INTERRUPT __)
清除外設(shè)中斷 - __HAL_PPP_GET_FLAG ( HANDLE , FLAG )
獲取外設(shè)的狀態(tài)標(biāo)記 - __HAL_PPP_CLEAR_FLAG ( HANDLE , FLAG )
清除外設(shè)的狀態(tài)標(biāo)記 - __HAL_PPP_ENABLE( HANDLE )
使能某一外設(shè) - __HAL_PPP_DISABLE( HANDLE )
禁用某一外設(shè) - __HAL_PPP_XXXX ( HANDLE , PARAM )
針對(duì)外設(shè)的特殊操作 - _HAL_PPP_GET IT_SOURCE ( HANDLE , __INTERRUPT __)
檢查外設(shè)的中斷源
HAL庫(kù)回調(diào)函數(shù):
- HAL_PPP_MspInit() / _MspDeInit()
舉例: HAL_USART_MspInit() 會(huì)被HAL_PPP_Init() 函數(shù)調(diào)用,該函數(shù)主要用于存放外設(shè)使用到的GPIO、CLOCK、NVIC、DMA等初始化代碼。 - HAL_PPP_ProcessCpltCallback
舉例: HAL_USART_TxCpltCallback由外設(shè)中斷或DMA中斷調(diào)用,HAL庫(kù)中斷公共處理函數(shù)已經(jīng)實(shí)現(xiàn)對(duì)中斷標(biāo)記位讀取、判斷和清除操作,用戶(hù)只需要專(zhuān)注于中斷邏輯功能的實(shí)現(xiàn)即可。 - HAL_PPP_ErrorCallback
舉例: HAL_USART_ErrorCallback外設(shè)或DMA中斷中發(fā)生的錯(cuò)誤,用于發(fā)生錯(cuò)誤處理。
此類(lèi)函數(shù)通常被_weak修飾(弱函數(shù)),允許用戶(hù)重新定義該函數(shù)。
1.5 HAL庫(kù)的設(shè)計(jì)思想
HAL庫(kù)借鑒 面向?qū)ο蟮脑O(shè)計(jì)思想 :

開(kāi)發(fā)方式的特點(diǎn):
- 屏蔽底層硬件 :編程者只需要了解庫(kù)函數(shù)中相關(guān)接口函數(shù)的功能,并按照要求傳入?yún)?shù),利用返回值完成操作即可,不需要過(guò)多了解底層硬件。
- 提高開(kāi)發(fā)效率 :開(kāi)發(fā)難度較小,開(kāi)發(fā)周期較短,后期的維護(hù)升級(jí)、以及硬件平臺(tái)的移植等工作量較小。
- 程序執(zhí)行效率 :由于考慮了程序的穩(wěn)健性、擴(kuò)充性和可移植性,程序代碼比較繁瑣和臃腫,執(zhí)行效率較低。
用戶(hù)代碼的處理主要分為三部分:
- 處理外設(shè)句柄(實(shí)現(xiàn)用戶(hù)功能)
- 處理MSP
- 處理各種回調(diào)函數(shù)
設(shè)計(jì)思想:從抽象到重載

1.6 以USART為例說(shuō)明HAL庫(kù)的抽象結(jié)構(gòu)
①外設(shè)句柄的定義:
HAL庫(kù)在結(jié)構(gòu)上,對(duì)每個(gè)外設(shè)抽象成了一個(gè)稱(chēng)為ppp_HandleTypeDef的結(jié)構(gòu)體,其中ppp就是每個(gè)外設(shè)的名字。所有的函數(shù)都是工作在ppp_HandleTypeDef指針之下。
例如,使用USART2時(shí),可以定義USART初始化結(jié)構(gòu)體變量(全局變量)huart2。huart2就被稱(chēng)為串口的句柄,它被貫穿整個(gè)USART收發(fā)的流程。
UART_HandleTypeDef huart2;
②外設(shè)句柄數(shù)據(jù)類(lèi)型的組成:


③串口初始化數(shù)據(jù)類(lèi)型的組成:

④串口初始化過(guò)程:

抽象—串口初始化函數(shù)
MX_USART2_UART_Init: 將與MCU無(wú)關(guān)的通信參數(shù)存入句柄結(jié)構(gòu) +使用HAL_UART_Init執(zhí)行串口初始化操作,將句柄參數(shù)寫(xiě)入寄存器。
HAL_UART_Init` 干了哪些事?調(diào)用
HAL_UART_MspInit* 修改狀態(tài)忙* 配置寄存器* 清除標(biāo)志位
承載—與MCU相關(guān)的初始化函數(shù)
HAL_UART_MspInit: 時(shí)鐘初始化 + 引腳初始化
⑤串口中斷處理過(guò)程:

HAL_UART_Receive_IT:開(kāi)啟中斷,在中斷方式下接收一定數(shù)量的數(shù)據(jù)。USART2_IRQHandler:串口2的中斷服務(wù)程序,調(diào)用串口中斷通用處理函數(shù)HAL_UART_IRQHandler。HAL_UART_IRQHandler:在函數(shù)HAL_UART_IRQHandler內(nèi)部通過(guò)判斷中斷類(lèi)型是否為接收完成中斷,確定是否調(diào)用UART_Receive_IT。
函數(shù)UART_Receive_IT的作用是把每次中斷接收到的字符保存在串口句柄的緩存指針pRxBuffPtr中,同時(shí)每次接收一個(gè)字符,其計(jì)數(shù)器RxXferCount減 1,直到接收完成RxXferSize個(gè)字符之后RxXferCount設(shè)置為0,同時(shí)調(diào)用接收完成回調(diào)函數(shù)HAL_UART_RxCpltCallback進(jìn)行處理。HAL_UART_RxCpltCallback:函數(shù)由串口中斷通用處理函數(shù)UART_Receive_IT調(diào)用,完成所有串口的接收中斷任務(wù)處理,函數(shù)內(nèi)部需要根據(jù)串口句柄的實(shí)例來(lái)判斷是哪一個(gè)串口產(chǎn)生的接收中斷,函數(shù)由用戶(hù)根據(jù)具體的處理任務(wù)編寫(xiě)。
-
微控制器
+關(guān)注
關(guān)注
49文章
8844瀏覽量
165622 -
mcu
+關(guān)注
關(guān)注
147文章
19116瀏覽量
403468 -
STM32
+關(guān)注
關(guān)注
2312文章
11189瀏覽量
374557 -
Cortex
+關(guān)注
關(guān)注
2文章
220瀏覽量
48997 -
HAL庫(kù)
+關(guān)注
關(guān)注
1文章
121瀏覽量
7736
發(fā)布評(píng)論請(qǐng)先 登錄
hadoop框架結(jié)構(gòu)的說(shuō)明介紹
STM32庫(kù)基礎(chǔ)知識(shí)
STM32H7的DAC基礎(chǔ)知識(shí)和HAL庫(kù)API
講解內(nèi)部Flash的基礎(chǔ)知識(shí)和對(duì)應(yīng)的HAL庫(kù)API
STM32H7的TIM定時(shí)器基礎(chǔ)知識(shí)和HAL庫(kù)
【STM32F407開(kāi)發(fā)板用戶(hù)手冊(cè)】第23章 STM32F407的USART串口基礎(chǔ)知識(shí)和HAL庫(kù)API 精選資料分享
USART的基礎(chǔ)知識(shí)和對(duì)應(yīng)的HAL庫(kù)API
STM32H7的ADC基礎(chǔ)知識(shí)和HAL庫(kù)API
入門(mén)有必要選擇STM32Cube HAL庫(kù)開(kāi)發(fā)嗎?
【STM32H7教程】第57章 STM32H7硬件JPEG編解碼基礎(chǔ)知識(shí)和HAL庫(kù)API
STM32基礎(chǔ)知識(shí):HAL庫(kù)的框架結(jié)構(gòu)
評(píng)論