- 基于STM32的嵌入式系統(tǒng)設計與實踐
- 鐘佩思 徐東方 劉梅編著
- 5000字
- 2021-03-12 20:28:37
2.2 庫文件及其層次關系
2.2.1 CMSIS標準軟件架構
基于Cortex-M3內(nèi)核的芯片雖然所采用的內(nèi)核是相同的,但核外的片上外設之間存在差異,而這些差異會導致軟件在同內(nèi)核、不同外設的芯片上移植困難。為了解決不同的芯片廠商所生產(chǎn)的Cortex系列微控制器軟件的兼容性問題,ARM公司與ST公司、Atmel公司、Keil公司等諸多芯片和軟件廠商制定了CMSIS標準(Cortex Microcontroller Software Interface Standard)。
所謂CMSIS標準,是指建立一個硬件抽象層,基于CMSIS標準的軟件架構(見圖2.2)主要分為用戶應用層、CMSIS層(包含操作系統(tǒng)和CMSIS核心層兩部分)和硬件寄存器層三層。CMSIS層起著承上啟下的作用,一方面它對硬件寄存器層進行統(tǒng)一實現(xiàn),屏蔽了不同廠商對Cortex-M系列微控制器核內(nèi)外設寄存器的不同定義;另一方面它為操作系統(tǒng)和用戶應用層提供接口,簡化了應用程序開發(fā)難度。因此,CMSIS層的實現(xiàn)相對復雜,CMSIS核心層主要分為以下3部分。

圖2.2 基于CMSIS標準的軟件架構
(1)核內(nèi)外設訪問層(Core Peripheral Access Layer,CPAL)。該層主要由ARM公司負責實現(xiàn),包括對內(nèi)核寄存器名稱、地址的定義,對NVIC(嵌套向量中斷控制器)、調(diào)試子系統(tǒng)訪問接口的定義和對特殊用途寄存器訪問接口(如CONTROL,xPSR等)的定義等。
(2)片上外設訪問層(Device Peripheral Access Layer,DPAL)。該層由芯片廠商負責實現(xiàn),與核內(nèi)外設訪問層類似,主要負責對硬件寄存器地址和外設訪問接口進行定義。該層可調(diào)用核內(nèi)外設訪問層提供的接口函數(shù),同時根據(jù)設備特性對異常向量表進行擴展,以處理相應外設的中斷請求。
(3)外設訪問函數(shù)(Access Functions for Peripherals,AFP)。該層由芯片廠商負責實現(xiàn),主要用于提供訪問片上外設的訪問函數(shù),這一部分是可選的。
對于一個Cortex-M系列微控制系統(tǒng)而言,CMSIS標準提供了與芯片廠商無關的硬件抽象層,既可以為接口外設、實時操作系統(tǒng)提供簡單的處理器軟件接口,又可以屏蔽不同硬件之間的差異,這對軟件的移植具有極大的幫助。STM32標準函數(shù)庫是按照這個標準來建立的。
2.2.2 庫目錄和文件簡介
STM32標準函數(shù)庫可以從ST公司的官網(wǎng)上下載。下面介紹目前最新的3.5.0庫文件。將下載的STM32標準函數(shù)庫解壓后,打開STM32F10x_StdPeriph_Lib_V3.5.0文件夾,可以看到STM32標準函數(shù)庫中的各文件夾,如圖2.3所示。

圖2.3 STM32標準函數(shù)庫
h_tmresc文件夾包含ST與CMSIS的圖標,這些一般用不到;Libraries文件夾包含驅(qū)動庫的源代碼和啟動文件,所要使用的庫函數(shù)就在這個文件夾中,在使用庫函數(shù)進行開發(fā)時,需要把Libraries目錄下的庫函數(shù)文件添加到相應的工程中,因此這個文件夾十分重要;Project文件夾包含用驅(qū)動庫寫的各種例子和工程模板,內(nèi)容非常全面,為每個外設寫好的例程具有非常重要的參考價值;Utilities文件夾包含基于ST官方評估開發(fā)板的各種例程,這些例程在實際的嵌入式系統(tǒng)開發(fā)過程中一般用不到;stm32f10x_stdperiph_lib_um.chm是STM32標準函數(shù)庫使用的英文幫助文檔,這是一個已經(jīng)編譯好的HTML文件,主要講述每個庫函數(shù)的使用方法,具有非常重要的參考價值。
在庫文件中,Libraries文件夾是開發(fā)過程中一定會用到的,打開Libraries文件夾,可以看到關于內(nèi)核與外設的庫文件分別存放在CMSIS文件夾和STM32F10x_StdPeriph_Driver文件夾中。下面簡要介紹開發(fā)過程中用到的主要文件。
1. CMSIS文件夾
CMSIS文件夾中的主要文件及其位置關系如圖2.4所示。

