keil MDK開發STM32使用內聯函式

2021-08-19 01:36:21 字數 1598 閱讀 5800

筆者在做移植時,將embest ide環境下的例程移到realview mdk的過程中,曾經遇到這樣乙個問題:在生成工程時,編譯全部通過,但在鏈結時提示許多符號未定義!如果讀者也遇到過這個問題,請繼續看下去,如果鏈結時提示未定義的變數是一些內聯函式(即使用了關鍵字__inline)。那麼就是筆者遇到的問題了。希望這篇文章對您有所幫助。

在mdk中使用關鍵字__inline時,除了執行速度和占用空間和普通函式不一樣之外,還有以下與普通函式不一樣的地方:表現為,不能將其申明為外部函式,即不能將__inline函式定義在乙個外部檔案中然後在引用的檔案中申明為extern型別。

原因是mdk中使用的__inline函式時和標準c++中的inline函式有相同的語義。

在c++標準中,乙個內聯函式在用到它的每個解釋單元需要相同的定義,這樣看來只有內部鏈結的才可能內聯。將外部檔案中的函式鏈結並內聯似乎不可能,特別是外部函式是非內聯的。為了在不同檔案之間的函式可以內聯,必須:

將這些函式放在乙個通用的標頭檔案中,例如foo.h;

將這些函式標記為extern __inline;

在需要該內聯函式時,#include內聯函式所在的標頭檔案。

當編譯器決定不內聯某個函式時,在編譯鏈結之後該函式只有乙個拷貝。注:根據筆者的實驗發現也可以將內聯函式直接定義為__inline。

在mdk中如果將__inline函式申明為extern的話,在編譯時會通過,而在鏈結時會說這些函式沒定義。這點與embest ide不同。embest ide允許將內聯函式在外部檔案中定義,在引用的檔案中,只須申明為extern型別即可通過編譯鏈結。

解決辦法,將內聯函式定義在.h檔案中,在需要引用的檔案中包含該標頭檔案。這樣就可以呼叫標頭檔案中的內聯函式了。並且能正確通過編譯、鏈結。

其實在mdk中at91rm9200的標準庫中也是這麼做的,at91rm9200的標準庫有兩個.h檔案――at91rm9200.h和lib_at91rm9200.h,其中at91rm9200.h中定義一些常量和外圍介面結構體。其中lib_at91rm9200.h中存放的就是庫函式,其庫函式均為內聯函式。

注:以上兩個標頭檔案存放的路徑為c:keilarmincatmelrm9200。(其中mdk安裝路徑為c:keil)

你用 __inline就行了,要注意,是小寫的,這是標準的c語言寫法,而你看到的 __inline,是

stm32

的庫進行的巨集定義,不是標準的c語言。

那個巨集定義在 core_m3.c檔案裡,只有在那個檔案,__inline才起作用。

#elif defined ( __tasking__ )

#define __asm __asm /*!< asm keyword for tasking compiler */

#define __inline inline /*!< inline keyword for tasking compiler */

#endif

這就是那個c檔案裡的巨集定義。

在iar中的寫法如下:

#pragma inline

int gettwobyte(const char *cmd,int pos)

在keil中的寫法如下:

__inline int gettwobyte(const char *cmd,int pos)

Keil MDK下學習STM32注意事項

摘自 1 stm32韌體庫使用外圍裝置的主要思路 在stm32中,外圍裝置的配置思路比較固定。首先是使能相關的時鐘,一方面是裝置本身的時鐘,另一方面如果裝置通過io口輸出還需要使能io口的時鐘 最後如果對應的io口是復用功能的io口,則還必須使能afio的時鐘。其次是配置gpio,gpio的各種屬性...

STM32開發點滴

上北郵研究生以來,恍恍惚惚已經過了一年,隨著師兄師姐們陸續離開實驗室去工作崗位,這下半年開始頓感壓力很大,主要還是因為自己太水了,演算法不精,語言不精,也沒發,連身體都沒鍛鍊好。所以這學期開始得要好好幹點對得起自己的事了。就順便記錄一下即將交工的stm32的專案,也算是對自己的激勵。用keil開發的...

STM32開發 GPIO詳解

之前有簡單講過gpio工作模式和暫存器,還是有點沒搞明白。這次需要全方位的看一下了。可知 stm32f105rc 一共有4組io口 一共16x3 3 51個io gpioa0 a15 gpiob0 b15 gpioc0 c15 gpiod0 d2 stm32f105rc使用gpio埠號為 gpioa...