搜索
bottom↓
回复: 5

flash和ram 中变量疑问

[复制链接]

出0入0汤圆

发表于 2012-7-18 10:17:57 | 显示全部楼层 |阅读模式
在gcc中,在flash中定义数组,依据这样的写法,const+类型+数组名[]+PROGMEM={};
在mdk中,我的理解,const+类型+数组名[]={};,在编译的时候就直接把这个数组存入到了flash中。在全局变量前加const修饰后,变量在编译时都自动地存入了flash中。首先,这个理解是否正确?
在这个前提下,gcc中,读取flash中的变量,需要调用avr/pgmspace.h中的库函数pgm_read_byte,pgm_read_word等,读取flash中的数据。
而在mdk中,我直接可以用一个const类型的指针把数组中的内容直接读取出来付给ram中的变量,而不需要调用这样的读取flash的函数。
以上两点理解是否正确?
那在mdk中,我定义这样的一个结构,结构中的成员都是const,按照上面的理解都是存在flash中。
struct AT_CMD_BODY{
        const char * const setcmdString;       
        const U8 user;       
        const char * const cmdreply;
        ERR_NUM (* const ProcCmd) (char ** argv,int argc);
};
然后定义两个这种结构体的全局变量,struct AT_CMD_BODY A和const struct AT_CMD_BODY B。
问题是,这两个变量A和B是存在flash中还是ram中?

出0入0汤圆

发表于 2012-7-18 15:21:18 | 显示全部楼层
要想将变量存入FLASH,在定义变量时必须要加上 PROGMEM ,并不是加上关键字const就存入FLASH中了。

出0入0汤圆

 楼主| 发表于 2012-7-18 15:51:02 | 显示全部楼层
richu 发表于 2012-7-18 15:21
要想将变量存入FLASH,在定义变量时必须要加上 PROGMEM ,并不是加上关键字const就存入FLASH中了。 ...

GCC编译器是这样的。MDK ARM没有这个字。

出0入0汤圆

发表于 2012-7-18 16:03:47 | 显示全部楼层
看看生成的代码就知道存哪儿了

出0入0汤圆

发表于 2013-4-5 11:00:01 | 显示全部楼层
vincent0319 发表于 2012-7-18 15:51
GCC编译器是这样的。MDK ARM没有这个字。

我看过存放地址
只要加const的变量都是从0x0800 0000开始
就是说已经放到FLASH区域
并没有擦洗的指令

问题
1.这样会不会造成数据出错
还是说MDK自动完成擦除任务

2.MCU的片上FLASH,一般存放什么数据
我把全局变量不加 const 他一样是存放在RAM中。

出0入0汤圆

发表于 2013-4-10 09:27:00 | 显示全部楼层
不同MCU的体系结构不同,数据存储格式会有区别。

在AVR GCC中,由于读取PROGMEM区域要使用LPM指令,
函数在实现的时候内嵌汇编完成操作,我们以pgm_read_word(address_short) 为例,
具体在pgm space.h中如此定义:

#define         pgm_read_word(address_short)   pgm_read_word_near(address_short)
#define         pgm_read_word_near(address_short)   __LPM_word((uint16_t)(address_short))

#define __LPM_word_enhanced__(addr)         \
(__extension__({                            \
    uint16_t __addr16 = (uint16_t)(addr);   \
    uint16_t __result;                      \
    __asm__                                 \
    (                                       \
        "lpm %A0, Z+"   "\n\t"              \
        "lpm %B0, Z"    "\n\t"              \
        : "=r" (__result), "=z" (__addr16)  \
        : "1" (__addr16)                    \
    );                                      \
    __result;                               \
}))

在单片机应用系统中,一般编译结果分段存储在FLASH中,
开机硬件会拷贝相应的代码段至RAM区,这就是所谓的全局变量。
因为单片机的FLASH支持按字节读取数据,为了节省RAM,常量尽量被写入FLASH区域。

Realview MDK 为ARM系列单片机开发平台,编译器不同,定义自然会有区别。

FLASH是按扇区擦除,可能会破坏其他数据,系统若支持IAP可以直接对FLASH区域编程,
存储固件的区域一般会被硬件保护。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-11 15:11

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表