圖2.4 CMSIS文件夾中的主要文件及其位置關系
(1)內(nèi)核相關文件。CoreSupport文件夾中有core_cm3.c和core_cm3.h兩個文件。core_cm3.c文件是實現(xiàn)操作內(nèi)核外部寄存器的函數(shù),而core_cm3.h頭文件用于實現(xiàn)內(nèi)核寄存器的映射,與DeviceSupport文件夾中的外設頭文件stm32f10x.h相對應,其區(qū)別在于core_cm3.h針對的是內(nèi)核外設,而stm32f10x.h針對的是片上外設。另外,core_cm3.h頭文件還包含stdint.h頭文件,這是一個ANSIC文件,獨立于微控制器之外。它位于RVMDK軟件的安裝目錄下,其主要作用是提供一些類型定義,這些類型定義用于屏蔽在不同芯片平臺上出現(xiàn)的諸如int的大小是16位還是32位的差異。stdint.h頭文件中的類型定義如下。在開發(fā)設計過程中,所使用的數(shù)據(jù)類型均應以stdint.h頭文件中定義的為準。

(2)STM32啟動文件。由圖2.4可以看出,STM32的啟動文件放在arm文件夾中,這個文件夾中有很多啟動文件。不同型號的單片機所使用的啟動文件也不一樣。STM32啟動文件說明如表2.1所示。
表2.1 STM32啟動文件說明

STM32F103ZET6單片機芯片的內(nèi)部FLASH存儲器容量為512KB,屬于基礎型中的大容量產(chǎn)品,所以啟動文件應該選擇startup_stm32f10x_hd.s。
(3)STM32專用文件。stm32f10x.h頭文件包含STM32F10×全系列所有外設寄存器的定義(寄存器的基地址和布局等)、位定義、中斷向量表和存儲空間的地址映射等,是一個非常重要的頭文件,在內(nèi)核中與之相對應的頭文件是core_cm3.h。system_stm32f10x.c文件和system_stm32f10x.h頭文件是STM32F10×系列微控制器的專用系統(tǒng)文件,其中system_stm32f10x.c文件主要對片上的RCC外設進行操作,用于實現(xiàn)STM32的時鐘配置。系統(tǒng)在上電之后,首先會執(zhí)行由匯編語言編寫的啟動文件,啟動文件中的復位函數(shù)所調(diào)用的Systeminit函數(shù)(用來初始化微控制器)就是在system_stm32f10x.c文件中定義的,調(diào)用完之后,STM32F103系列芯片的系統(tǒng)時鐘頻率會被初始化成72MHz。在實際應用中如果需要對系統(tǒng)時鐘進行重新配置,則可以參考這個函數(shù)重寫,為了維持STM32標準函數(shù)庫的完整性,建議不要直接在這個文件里修改時鐘配置函數(shù)。
2. STM32F10x_StdPeriph_Driver文件夾
Libraries目錄下的STM32F10x_StdPeriph_Driver文件夾中包含inc(include的縮寫)和src(source的縮寫)兩個文件夾,其中所包含的是不屬于CMSIS文件夾的片上外設相關文件。src文件夾中包含每個外設的驅(qū)動源文件,而inc文件夾中包含相對應的頭文件,這些是ST公司針對每個STM32外設所編寫的庫函數(shù)文件,是STM32標準函數(shù)庫的主要內(nèi)容,其重要性不言而喻。
每個外設對應一個.c后綴的驅(qū)動源文件和一個.h后綴的頭文件,這些外設文件分別統(tǒng)稱為stm32f10x_ppp.c文件和stm32f10x_ppp.h文件,其中ppp表示外設名稱。例如,對于ADC外設,在src文件夾中有一個stm32f10x_adc.c驅(qū)動源文件,而在inc文件夾中有一個stm32f10x_adc.h頭文件與之相對應。若開發(fā)的工程用到了STM32內(nèi)部的ADC,則至少要把這兩個文件添加到工程中。src文件夾和inc文件夾中的所有驅(qū)動源文件和頭文件如圖2.5所示,從中可以看出,除了stm32f10x_ppp.c文件和stm32f10x_ppp.h文件,這兩個文件夾中還有一個很特別的misc.c文件和與之對應的misc.h頭文件。這個文件包含外設對內(nèi)核中的NVIC的訪問函數(shù),在配置中斷時,必須把這個文件添加到工程中。

