當(dāng)前位置:首頁 > 公眾號精選 > 玩轉(zhuǎn)嵌入式
[導(dǎo)讀]很久之前就聽說st出了一個(gè)新版本的庫,用于代替原來的標(biāo)準(zhǔn)庫,非常好奇,但是一直沒有機(jī)會去體驗(yàn)。這次借著做畢設(shè)的機(jī)會,嘗試著切換到新庫。官網(wǎng)介紹說,hal是一層硬件的抽象,看到這里,我非常激動,看來st終于意識到原來標(biāo)準(zhǔn)庫的問題了,原來的標(biāo)準(zhǔn)庫非常依賴于具體硬件細(xì)節(jié),很難體現(xiàn)出使用庫的優(yōu)勢,而且很難移植。同時(shí)我也非常好奇,st到底是如何把不同系列mcu的操作給封裝起來的,是不是足夠抽象,方便移植。

很久之前就聽說st出了一個(gè)新版本的庫,用于代替原來的標(biāo)準(zhǔn)庫,非常好奇,但是一直沒有機(jī)會去體驗(yàn)。這次借著做畢設(shè)的機(jī)會,嘗試著切換到新庫。

官網(wǎng)介紹說,hal(hardware abstract layer)是一層硬件的抽象,看到這里,我非常激動,看來st終于意識到原來標(biāo)準(zhǔn)庫的問題了,原來的標(biāo)準(zhǔn)庫非常依賴于具體硬件細(xì)節(jié),很難體現(xiàn)出使用庫的優(yōu)勢,而且很難移植。同時(shí)我也非常好奇,st到底是如何把不同系列mcu的操作給封裝起來的,是不是足夠抽象,方便移植。

話不多說,直接上官網(wǎng)下下來再說。

上圖就是hal庫的全部內(nèi)容,其中STM32F1xx_HAL_Driver中屬于hal庫的內(nèi)容。

拿到庫第一步需要做的就是配置一個(gè)簡單的hello world,我在配置的時(shí)候,出現(xiàn)了非常多的問題。最開始非常自信,只從文件夾里挑選自認(rèn)為有用的文件加入到工程中,結(jié)果出現(xiàn)了各種問題,里面各種庫的依賴關(guān)系比較復(fù)雜,如果不是很熟悉整個(gè)架構(gòu)的話,還是老老實(shí)實(shí)拷貝整個(gè)文件夾吧。

配置之前,首先要了解一下整個(gè)庫的框架,官方給的框架圖如下:

個(gè)人認(rèn)為這幅圖和我理解的有些許出入,故重新畫了一張:

有幾點(diǎn)區(qū)別:

  • cmsis我放在了驅(qū)動層的最底層,因?yàn)閏msis庫中包含的內(nèi)容都是和具體cpu內(nèi)核相關(guān)的東西,還有一些地址定義,這些都是非常底層的東西了,而且hal層確實(shí)是依賴于cmsis。

  • hal底層我增加了一層msp,類似于bsp,全稱是mcu support package,這一層相當(dāng)于hal的驅(qū)動層,與硬件相關(guān)的部分比如最終的時(shí)鐘配置,gpio配置等等提取出來,交給用戶配置。

了解了架構(gòu),下面我們就來配置一個(gè)簡單的工程吧。

  1. 首先拷貝整個(gè)Driver目錄到工程中。

  2. 新建user文件夾,新建main.c文件。
    找到stm32f1xx_hal_conf_template.h,stm32f1xx_hal_msp_template.c,去掉"_template"放入user文件夾。
    找到stm32f1xx_it.c和stm32f1xx_it.h放入user文件夾。

  3. 新建工程
    添加源文件:

配置工程:

  • 勾選Use MicroLib,因?yàn)閔al使用了c標(biāo)準(zhǔn)庫。

  • 添加全局宏定義:USE_HAL_DRIVER,STM32F103xB。關(guān)于芯片選擇,有如下表格:

  • 勾選c99支持,因?yàn)閔al采用的是c99標(biāo)準(zhǔn)編寫,不勾選的話,會出現(xiàn)類似于uint32_t等類型不存在的編譯錯(cuò)誤。

  • 添加包含目錄,如下圖:

