微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > ARM调试和Flash调试的区别

ARM调试和Flash调试的区别

时间:10-02 整理:3721RD 点击:

其实关于Flash调试和RAM调试的概念,我也是从调试Kinetis的时候才开始接触, 最初只是随便用用,没有深究,之后用的多了才开始深入研究两者之间的区别,发现里面大有文章可作,所以觉着有必要在这里谈谈自己的一点看法,做个笔记:



上图为在IAR环境下的Flash调试界面和RAM调试界面

    首先说说什么是Flash调试和RAM调试,Flash调试就是通常意义下的普通调试,即将编译链接之后的code下载到单片机的ROM区,数据放到RAM区,然后进行调试;而RAM调试则是将数据放到RAM区的同时再从RAM区中额外开辟出一段空间存放可执行code,这样就是code和数据同时运行在RAM区里面。

    至于为什么要刻意区分出这两种调试方式,其实在低端MCU领域是没有RAM调试这个概念的,其中很大一部分原因是它没有足够大的RAM空间在存放编译后code代码的同时仍然可以拿出额外的空间作为数据RAM的,而在高端MCU领域中,比如ARM,动辄几十KB的RAM是很常见的,在不运行超大工程的情况下是完全可以拿出一部分空间运行代码的,所以也就出现了RAM调试这种方法了。

    相比于Flash调试,RAM调试则与生俱来的带来两个最大的先天优势,一个是RAM的可擦写的次数理论上是无限的,在调试代码的期间我们往往是需要不断下载更新的,而Flash的擦写次数是有限的(一般几万次、几十万次不等,虽然看起来足够多,但是也心疼的慌),因此在调试期间我们可以选择RAM调试;另一个方面,则更是RAM调试的强项(Flash真够悲催的),在RAM区的代码执行速率和效率远高于需要不断地读写Flash区代码的,这点毋庸置疑,所以在当今智能手机比拼硬件的时代,我们选择一款强大的CPU是应该的,但是要想让系统运行的更流畅,足够大的机载RAM是必须的,呵呵。当然RAM调试的缺点是掉电丢失,在RAM区运行的代码在掉电的情况下是不会被保存的,下次上电单片机仍然会执行Flash区内部的老的代码,这点是需要注意的,很多人忘记考虑这点,在RAM调试功能完毕,等拿到现场单片机独立运行的时候却发现程序是不对的,咳咳,那当然不对啦。

    理论部分介绍完毕,下面我们结合IAR开发环境来分析一下怎么实现Flash调试和RAM调试的。其实我们仔细研究发现,Flash调试和RAM调试在IAR下的区别只是.icf配置文件的不同罢了,其实很简单很容易理解,也就是把单片机的内存映射改变了,下面单拿出两者不同的部分晒出来(重要部分加了注释,供参考):

flash调试的256KB_Pflash.icf文件:



  1. /*-Specials-*/<span style="font-family:宋体;mso-ascii-font-family:&quot;Times New Roman&quot;;mso-hansi-font-family:
  2. &quot;Times New Roman&quot;">转载请注明出处和原作者</span><span lang="EN-US">jicheng0622</span>

  3. define symbol __ICFEDIT_intvec_start__ = 0x00000000;/* 中断向量的起始地址为ROM的首地址 */

  4. /*-Memory Regions-*/

  5. define symbol __ICFEDIT_region_ROM_start__ = 0x0;

  6. define symbol __ICFEDIT_region_ROM_end__   = 0x00040000;/* 256k ROM空间 */

  7. define symbol __ICFEDIT_region_RAM_start__ = 0x1fff8410;

  8. define symbol __ICFEDIT_region_RAM_end__   = 0x20000000;







  9. define exported symbol __VECTOR_TABLE = 0x00000000;/* 中断向量表放在ROM区0起始地址 */

  10. define exported symbol __VECTOR_RAM = 0x1fff8000;







  11. define symbol __code_start__ = 0x00000410;/* 代码开始区地址在ROM区 */







  12. place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

  13. place at address mem:__code_start__ { readonly section .noinit };



  14. place in ROM_region   { readonly, block CodeRelocate}; /* 将只读代码放到ROM区 */



  15. place in RAM_region   { readwrite, block CodeRelocateRam,

  16.                         block CSTACK, block HEAP };



  17. RAM调试的64k_ram.icf文件:



  18. /*-Specials-*/

  19. define symbol __ICFEDIT_intvec_start__ = 0x1fff8000;/* 中断向量的起始地址为RAM的首地址 */

  20. /*-Memory Regions-*/

  21. define symbol __ICFEDIT_region_ROM_start__ = 0x0;

  22. define symbol __ICFEDIT_region_ROM_end__   = 0x0;/* 将ROM空间置0 */

  23. define symbol __ICFEDIT_region_RAM_start__ = 0x1fff8000;

  24. define symbol __ICFEDIT_region_RAM_end__   = 0x20000000;







  25. define exported symbol __VECTOR_TABLE = 0x1fff8000;/* 中断向量表放在RAM区首地址 */

  26. define exported symbol __VECTOR_RAM = 0x1fff8000;







  27. define symbol __code_start__ = 0x1fff8410;/* 将代码开始区地址在RAM区 */







  28. place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

  29. place at address mem:__code_start__ { readonly section .noinit };



  30. place in RAM_region   { readonly, block CodeRelocate }; /* 将只读代码放到RAM区 */



  31. place in RAM_region   { readwrite, block CodeRelocateRam,

  32.                         block CSTACK, block HEAP };

复制代码



上面的代码我就不多做详细解释了,通过注释和对比估计大多数博友应该会理解了,不明白的地方欢迎下面留言共同探讨,当然,欢迎投票,呵呵。


这个倒是知道

看到题目,瞬间震精了,还以为又出来一种什么高大上的单片机Flash呢。

看看,,,,,,,,,,,,,,,,

谢谢!

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top