圖2.5 src文件夾和inc文件夾中的所有驅(qū)動源文件和頭文件
3. 庫工程模板
在文件目錄STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template下,存放了一個官方的庫工程模板。當使用庫函數(shù)建立一個完整的工程時,需要添加該目錄下的stm32f10x_it.c文件、system_stm32f10x.c文件和stm32f10x_conf.h頭文件。
stm32f10x_it.c文件是專門用來編寫中斷服務函數(shù)的。該文件已經(jīng)定義好了一些系統(tǒng)異常中斷(特殊中斷)的接口,而其他普通中斷服務函數(shù)可以在開發(fā)過程中自行添加。在編寫中斷服務函數(shù)時,其函數(shù)接口并不是隨意定義的,相關接口可以在匯編啟動文件中找到,這部分內(nèi)容在學習中斷時再詳細介紹。
system_stm32f10x.c文件在前面已經(jīng)介紹過了,它包含STM32芯片上電后初始化系統(tǒng)時鐘和擴展外部存儲器所用的函數(shù)。在實際應用中如果需要修改系統(tǒng)時鐘頻率,可以參照該文件重寫時鐘配置函數(shù)。為了保持STM32標準函數(shù)庫的完整性,建議不要直接在這個文件中修改時鐘配置函數(shù)。
stm32f10x_conf.h頭文件包含所有片上外設的頭文件,它被包含在stm32f10x.h頭文件中。如果沒有stm32f10x_conf.h頭文件,在使用庫函數(shù)編程時,用到某個外設的驅(qū)動庫,就必須把該外設的頭文件包含進來。如果用了很多外設,則需要分別將每個外設對應的頭文件都包含進來,這不僅影響代碼的美觀性,也不好管理。stm32f10x_conf.h頭文件很好地實現(xiàn)了片上外設頭文件的統(tǒng)一管理,因此應用程序只要包含這個頭文件即可。由于這個頭文件被包含在stm32f10x.h頭文件中,所以最終只需要包含stm32f10x.h頭文件即可。stm32f10x_conf.h頭文件中的程序代碼如下。

在默認情況下,所有頭文件都被包含,但在開發(fā)過程中可以把不用的頭文件注釋掉,只留下需要的即可。
stm32f10x_conf.h頭文件還可以配置是否使用斷言編譯選項,程序代碼如下。

STM32標準函數(shù)庫中的函數(shù)一般會包含輸入?yún)?shù)的檢查,即代碼中的assert_param宏。當參數(shù)不符合要求時,會調(diào)用assert_failed函數(shù),這個函數(shù)默認是空的。
在實際開發(fā)中使用斷言編譯選項時,先通過定義USE_FULL_ASSERT宏來使能斷言,然后定義assert_failed函數(shù),通常會讓它調(diào)用printf函數(shù),以輸出錯誤說明。在使能斷言后,程序在運行時會對函數(shù)的輸入?yún)?shù)進行檢查,當通過測試可以發(fā)布時,會通過取消USE_FULL_ASSERT宏來去掉斷言功能,使程序全速運行。
4. 庫文件之間的相互關系
將庫文件對應到基于CMSIS標準的軟件架構上,其層次關系如圖2.6所示。