4.編寫代碼:

配置stm32f1xx_hal_conf.h:
這里面有許多用于配置的宏,比如用于精準(zhǔn)延時(shí)的晶振頻率,還有各個(gè)外設(shè)模塊的開關(guān)等等。

main.c

		

#include "stm32f1xx_hal.h"int main() { ? ?HAL_Init(); __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitTypeDef gpio_initstruct; gpio_initstruct.Mode=GPIO_MODE_OUTPUT_PP; gpio_initstruct.Speed=GPIO_SPEED_FREQ_HIGH; gpio_initstruct.Pull=GPIO_NOPULL; gpio_initstruct.Pin=GPIO_PIN_13; HAL_GPIO_Init(GPIOC,&gpio_initstruct); while(1) ? ?{ ? ? ? ?HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,0); HAL_Delay(150); HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,1); HAL_Delay(150); HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,0); HAL_Delay(150); HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,1); HAL_Delay(1000); } ? ?return 0;}

stm32f1xx_hal_msp.c

			

#include "stm32f1xx_hal.h"void SystemClock_Config(void);void HAL_MspInit(void){ ? ?SystemClock_Config(); }void SystemClock_Config(void){ ?RCC_ClkInitTypeDef clkinitstruct = {0}; ?RCC_OscInitTypeDef oscinitstruct = {0}; /* Configure PLL ------------------------------------------------------*/ /* PLL configuration: PLLCLK = (HSI / 2) * PLLMUL = (8 / 2) * 16 = 64 MHz */ /* PREDIV1 configuration: PREDIV1CLK = PLLCLK / HSEPredivValue = 64 / 1 = 64 MHz */ /* Enable HSI and activate PLL with HSi_DIV2 as source */ oscinitstruct.OscillatorType ?= RCC_OSCILLATORTYPE_HSE;//RCC_OSCILLATORTYPE_HSI; oscinitstruct.HSEState ? ? ? ?= RCC_HSE_ON;//RCC_HSE_OFF; oscinitstruct.LSEState ? ? ? ?= RCC_LSE_OFF; ?oscinitstruct.HSIState ? ? ? ?= RCC_HSI_OFF;//RCC_HSI_ON; oscinitstruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; ?oscinitstruct.HSEPredivValue ? ?= RCC_HSE_PREDIV_DIV1; ?oscinitstruct.PLL.PLLState ? ?= RCC_PLL_ON; ?oscinitstruct.PLL.PLLSource ? = RCC_PLLSOURCE_HSE;//RCC_PLLSOURCE_HSI_DIV2; oscinitstruct.PLL.PLLMUL ? ? ?= RCC_PLL_MUL9;//RCC_PLL_MUL16; if (HAL_RCC_OscConfig(&oscinitstruct)!= HAL_OK) ?{ /* Initialization Error */ while(1); ?} /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 ? ? clocks dividers */ clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); ?clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; ?clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1; ?clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1; ?clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2)!= HAL_OK) ?{ /* Initialization Error */ while(1); ?} }

整個(gè)編程步驟就是,hal庫初始化->開外設(shè)時(shí)鐘->外設(shè)初始化->用戶程序,然后在msp.c文件里實(shí)現(xiàn)其他平臺相關(guān)的雜七雜八的操作,需要調(diào)用的時(shí)候會自動調(diào)用,我這里只實(shí)現(xiàn)了一個(gè)點(diǎn)亮led的功能,故只實(shí)現(xiàn)了HAL_MspInit()函數(shù)。如果我們要使用uart、adc等其他更復(fù)雜的外設(shè),我們需要在msp.c文件里重寫HAL_UART_MspInit()、HAL_ADC_MspInit()等函數(shù),當(dāng)我們調(diào)用HAL_PPP_Init()時(shí),他們都會自動被調(diào)用。

