[测评]ICC7.15 中关于const和__flash关键字的实际测试(已解决)
自从ICC V7被发现可以使用某著名的Loader破解工具一网打尽以来,不知不觉中ICC已经迎来了7.15版。从官方的改进日志中,我们发现,从稳定的7.13A到7.15,ICC着重增加了对 64bits的double型数据类型的支持,增加并修订了针对8位操作的优化选项……总之,小打小闹不断。可惜自从7.14以来,不知道是什么原因,Loader破解的版本总会随机的自动关闭,让我一直心有余悸——万一哪天写代码时突然遭闪机……岂不是欲哭无泪?所以,不急于吃螃蟹的人,我还是推荐大家留着宝贵的7.13A,毕竟稳定才是硬道理。
在7.14的某个亚版中,开始将const关键字和flash关键字的概念进行分离——总的来说就是试图还const以ANSI-C所定义的本来面貌,这对ICC的用户来说,是一个不小的改动。官方声称,通过option中增加的一个选项'Treat 'const' as '__flash'来实现向下兼容。本以为这是一个体贴的设计,无奈,兼容毕竟不是等同,笔者进行测试时就碰了一鼻子灰。
首先,建立两个文件。Example.c和Example.h
在Example.c中加入
const unsigned char g_chArray;
const unsigned int g_wArraySize = sizeof(g_chArray) / sizeof(g_chArray);
在Example.h中加入
extern const unsigned char g_chArray[];
extern const unsigned intg_wArraySize;
当其他.c文件饱含Example.h进行编译时,7.13A可以正常通过。7.15种,如果没有选择 Treat 'const' as '__flash'如果没有出现SRAM 'Data'区溢出,则通常能正常通过(这是当然的,因为此时,数组合变量其实都占用着SRAM空间),如果选择了Treat 'const' as '__flash' 噩梦从此开始。
无论如何,系统总是会爆出如下的错误:
const object 'g_wArraySize' has no initialized value
怪异吧?似乎是extern对__flash关键字修饰的变量不起作用?
为了验证自己的想法,修改程序如下:
1、首先去掉Treat 'const' as '__flash'选项前面的勾勾。
2、修改程序为:
Example.c
--------------------------------------
__flash unsigned char g_chArray;
const unsigned int g_wArraySize = sizeof(g_chArray) / sizeof(g_chArray);
Example.h
--------------------------------------
extern __flash unsigned char g_chArray[];
extern const unsigned intg_wArraySize;
问题总算是被蒙混过去了。可是,我们牺牲了一个SRAM空间来保存const型变量……真是不爽阿……
extern 看来对 __flash型变量真的 不买账……期待官方的进一步改进。
无责任测评结束^_^ 辛苦了 看来还是IAR才是王道哈
AVR GCC貌似都不支持ANSI C的标准const??? 请【2楼】 dvhome从ISO C89/99标准中找出有说const必须保存在ram或rom里的规范定义说明。
论坛里就有C99的英文版标准文档。
而且C89/99标准里根本就没有像flash作用的关键词,所以各种编译器才用自己的方法来定义关键词或属性。 看来还是IAR才是王道哈
但是IAR的指针有时候也头大啊,分得太细了~!!!! 7.14C版的那个Loader破解不会自动关闭,并且可以用7.15版,也不自动关闭
傻孩子:我的7.15就老是自动关闭……不知道是什么原因……哪位大虾明示? to 3 楼:
const 修饰的必须是一个变量吧?至于这个变量是存在哪里,那就要看编译器怎么解释了
一个变量,使用了const修饰,而没有其他的关键字修饰的话,那按照C的标准,这个变量就必须是存在RAM里面的,如下:
const unsigned char i;
unsigned char * p;
p = &i;
i = 3; //不合法
*p = 3; //合法
至于,为什么C89/99标准里没有像flash作用的关键词,那是因为C89/99不是为嵌入式,不是为单片机而做的标准,它是一个编程语言的标准,那就肯定不会去理会你具体是用什么样的存储介质了,这个是编译器的事情
一家之言,欢迎拍砖,呵呵…… 再问 3楼 以及与3楼同样观点的朋友:
如果认为const与flash关键字是一样的,那么编译器如何实现以下语句:
unsigned char b;
void test(const unsigned char i)
{
......
}
调用
test(b);
请问,上面的调用正确吗?? 论坛里有c99标准文档的。无论是否是const变量,c99标准都没规定它存在ram里还是rom里。
c99规范只是规范了编译的标准,而非链接的标准。
也就是说,我完全可以定义一个普通变量,但是却在链接时把它定位于rom中(虽然如果运行时对它的写入操作是不正确的)。c99标准的编译器不会拒绝对这样的代码的编译(因为变量存储的实际地址分配不是它的职责)。
flash之类的关键词只是告诉编译器应该把变量分配到目标文件中的哪个段,并使用特殊的汇编语句,但是该段应当存储在哪里是链接器的事。
const和flash是完全不同的2个关键词,const是标准中定义的,主要限定作用在于不应当作为左值。而flash由于是非标准的,其解释完全由不同的编译器决定。所以icc开始区分这2个关键词。而gcc则是利用变量属性实现flash关键词。
楼上的调用,语法是正确的,因为参数是作为右值传递。
比如一些arm芯片同样有flash,但其总线是统一编址的,指令集也是统一的,arm没有定义特殊的汇编指令去读写rom(读一般和ram操作一样)。这样,如果有flash关键词的话,只是针对某些具体的芯片,一般也仅起到让编译器分配到某个段中的作用了。
如果没有flash关键词,也没有变量属性,也不意味着变量只能存放在某个特定的存储空间里。因为还有链接器(或者应该说,这正是它的职责)。 我没有说const一定是存在ROM里面哦
请仔细看我发的帖子
但是如果是没有经过其他关键字修饰,只使用了const关键字修饰的变量,按照C标准,是不是应该存在RAM里面呢?如果不是,那么我在7楼的问题应该怎么解释呢? 我的意见就是,c标准没有规定const限定的变量应当存放在哪里,所以编译器把const限定的变量输出到哪个段里不影响其是否符合c标准。
只是因为像avr这样的架构、汇编指令编译上的要求,才使得编译器要用某种方式去区分变量的读取方式。 傻孩子:看热闹!嘿嘿 10楼
那我们的意见其实是一样的了,哈哈…… 看6楼:
“const 修饰的必须是一个变量吧?至于这个变量是存在哪里,那就要看编译器怎么解释了 ”
我为什么说ICC的不标准呢?是因为const在C标准里面是没有限定变量存储位置的,它是一个C标准里面已经存在的关键字,而老版本的ICC把它拿来重新定义了,使得const定义的必须在Flash里面,这样我觉得不好,比如我在7楼提出的问题,就无法解决了(或者是ICC提供另外的解决办法?我没有怎么使用过ICC,也许是我不知道哈) 简单的说就是,以前版本的icc把const限定词作为与链接过程有关联的关键词(而不是仅仅作为一个编译用关键词),而现在则不再使用这种关联了。 在最新的ICC7.16版本中,针对以上BUG专门作了修正,可以高枕无忧了。哈哈。
CHANGE LOGS:
V7.16 - Feb 11th, 2008
IDE
- Added capability to create Library projects.
- the AppBuilder generated incorrect register names for the M324P
UART0 init function
- Added entries for PWM216 and PWM316
Compiler
- 7.15 incorrectly gives error on
extern __flash <object>;
without initialization.
- __flash const ....;
was causing an assertion error from the compiler
Header File
- Added iccioavr.h. You may #include this and it will #include the
correct device specific AVR header file based on the device you
selected in the IDE.
大家注意这里:
- 7.15 incorrectly gives error on
extern __flash <object>;
without initialization.
- 7.15 未能正确的给与
extern __flash <objext>;
初始化。
注意到
Header File
- Added iccioavr.h. You may #include this and it will #include the
correct device specific AVR header file based on the device you
selected in the IDE.
我们以后可以不用为每一个不同的器件使用不同的头文件了。
例如:
# include <iom8v.h>
以后只要写成
# include <iccioavr.h>
就可以了,很方便哈。 icc7.14c的破解能用于ICC7.16的 最新的破解 iccv7ProLoader.exe 版本已经到了1.0.1.0,据说彻底解决了从7.14引入的软件逻辑炸_弹(也就是4分钟自动关闭)。
今天才知道……汗一个,这下可以安心使用7.16了。 在7.14C以前的版本编译通过的工程,在7.15或7.16里怎么出错了? 如果你使用工程编译的,可以尝试用Shift + F9开重新编译。
如果还不能解决问题,可以把出错代码粘贴过来,我们一起分析一下。 1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_214095.jpg
用7.14C编译通过,用7。16就出现以上错误 在7.16新開一個 project試試,我從 7.15轉 7.16也是要這樣做. 按20楼朋友的方法试了下,也不行。 你这个问题好像是const导致的。7.16里面const型的变量也是放在SRAM中的,你需要在Option选项卡里面
选择 Treat 'const' as '__flash' 你这个问题好像是const导致的。7.16里面const型的变量也是放在SRAM中的,你需要在Option选项卡里面
选择 Treat 'const' as '__flash'
试了下:OK 编译通过
谢谢傻孩子 请问傻孩子 :
ICC7.16那里有下的??
能不能贴个链接啊! http://www.imagecraft.com/pub/iccv7avr_demo.exe 呵呵.....太精采了 哪里可以找到iccv7ProLoader.exe 版本1.0.1.0这个东东?
傻孩子:你可以到这里看看http://bbs.mcu123.net/bbs/dispbbs_14_52695_8215_skin0_1_1.html icc7.16a 那里有注册机下载????
傻孩子:没有听说过注册机,只有内存补丁好像…… 那个内存补丁下了解压不出来啊!! 把杀毒软件关掉…… 我来说几句,对于LS说的const和__flash,我有点不太赞同,我曾做过这样一个试验,大家可以去试一下。我用的是M16,ICCAVR编译器,用const来定义一个比较大的数组,大小超过SRAM,而在很多书中都说const是把定义的常量放在flash中,这点不假,当去编译时却通不过,出现的问题见19楼,当改成__flash后编译通过,运行正常。同样的程序,拿到GCC去编译时却没有错,当我用AVR Studio来仿真时发现了问题的所在。用const去修饰时,数组的确是存储在了flash中,但是,在调用时,却把整个数组全部调到了SRAM中,这样就会导到溢出,也就是ICC为什么编译不通过的原因,而用__flash去修饰时,并没有把数组调到SRAM中,所以运行正常。对于这个问题大家可以去验证,当然还有一个办法可以解决,就是在定义时用绝对地址的办法把数组放到一个固定地址存放。
欢迎拍砖!! to 【31楼】 jiben042
我不明白楼上具体对我的哪些说法有不同观点……请明示?
ICC不同版本处理不同,请您能先说明您测试的版本号么?还有你注意到Treat const as __flash的选项了么?
在ICC的帮助文档中,明确说明了__flash关键字修饰的变量会放在FLASH空间中,并且不会拷贝到RAM中。
GCC和ICC处理FLASH数据的方法是不同的,ICC中存放在flash里面的数据可以直接访问,而GCC却需要专门的库
函数才能读取。
ICC7.16以上版本,const在默认情况下,其修饰的“变量”仍然是存放在RAM中的。但是const修饰的变量必须
有初值,而这一初值必然存放在FLASH中,当程序启动时,startup代码会自动从FLASH中读取初值存储到对应
的RAM地址。所有全局变量和静态局部变量的初始化都是采用同样的过程:即数据在FLASH中保存,而startup
负责在初始化时将数据从FLASH中拷贝到对应的地址。所谓的.data段保存的就是这些全局变量和静态局部变量
而.bss段保留的就是那些没有初始值的全局变量或者静态局部变量。 呵呵,我在PIC24中也遇到了个类似的问题。 谢谢这个话题,,Treat const as __flash打上钩后可以用了,,常量数组被分配到FLASH ROM里面了,没有溢出 谢谢LZ的评测,7.22中也是要打钩后,编译不报area data not large enough的错误啦 我也来看热闹 在IAR中,对CONST 和__FLASH的定义早有分明,ICC到现在才想起来。
看来IAR确是王道。 mark 从大虾们激烈的讨论中,学到了很多东西!希望能看到更多这么精彩的辩论!
页:
[1]