圖2.6 庫文件之間的層次關系
根據(jù)前面對主要庫文件及其作用的簡要介紹,我們已大致了解了STM32標準函數(shù)庫,下面將從整體上來把握該庫中各個文件之間的相互關系。在基于CMSIS標準的軟件架構的庫文件層次關系中,位于用戶應用層的幾個文件需要針對不同的應用場合進行配置和修改。在編程時需要把位于CMSIS層的文件包含進工程中,除了個別應用場合在修改系統(tǒng)時鐘頻率時,可以對system_stm32f10x.c文件進行適當改動(最好另外重寫時鐘配置函數(shù)),為了保持STM32標準函數(shù)庫的完整性,建議不修改CMSIS層中的其他文件。
2.2.3 如何使用官方資料
由2.2.2節(jié)的介紹可知,庫函數(shù)是指STM32標準函數(shù)庫文件中編寫好的驅(qū)動外設的函數(shù)接口。只要調(diào)用這些庫函數(shù),就可以實現(xiàn)STM32寄存器的配置。在實際開發(fā)過程中,可以不知道庫函數(shù)驅(qū)動外設的具體實現(xiàn)過程,但是在調(diào)用函數(shù)時必須知道所使用的函數(shù)的功能、可傳入?yún)?shù)及其意義和函數(shù)的返回值,如何才能記住這么多函數(shù)呢?其實,并不需要耗費精力去記住這些函數(shù),在開發(fā)過程中只要會查閱就可以了,所以學會查閱官方幫助文檔是很有必要的。
事實上,目前人們所能接觸到的所有關于STM32的嵌入式系統(tǒng)設計與開發(fā)教程,都來自STM32官方資料。這些官方資料是所有關于STM32知識的源頭,幾乎包含了開發(fā)過程中所有可能遇到的問題。通過查閱這些官方資料,不僅能夠更加順利地進行嵌入式系統(tǒng)的設計與開發(fā),還能夠進一步深入、全面地了解STM32。下面講解開發(fā)過程中較為常用的官方資料及其使用。
(1)《STM32F10x中文參考手冊》。《STM32F10x中文參考手冊》翻譯自STM32英文參考手冊STM32 Reference Manual,該手冊全方位地介紹了STM32芯片的各種片上外設,把STM32的時鐘、存儲器架構、各種外設、寄存器都描述得清清楚楚。當對STM32的外設感到困惑時,可以查閱該手冊。如果以直接配置寄存器的方式進行系統(tǒng)設計與開發(fā),則查閱該手冊的寄存器部分的頻率會相當高。采用這種開發(fā)方式比采用庫函數(shù)開發(fā)方式的效率要低很多。
(2)《Cortex-M3權威指南》。《Cortex-M3權威指南》由ARM公司提供,是針對Cortex-M3內(nèi)核的經(jīng)典官方資料,它詳細講解了Cortex-M內(nèi)核的架構和特性。如果需要深入了解Cortex-M內(nèi)核的相關知識,那么這個文檔應該是首選參考資料。
(3)《Cortex-M3內(nèi)核編程手冊》。《Cortex-M3內(nèi)核編程手冊》由ST公司提供,主要介紹STM32內(nèi)核寄存器的相關知識,如系統(tǒng)定時器、NVIC等核內(nèi)外設寄存器。這部分內(nèi)容是對《STM32F10x中文參考手冊》沒有涉及的內(nèi)核部分所進行的補充。但是相對來說,《Cortex-M3內(nèi)核編程手冊》對內(nèi)核架構和特性方面的介紹不如《Cortex-M3權威指南》詳細,當需要學習Cortex-M內(nèi)核編程時,這兩個官方資料可以相互配合使用。
(4)《STM32規(guī)格書》。《STM32規(guī)格書》相當于STM32的數(shù)據(jù)手冊,它包含STM32芯片所有的引腳功能說明、存儲器架構和芯片外設架構說明。當在設計開發(fā)過程中使用STM32的其他外設時,需要用到《STM32規(guī)格書》,通過它能夠查閱所使用的外設具體應該對應STM32中的哪個引腳。
(5)stm32f10x_stdperiph_lib_um.cbm。stm32f10x_stdperiph_lib_um.cbm是本章提到的STM32F10x_StdPeriph_Lib_V3.5.0文件夾中的庫幫助文檔。在使用庫函數(shù)設計嵌入式系統(tǒng)時,可以先通過查閱該文檔來了解STM32標準函數(shù)庫提供的外設、函數(shù)原型或庫函數(shù)的調(diào)用的方法,這會使開發(fā)過程更為順暢。當然也可以直接查閱STM32標準函數(shù)庫的源碼,庫幫助文檔的說明是根據(jù)源碼生成的,所以直接查看源碼也可以了解函數(shù)功能。
庫幫助文檔如圖2.7所示。逐層打開庫幫助文檔中的目錄標簽Modules\STM32F10x_StdPeriph_Driver,可看到標簽下有很多外設驅(qū)動文件,如MISC、ADC、BKP和CAN等,這些驅(qū)動文件中介紹了每個庫函數(shù)的使用方法。

