在线时间1 小时
UID404875
注册时间2012-12-1
NXP金币0
该用户从未签到
注册会员

- 积分
- 155
- 最后登录
- 2020-12-15
|

楼主 |
发表于 2012-12-11 10:46:06
|
显示全部楼层
回复:C语言功底检测,看看这句话能否看懂?高手云集
回复第 18 楼 于2012-12-10 23:04:21发表:
回复第 16 楼 于2012-12-10 19:39:18发表:
回复第 14 楼 于2012-12-09 22:24:38发表:
回复第 13 楼 于2012-12-08 12:50:36发表:
回复第 12 楼 于2012-12-08 11:20:10发表:
回复第 11 楼 于2012-12-08 09:21:09发表:
回复第 10 楼 于2012-12-07 21:32:08发表:
回复第 9 楼 于2012-12-07 12:41:03发表:
回复第 6 楼 于2012-12-06 21:28:56发表:
回复第 5 楼 于2012-12-06 17:29:12发表:
回复第 4 楼 于2012-12-06 16:53:40发表:
嗯,lwn71说的对,我用的编译器链接文件格式是.lcf。由于我没有给FlashProgram_C分配在固定地址,所以他的起始地址由编译器自动给定。但是我若给这个数组分配在code flash的后段地址(即暂未用到的flash地址)的话,FlashProgram_C数组中初始化值将丢失,写入不了flash地址。lwn71有何解决方案吗?
我不太明白您这句话的意思“但是我若给这个数组分配在code flash的后段地址(即暂未用到的flash地址)的话,FlashProgram_C数组中初始化值将丢失,写入不了flash地址”。是指如果把数据分配在flash的后段地址,编译器不让您带初始化数据吗?那可能是编译器的问题了
如果只想把FlashProgram_C数组固定在code flash的某个地址,问题就简单了,而且有多种方法。一个办法就是用上边提到的const并给出具体地址, 如const unsigned long FlashProgram_C[size] @ 0x00005000。另外在.lcf里在MEMORY那段你要把code等等的地址范围和你的FlashProgram_C地址段错开,否则有些(版本的)编译器会把code覆盖到FlashProgram_C上,您就会看到象您说的初始化值丢失。
因为不知道您用那款芯片和那个编译器,我不确认我方法对您有效。
我用的是MPC5604P单片机,编译环境是Code Warrior2.10。我是通过在.lcf文件中给数组分段在Data Flash地址,然后用#pragma形式将数组放到该地址上,并附上了初始化数值。编译后,在internal_flash.map文件中看到该数组的起始地址就是我给定的data flash地址。但查看最终生成的文件(类似s19文件),发现并没有该数组。而且将程序载入单片机后,发现给定的data flash地址上的内容仍然是缺省值0xFFFFFFFF。我觉得这跟flash初始化配置没有关系,怀疑是否在.lcf文件中插入data flash段地址格式不对。我很困惑,希望大侠能给我一点帮助,感激不尽啊!
5604是款不错的芯片,明年的一个项目我正想用它,到时希望能向您请教。
根据对datasheet的学习和对类似芯片的经验,我觉得data flash不是这样用的。它就像没有data flash的单片机系统扩展的
一片EEPROM一样,主要用于系统在运行中存储设置参数,你在.lcf定义的所有东西不会进data flash,而是code flash. 所以你看到ff 在data flash是对的
就象我提的用类似const unsigned long FlashProgram_C[size] @ 0x00005000={ .........}不好使吗?记住在.lcf文件内把其它代码的地址和你要分配给FlashProgram_C的地址分开
大侠过奖了,我在这个问题上已经耽搁太长时间了。我之前也试过你说的方法,但是目前2.10编译环境还不支持“@”格式。我能想到的给数组固定地址的方法就是用#pragma了,也想过用宏定义结构体的方法,但都不好使。你有什么推荐的好方法吗?其实不管我把数组是否定义在data flash,只要是程序还没有覆盖的flash地址,我的数据都不能写进去。而且倘若我改动了程序主函数的入口地址的话,之前的函数功能都失效了。你知道这是怎么回事吗?
如果不支持@,试试这样行不行:
在.lcf内定义一段地址my_flash
在C代码内
#pragma define_section my_FlashProgram ".my_flash"
__declspec(my_FlashProgram) const long FlashProgram_C[size]={......}
改动了程序主函数的入口地址问题,你是什么改的?还要回去看看你的lcf文件怎么写的,任何与lcf不符的定义都有可能引起编译器出错
谢谢lwn71兄建议,主函数的入口地址应该是不能随意改动的,和flash操作没有关系。您说的分段,我也试了,但是我不知道"__declspec”和"define_section"是编译环境自带的字符还是您写的,我这上面不能直接用。我把我之前写的分段附下来,麻烦您帮我看下有无错误之处啊,真的很感谢您不厌其烦的给我指导,非常感谢:
.lcf文件部分分段:
MEMORY /*这里主要用来划分段*/
{
internal_flash: org = 0x00002000, len = 0x00070000 /*系统分配的内存段,org值就是主函数的入口地址*/
my_flash: org = 0x00072000, len = 0x0000E000 /*我自己分的段,前后值分别表示段起始地址和段长度,在code flash中*/
}
SECTIONS /*通过下面的段插入,后面才可以使用划分的段*/
{
GROUP:{ /*这段是系统生成的插入格式*/
.text : {}
............
}>internal_flash
GROUP : { /*这段是我自己写的插入格式*/
Rodata (CONST) : {
*(Rdata)
*(Rodata) }
} > my_flash
}
初始化定义数组:
#pragma push
#pragma section const_type ".Rodata"
const unsigned Flash_Program_C[10] =
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /*通过.map文件看到该数组起始地址为0x00072000,但调试时发现该地址内容仍为0xffffffff*/
}
#pragma pop
lwn71兄看看我这样写哪里出了问题?不好意思,多次打扰了。
这个问题说以来很简单,可能也很普遍:你要是查一下(编译器目录下的Help文件)你当前版本的是否支持你调用的预处理指令。(可能查了也没有用,Freescale的东西普遍都不错,但文档做的太差。文档与实物不相符的在产品初期不少见。)
回到你的具体问题,我不确认pragma section 和下一行是否在你的编译器上完全有效。我的机器上也没有你这个版本,没法帮你试了,对不起。
我用那个是Freescale推荐的,你可以看看应用文档AN4329第六页开始(4 Relocating Code in ROM......),链接在这里http://cache.freescale.com/files/soft_dev_tools/doc/app_note/AN4329.pdf
#pragma define_section 和 declspec 是很多CodeWarrior版本都支持的。declspec 最早好像是微软给C++扩展的,你检查一下你是否不小心把编译器C++选项给关掉了。另外__declspec那个"__" 是两个"_" ,没少打或多达一个吧?
嗯,lwn71兄说得完全正确,我也问了飞思卡尔官方技术人员,他们说我这个编译器默认不支持我那样的写法。而且我建立工程的时候的确也没有打开C++选项,接下来我再重新建立工程,试试您提供的方法。非常感谢lwn71兄不断提供帮助啊。无以言表的感谢......
|
|