|
|
最近一直埋頭于設(shè)計的撰寫當(dāng)中,成天大眼對小眼地面對著word、viso和知網(wǎng)客戶端等等文字編輯工具真是有種麻木的趕腳,不寫不知道,一寫嚇一跳,感覺讓我寫上幾萬行代碼也比坐在電腦面前憋出幾萬字論文來的輕巧,“問君能有幾多愁,恰似一江春水向東流”,哎,突然間發(fā)現(xiàn),人生最最痛苦的不是人死了錢沒花了,而是寫了十幾天的論文才發(fā)現(xiàn),暈,還有一多半沒寫呢,不過木有辦法,只能硬著頭皮上了,再此之前還是更篇博客為好,不然該沉底落灰了(話說貌似斷更了好長時間了,不過幸好不是寫小說,不然該被拍磚了),哈哈~
閑話少說,下面進(jìn)入正題。其實(shí)關(guān)于Flash調(diào)試和RAM調(diào)試的概念,我也是從調(diào)試Kinetis的時候才開始接觸,最初只是隨便用用,沒有深究,之后用的多了才開始深入研究兩者之間的區(qū)別,發(fā)現(xiàn)里面大有文章可作,這也是我為什么后來又把本文的前綴改成【原創(chuàng)精品】的緣故,翻看了網(wǎng)上的一些資料,大多是授人以魚的文章,所以覺著有必要在這里談?wù)勛约旱囊稽c(diǎn)看法,做個筆記:

上圖為在IAR環(huán)境下的Flash調(diào)試界面和RAM調(diào)試界面
首先說說什么是Flash調(diào)試和RAM調(diào)試,F(xiàn)lash調(diào)試就是通常意義下的普通調(diào)試,即將編譯鏈接之后的code下載到單片機(jī)的ROM區(qū),數(shù)據(jù)放到RAM區(qū),然后進(jìn)行調(diào)試;而RAM調(diào)試則是將數(shù)據(jù)放到RAM區(qū)的同時再從RAM區(qū)中額外開辟出一段空間存放可執(zhí)行code,這樣就是code和數(shù)據(jù)同時運(yùn)行在RAM區(qū)里面。
至于為什么要刻意區(qū)分出這兩種調(diào)試方式,其實(shí)在低端MCU領(lǐng)域是沒有RAM調(diào)試這個概念的,其中很大一部分原因是它沒有足夠大的RAM空間在存放編譯后code代碼的同時仍然可以拿出額外的空間作為數(shù)據(jù)RAM的,而在高端MCU領(lǐng)域中,比如ARM,動輒幾十KB的RAM是很常見的,在不運(yùn)行超大工程的情況下是完全可以拿出一部分空間運(yùn)行代碼的,所以也就出現(xiàn)了RAM調(diào)試這種方法了。
相比于Flash調(diào)試,RAM調(diào)試則與生俱來的帶來兩個最大的先天優(yōu)勢,一個是RAM的可擦寫的次數(shù)理論上是無限的,在調(diào)試代碼的期間我們往往是需要不斷下載更新的,而Flash的擦寫次數(shù)是有限的(一般幾萬次、幾十萬次不等,雖然看起來足夠多,但是也心疼的慌),因此在調(diào)試期間我們可以選擇RAM調(diào)試;另一個方面,則更是RAM調(diào)試的強(qiáng)項(xiàng)(Flash真夠悲催的),在RAM區(qū)的代碼執(zhí)行速率和效率遠(yuǎn)高于需要不斷地讀寫Flash區(qū)代碼的,這點(diǎn)毋庸置疑,所以在當(dāng)今智能手機(jī)比拼硬件的時代,我們選擇一款強(qiáng)大的CPU是應(yīng)該的,但是要想讓系統(tǒng)運(yùn)行的更流暢,足夠大的機(jī)載RAM是必須的,呵呵。當(dāng)然RAM調(diào)試的缺點(diǎn)是掉電丟失,在RAM區(qū)運(yùn)行的代碼在掉電的情況下是不會被保存的,下次上電單片機(jī)仍然會執(zhí)行Flash區(qū)內(nèi)部的老的代碼,這點(diǎn)是需要注意的,很多人忘記考慮這點(diǎn),在RAM調(diào)試功能完畢,等拿到現(xiàn)場單片機(jī)獨(dú)立運(yùn)行的時候卻發(fā)現(xiàn)程序是不對的,咳咳,那當(dāng)然不對啦。。。
理論部分介紹完畢,下面我們結(jié)合IAR開發(fā)環(huán)境來分析一下怎么實(shí)現(xiàn)Flash調(diào)試和RAM調(diào)試的。其實(shí)我們仔細(xì)研究發(fā)現(xiàn),F(xiàn)lash調(diào)試和RAM調(diào)試在IAR下的區(qū)別只是.icf配置文件的不同罷了,其實(shí)很簡單很容易理解,也就是把單片機(jī)的內(nèi)存映射改變了,下面單拿出兩者不同的部分曬出來(重要部分加了注釋,供參考):
flash調(diào)試的256KB_Pflash.icf文件:
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;/* 中斷向量的起始地址為ROM的首地址 */
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x0;
define symbol __ICFEDIT_region_ROM_end__ = 0x00040000;/* 256k ROM空間 */
define symbol __ICFEDIT_region_RAM_start__ = 0x1fff8410;
define symbol __ICFEDIT_region_RAM_end__ = 0x20000000;
…
define exported symbol __VECTOR_TABLE = 0x00000000;/* 中斷向量表放在ROM區(qū)0起始地址 */
define exported symbol __VECTOR_RAM = 0x1fff8000;
…
define symbol __code_start__ = 0x00000410;/* 代碼開始區(qū)地址在ROM區(qū) */
…
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place at address mem:__code_start__ { readonly section .noinit };
place in ROM_region { readonly, block CodeRelocate}; /* 將只讀代碼放到ROM區(qū) */
place in RAM_region { readwrite, block CodeRelocateRam,
block CSTACK, block HEAP };
RAM調(diào)試的64k_ram.icf文件:
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x1fff8000;/* 中斷向量的起始地址為RAM的首地址 */
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x0;
define symbol __ICFEDIT_region_ROM_end__ = 0x0;/* 將ROM空間置0 */
define symbol __ICFEDIT_region_RAM_start__ = 0x1fff8000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20000000;
…
define exported symbol __VECTOR_TABLE = 0x1fff8000;/* 中斷向量表放在RAM區(qū)首地址 */
define exported symbol __VECTOR_RAM = 0x1fff8000;
…
define symbol __code_start__ = 0x1fff8410;/* 將代碼開始區(qū)地址在RAM區(qū) */
…
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place at address mem:__code_start__ { readonly section .noinit };
place in RAM_region { readonly, block CodeRelocate }; /* 將只讀代碼放到RAM區(qū) */
place in RAM_region { readwrite, block CodeRelocateRam,
block CSTACK, block HEAP };
上面的代碼我就不多做詳細(xì)解釋了,通過注釋和對比估計大多數(shù)博友應(yīng)該會理解了,不明白的地方歡迎下面留言共同探討,當(dāng)然,歡迎投票,呵呵。,轉(zhuǎn)載請注明出處和原作者jicheng0622信息,謝謝理解,再聊,未完待續(xù)~
|
|