圖2.7 庫幫助文檔
以查閱GPIO端口的位設置函數(shù)GPIO_SetBits為例,打開標簽GPIO\GPIO_Private_Functions\Functions\GPIO_SetBits,可以看到如圖2.8所示的庫幫助文檔的函數(shù)說明。通過閱讀這個函數(shù)說明,即使不去看它的程序源代碼,也能夠知道它所實現(xiàn)的功能和具體的使用方法。

圖2.8 庫幫助文檔的函數(shù)說明
從圖2.8中可以看出,GPIO_SetBits函數(shù)的原型為void GPIO_SetBits(GPIO_TypeDef*GPIOx,uint16_t GPIO_Pin),其功能是通過輸入一個類型為GPIO_TypeDef的指針參數(shù)GPIOx選定要控制的GPIO端口,其中x可以取A~G中的任何一個,由此選擇所控制的GPIO端口;再通過輸入GPIO_Pin宏指定要寫入的端口位,此參數(shù)可以是GPIO_Pin_x的任意組合,其中x的值可以是0~15。調(diào)用的函數(shù)沒有返回值,通過輸入相應的參數(shù)即可實現(xiàn)對端口位的置位操作。
GPIO_SetBits函數(shù)中的兩個傳入?yún)?shù)屬于結構體指針,以圖2.8中的GPIO_TypeDef為例,如果開發(fā)者在函數(shù)調(diào)用過程中不了解某個參數(shù)類型要表達的意思,可以通過單擊函數(shù)原型中帶下畫線的“GPIO_TypeDef”直接獲得該類型的具體聲明,操作非常簡單方便。在后面的嵌入式系統(tǒng)設計過程中,也會簡要介紹經(jīng)常用到的STM32庫函數(shù),以保證開發(fā)者能夠順利地進行系統(tǒng)程序設計。但是若要詳細地了解某個庫函數(shù)的信息,則建議開發(fā)者查閱“stm32f10x_stdperiph_lib_um.cbm”庫幫助文檔。
通過解讀庫函數(shù)說明,我們會發(fā)現(xiàn)每個函數(shù)及其數(shù)據(jù)類型都符合“見名知義”的原則,可以看出STM32標準函數(shù)庫的編寫十分美觀,使用庫函數(shù)設計和開發(fā)STM32嵌入式系統(tǒng)不僅簡單迅速,而且可讀性非常強。
- 嵌入式實時操作系統(tǒng)原理與最佳實踐
- MC9S12XS單片機原理及嵌入式系統(tǒng)開發(fā)
- TinyML:基于TensorFlow Lite在Arduino和超低功耗微控制器上部署機器學習
- 嵌入式Qt實戰(zhàn)教程
- 51單片機逆向?qū)W習實戰(zhàn)教程(電子設計與嵌入式開發(fā)實踐叢書)
- STM32單片機全案例開發(fā)實戰(zhàn)
- 嵌入式系統(tǒng)Linux內(nèi)核開發(fā)實戰(zhàn)指南(ARM平臺)
- 計算機與嵌入式系統(tǒng)架構
- C51單片機項目設計實踐教程(第2版)
- AVR單片機原理與應用實例
- 愛上單片機(第4版)
- 嵌入式通信系統(tǒng)
- 單片機原理與工程應用
- 零基礎學西門子S7- 200 SMART PLC編程及應用
- 單片機應用技術項目教程(微課版)