找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 12714|回復(fù): 0
收起左側(cè)

淺談IAR環(huán)境下Flash調(diào)試和RAM調(diào)試的區(qū)別

[復(fù)制鏈接]
ID:82781 發(fā)表于 2015-6-24 17:06 | 顯示全部樓層 |閱讀模式
     最近一直埋頭于設(shè)計(jì)的撰寫當(dāng)中,成天大眼對(duì)小眼地面對(duì)著word、viso和知網(wǎng)客戶端等等文字編輯工具真是有種麻木的趕腳,不寫不知道,一寫嚇一跳,感覺(jué)讓我寫上幾萬(wàn)行代碼也比坐在電腦面前憋出幾萬(wàn)字論文來(lái)的輕巧,“問(wèn)君能有幾多愁,恰似一江春水向東流”,哎,突然間發(fā)現(xiàn),人生最最痛苦的不是人死了錢沒(méi)花了,而是寫了十幾天的論文才發(fā)現(xiàn),暈,還有一多半沒(méi)寫呢,不過(guò)木有辦法,只能硬著頭皮上了,再此之前還是更篇博客為好,不然該沉底落灰了(話說(shuō)貌似斷更了好長(zhǎng)時(shí)間了,不過(guò)幸好不是寫小說(shuō),不然該被拍磚了),哈哈~
            閑話少說(shuō),下面進(jìn)入正題。其實(shí)關(guān)于Flash調(diào)試和RAM調(diào)試的概念,我也是從調(diào)試Kinetis的時(shí)候才開(kāi)始接觸,最初只是隨便用用,沒(méi)有深究,之后用的多了才開(kāi)始深入研究?jī)烧咧g的區(qū)別,發(fā)現(xiàn)里面大有文章可作,這也是我為什么后來(lái)又把本文的前綴改成【原創(chuàng)精品】的緣故,翻看了網(wǎng)上的一些資料,大多是授人以魚的文章,所以覺(jué)著有必要在這里談?wù)勛约旱囊稽c(diǎn)看法,做個(gè)筆記:
        
        上圖為在IAR環(huán)境下的Flash調(diào)試界面和RAM調(diào)試界面
            首先說(shuō)說(shuō)什么是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ū)的同時(shí)再?gòu)腞AM區(qū)中額外開(kāi)辟出一段空間存放可執(zhí)行code,這樣就是code和數(shù)據(jù)同時(shí)運(yùn)行在RAM區(qū)里面。
            至于為什么要刻意區(qū)分出這兩種調(diào)試方式,其實(shí)在低端MCU領(lǐng)域是沒(méi)有RAM調(diào)試這個(gè)概念的,其中很大一部分原因是它沒(méi)有足夠大的RAM空間在存放編譯后code代碼的同時(shí)仍然可以拿出額外的空間作為數(shù)據(jù)RAM的,而在高端MCU領(lǐng)域中,比如ARM,動(dòng)輒幾十KB的RAM是很常見(jiàn)的,在不運(yùn)行超大工程的情況下是完全可以拿出一部分空間運(yùn)行代碼的,所以也就出現(xiàn)了RAM調(diào)試這種方法了。
            相比于Flash調(diào)試,RAM調(diào)試則與生俱來(lái)的帶來(lái)兩個(gè)最大的先天優(yōu)勢(shì),一個(gè)是RAM的可擦寫的次數(shù)理論上是無(wú)限的,在調(diào)試代碼的期間我們往往是需要不斷下載更新的,而Flash的擦寫次數(shù)是有限的(一般幾萬(wàn)次、幾十萬(wàn)次不等,雖然看起來(lái)足夠多,但是也心疼的慌),因此在調(diào)試期間我們可以選擇RAM調(diào)試;另一個(gè)方面,則更是RAM調(diào)試的強(qiáng)項(xiàng)(Flash真夠悲催的),在RAM區(qū)的代碼執(zhí)行速率和效率遠(yuǎn)高于需要不斷地讀寫Flash區(qū)代碼的,這點(diǎn)毋庸置疑,所以在當(dāng)今智能手機(jī)比拼硬件的時(shí)代,我們選擇一款強(qiáng)大的CPU是應(yīng)該的,但是要想讓系統(tǒng)運(yùn)行的更流暢,足夠大的機(jī)載RAM是必須的,呵呵。當(dāng)然RAM調(diào)試的缺點(diǎn)是掉電丟失,在RAM區(qū)運(yùn)行的代碼在掉電的情況下是不會(huì)被保存的,下次上電單片機(jī)仍然會(huì)執(zhí)行Flash區(qū)內(nèi)部的老的代碼,這點(diǎn)是需要注意的,很多人忘記考慮這點(diǎn),在RAM調(diào)試功能完畢,等拿到現(xiàn)場(chǎng)單片機(jī)獨(dú)立運(yùn)行的時(shí)候卻發(fā)現(xiàn)程序是不對(duì)的,咳咳,那當(dāng)然不對(duì)啦。。。
            理論部分介紹完畢,下面我們結(jié)合IAR開(kāi)發(fā)環(huán)境來(lái)分析一下怎么實(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í)很簡(jiǎn)單很容易理解,也就是把單片機(jī)的內(nèi)存映射改變了,下面單拿出兩者不同的部分曬出來(lá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;/* 代碼開(kāi)始區(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;/* 將代碼開(kāi)始區(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ì)解釋了,通過(guò)注釋和對(duì)比估計(jì)大多數(shù)博友應(yīng)該會(huì)理解了,不明白的地方歡迎下面留言共同探討,當(dāng)然,歡迎投票,呵呵。,轉(zhuǎn)載請(qǐng)注明出處和原作者jicheng0622信息,謝謝理解,再聊,未完待續(xù)~

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表