說到這里,我要說一下這里其實(shí)使用了一個(gè)c語言的技巧,實(shí)現(xiàn)了類似于c++的重載功能。比如我們來看UART的源文件:

			

/** ?* @brief ?USART MSP Init. ?* @param ?husart: Pointer to a USART_HandleTypeDef structure that contains ?* ? ? ? ? ? ? ? ? the configuration information for the specified USART module. ?* @retval None ?*/ __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart){ /* Prevent unused argument(s) compilation warning */ UNUSED(husart); /* NOTE: This function should not be modified, when the callback is needed, ? ? ? ? ? the HAL_USART_MspInit can be implemented in the user file ? */ }

函數(shù)被__weak修飾了,意思就是,如果別處沒定義,這個(gè)函數(shù)就是他,如果別處重定義了,就用新的函數(shù),這樣就實(shí)現(xiàn)了重載。這有一個(gè)很大的好處,就是實(shí)現(xiàn)思想中的差異化編程,hal實(shí)現(xiàn)所有硬件通用的功能,而把不通用的部分通過可重載的函數(shù)開放給用戶修改。

每個(gè)函數(shù)中,都會接收到一個(gè)handle指針,這其實(shí)和this指針非常類似,每個(gè)函數(shù)都不用知道自己到底是在操作某一個(gè)具體的對象,只需要根據(jù)handle的指向來操作就可以了。

回到上面的重載。在hal庫中有一點(diǎn)比較大的改變是,中斷都是通過回調(diào)函數(shù)來開放給用戶的,具體使用方式也是重載相關(guān)回調(diào)函數(shù),不像標(biāo)準(zhǔn)庫是直接在stm32fxxx_it.c里填寫相關(guān)中斷處理函數(shù)。這樣做的好處是,hal幫我們處理了一些中斷來臨時(shí)的雜務(wù),只把我們感興趣的事件開放給用戶。

但是個(gè)人覺得這個(gè)改變需要再徹底一點(diǎn),因?yàn)檫@并沒有解決代碼耦合性的痛點(diǎn),每一次我們需要寫中斷函數(shù)的時(shí)候,總是要去改底層代碼,而如果st給我們實(shí)現(xiàn)一個(gè)注冊回調(diào)的接口,那么上層和下層之前就完全分離了,應(yīng)用層各個(gè)模塊之間也不會產(chǎn)生耦合。

總結(jié):
總體而言,hal相比于標(biāo)準(zhǔn)庫,層次架構(gòu)更加清晰了,對平臺更加抽象,但是還遠(yuǎn)遠(yuǎn)不夠,依然非常依賴于具體的硬件,如果能實(shí)現(xiàn)Qt的那種抽象就完美了。用戶使用的時(shí)候,只用包含hal.h而不用去管是hal_f1還是hal_f2或是什么其他系列的頭文件,所有系列的代碼打包在一起,通過條件編譯來實(shí)現(xiàn)真正的跨平臺,而如果需要使用某款mcu的特色功能時(shí),就再包含一個(gè)hal_f1extend.h。如果這些st都實(shí)現(xiàn)了,那么單片機(jī)編程將會變得和應(yīng)用編程一樣簡單方便!

文章來源于“簡書”,作者:logic_wei

文章出處:http://www.jianshu.com/p/c6809c2bcb4f

關(guān)注微信公眾號『玩轉(zhuǎn)嵌入式』,后臺回復(fù)“128”獲取干貨資料匯總,回復(fù)“256”加入技術(shù)交流群。

精彩技術(shù)文章推薦


01

單片機(jī)的Bootloader,可以實(shí)現(xiàn)用戶輕松升級程序


02

模塊化編程,是團(tuán)隊(duì)協(xié)作編程的前提


03

PWM是什么,有哪些用處?


04

零基礎(chǔ)如何學(xué)習(xí)單片機(jī),一位入門者的進(jìn)階路徑,可參考



免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