keil作為單片機(jī)學(xué)習(xí)入門必備的軟件,用戶量還是非常龐大的,當(dāng)然使用過程中遇到的問題也是五花八門,特別是初學(xué)者,有時可能卡在一個問題上幾天都解決不了。 ?
1、自定義關(guān)鍵字
? ? 在軟件項(xiàng)目中,我們經(jīng)常會自定義一些數(shù)據(jù)類型,由于自定義的數(shù)據(jù)類型不屬于關(guān)鍵字,所以在 Keil 中無法高亮顯示。Keil 的配置選項(xiàng)中,提供了自定義關(guān)鍵字配置;我們可以將自定義的數(shù)據(jù)類型設(shè)置為關(guān)鍵字,從而實(shí)現(xiàn)自定義數(shù)據(jù)類型的高亮顯示。 步驟1:點(diǎn)擊工具欄中的扳手圖標(biāo),打開 Keil 配置選項(xiàng)。
? 步驟2:選擇 Configuration 中的 User Keywords 選項(xiàng),左側(cè) Text File Type 中選擇 C/C++ Editor files,在右側(cè)添加自定義關(guān)鍵字后點(diǎn)擊 OK 即可。
2、調(diào)試STM32的兩個誤會
? ? 一、片內(nèi)RAM用完了?
曾有兩個不同的STM32用戶反饋了相似的問題,他們在對STM32F7Cube庫里的工程例程進(jìn)行編譯時,發(fā)現(xiàn)了一個令人很不解的事。編譯的結(jié)果提示芯片內(nèi)的RAM幾乎都耗光了,但以他們對工程基本功能的了解,按理說不應(yīng)該那樣。 ? 具體情況是這樣的:他們先在STM32CubeF7的固件庫里打開了一個有關(guān)lwip應(yīng)用的工程示例。比如下面目錄處的一個工程,使用ARM MDK進(jìn)行編譯。 STM32Cube_FW_F7_V1.15.0ProjectsSTM32746G-DiscoveryApplicationsLwIPLwIP_HTTP_Server_Netconn_RTOSMDK-ARM。 結(jié)果發(fā)現(xiàn)編譯結(jié)果提示片內(nèi)RAM的空間已經(jīng)基本用完了,但感覺應(yīng)該用不了那么多RAM內(nèi)存。客戶還想添加自己的其它用戶程序,還需使用RAM呢。 打開相應(yīng)軟件工程,使用ARM MDK進(jìn)行編譯,發(fā)現(xiàn)編譯結(jié)果跟客戶反饋的一致。
從編譯結(jié)果來看,感覺RAM真的被用去了320多K,那RAM用到哪里去了呢?打開對應(yīng)的MAP文件進(jìn)一步查看,可得到如下數(shù)據(jù)。
先看看芯片內(nèi)部RAM情況。目前使用的芯片是STM32F746NG,查看其數(shù)據(jù)手冊可知其內(nèi)部系統(tǒng)RAM容量為320KB【1KB=1024B】,分別由如下三塊RAM區(qū)域組成,各區(qū)域容量及地址范圍如下:
結(jié)合編譯結(jié)果和上面數(shù)據(jù)信息來看,貌似RAM真的用完了。既然這樣,只好硬著頭皮繼續(xù)查看MAP文件的其它細(xì)節(jié),?看看RAM到底消耗在哪些地方去了。后來發(fā)現(xiàn)在某個地址段有個巨大的PAD補(bǔ)丁填充區(qū)。
即從0x2000fd08到0x2004bfff這段區(qū)域,共246,520Bytes【即上圖?黃色區(qū)域所指】。一般來講,代碼編譯后產(chǎn)生的PAD補(bǔ)丁塊往往是因?yàn)榈刂穼R方面的原因?qū)е碌囊恍┎槐闶褂玫牧闵?nèi)存碎片,正常來講,?這些補(bǔ)丁塊不會大面積的集中在一起。 比如使用下面結(jié)構(gòu)體變量的時候會插入padding.
? 但這里提示的補(bǔ)丁塊太大了,高達(dá)200多KB而且是連續(xù)空間!感覺是哪里誤會了。從分析來看,初步判斷這個PAD區(qū)間應(yīng)該還是可以被用戶使用的。于是嘗試在現(xiàn)有代碼里隨意增加一塊16KB的RAM有效使用量,編譯一切正常,編譯后顯示的內(nèi)存用量結(jié)果跟之前幾乎一模一樣,依然顯示RAM用完了。但通過查看MAP文件,可以發(fā)現(xiàn)上面提到的那個大補(bǔ)丁塊空間也隨之減小了16KB。顯然,RAM并非真正用完了,只是編譯器把它當(dāng)作類似對齊原因?qū)е碌难a(bǔ)丁塊了。現(xiàn)在問題是,怎么會被編譯器誤判成這么大的一個補(bǔ)丁塊呢? ? 進(jìn)一步查看MAP和部分代碼源文件,我們可以發(fā)現(xiàn)有一塊RAM區(qū)域,即芯片內(nèi)的SRAM2區(qū)域被用戶使用attribute關(guān)鍵字自行做了內(nèi)存使用分配了,即這塊內(nèi)存空間不是交給編譯器安排的。【下圖中綠色方框內(nèi)的內(nèi)存分配】
結(jié)合上面的分析,那個巨大的pad區(qū)域正是經(jīng)編譯器分配使用到的RAM空間的?末尾地址開始?到SRAM2起始地址【0X2004C000】之前的那段空間。 這里讓人想到一個地方,那就是MDK IDE選項(xiàng)配置中Target配置的這個地方:
這里片內(nèi)RAM配置是這樣的,意味著從0x20000000到0x2004ffff的全部RAM空間交由編譯器分配管理。
而在實(shí)際應(yīng)用代碼中,編譯器從0x20000000開始分配內(nèi)存,而SRAM2區(qū)域則由用戶自行安排使用的。這樣的話,經(jīng)編譯器所分配所用到的RAM內(nèi)存末尾到0x2004BFFF這段未用區(qū)域被視為了pad區(qū)域。看來只是誤會一場。 那如何消除這個誤會呢?我們可以將上面的內(nèi)存配置項(xiàng)稍微修改下,讓SRAM2區(qū)域不再讓編譯器分配管理,這樣就避免了編譯器分配的內(nèi)存末尾到SRAM2區(qū)域起始地址的這段空間被視為補(bǔ)丁區(qū)。像下面一樣修改:
這樣修改后再做編譯,結(jié)果如下,不再給人RAM都用光的感覺了,只用到70多KB的片內(nèi)RAM。
用人使用STM32F7開發(fā)產(chǎn)品,發(fā)現(xiàn)編譯時找不到合適的Flash算法文件,或者M(jìn)DK自帶的現(xiàn)有FLM文件用不了。具體情況是這樣的:有人使用STM32F750V8開發(fā)產(chǎn)品,編譯完畢后欲進(jìn)行下載調(diào)試,結(jié)果沒法完成程序下載,提示FLASH下載錯誤。
檢查了各個配置后,懷疑FLASH算法文件是否有問題。 打開MDK選項(xiàng)配置里flash_download的編程配置頁面,那里已經(jīng)添加了相關(guān)FLASH編程算法文件。
不過,如果使用STM32芯片做過開發(fā)的人可能比較容易發(fā)現(xiàn)有個地方有點(diǎn)刺眼,就是起始地址那個地方。用過STM32F0/F1/F4等系列的人可能比較容易發(fā)現(xiàn),那個FLASH起始地址一般是在0x8000000這個地方,這里卻是0x00200000。我們再看看MDK選項(xiàng)配置有關(guān)內(nèi)存分配的那個地方,如下圖所示:
這里的片內(nèi)FLASH默認(rèn)起始地址卻是0x8000000。顯然這里跟FLASH編程算法文件的起始地址定義不一致,初步判斷應(yīng)該是這個地方導(dǎo)致的問題。 到此,我們有必要看看STM32F7的相關(guān)技術(shù)手冊了關(guān)于內(nèi)部FLASH地址分配的內(nèi)容。下圖是STM32F750片內(nèi)主從外設(shè)及總線的框架圖,對于片內(nèi)FLASH,CPU可以有兩條總線通路訪問它,一條是通過AXIM接口,經(jīng)過AXI-AHB橋以64位總線訪問,另一條是通過ITCM接口,經(jīng)過片內(nèi)ART加速器后訪問它。【如下圖所示】
我們通過進(jìn)一步查看手冊,可以得知CPU訪問該FLASH區(qū)域時因使用不同總線接口而安排了不同的地址訪問區(qū)域。
從上面表格可以清楚地看到,CPU從不同接口訪問FLASH時其對應(yīng)地址是不一樣的。通過AXIM接口訪問內(nèi)部flash的起始地址為0x08000000,通過ITCM接口訪問內(nèi)部flash的起始地址是0x00200000。 ? 結(jié)合到上面案例,MDK選項(xiàng)配置中Target頁面的片內(nèi)FLASH地址安排與Flash算法定義的地址不一致導(dǎo)致程序下載失敗。那么,我們可以將二者的地址及大小調(diào)整得一致,具體根據(jù)實(shí)際開發(fā)需求來調(diào)整,即根據(jù)你希望CPU通過哪個接口來訪問FLASH來做相應(yīng)調(diào)整。 ? 1、如果希望走ITCM接口來訪問,我們就將Target頁面的FLASH存儲起始地址與FLASH算法文件定義的起始地址都設(shè)置為0x00200000,如下圖所示:
2、如果希望走AXIM接口來訪問,我們就將FLASH算法文件定義的起始地址與Target頁面定義得一致,這里就是0x08000000。 基于MDK提供的FLASH算法文件我們可以直接修改其起始地址及大小。比如,如果剛加載進(jìn)來的算法文件是基于ITCM接口的地址定義,如下圖所示。
我們可以直接基于上面算法文件參數(shù)進(jìn)行起始地址修改,即修改橢圓里的起始地址數(shù)據(jù),修改完畢后點(diǎn)擊下方的OK按鈕即可。操作如下圖所示:
【注:我所用ARM MDK版本為5.28。】 基于修改后的配置,再進(jìn)行編譯后即可進(jìn)行下載調(diào)試。
?
3、分享幾篇keil使用問題的文章
?
下面分享幾篇keil使用過程容易遇到的問題以及相關(guān)解決方案的文章。 ? 解決KEIL中ARM編譯器不能編譯的問題[1] 關(guān)于keil中無法跳轉(zhuǎn)到函數(shù)、變量定義處的問題[2] keil報錯解決:Loading PDSC Debug Description failed for STMicroelectronics STM32Fxxxxxxx[3] keil出現(xiàn)fatal error: error in backend: ran out of registers during register allocation的解決方案[4] 使用過程中遇到問題是正常的,首先不要著急,先自己根據(jù)報錯提示信息嘗試找到報錯問題所在以及報錯原因,試著對癥下藥。如果自己解決不了可以根據(jù)報錯代碼在keil官方手冊中查找對應(yīng)說明。如果平時有遇到其他問題并且還沒解決可以后臺留言。 ? 如果安裝多個keil產(chǎn)品遇到不能共存的問題可以參考視頻(這個鏈接是公眾號視頻鏈接可以直接打開):keil MDK與C51共存也算個問題?
編輯:黃飛
?
評論
查看更多