本帖最后由 zc123 于 2016-12-13 13:23 编辑
好久没看,帖子又被顶上来了,一年前因为积累知识的不足,虽然解释还算详细,但支撑点不足,且因为粗心对最末尾字段的解读有错,所以这里在详细说明下:
这是keil显示的代码统计
(图片详见附件一)
简单解释下, code:代码, RO-data:只读数据, RW-data: 初始化了的可读写数据 ZI-data:定义了但未初始化的可读写数据
理解的这点,在详细的看下方生成的.map文件, 就会发现KEIL中显示的是下图的Grand Totals/ELF Image Totals, 而实际存储在ROM中的数据并不包含ZI-Data(这也好理解,ZI-Data未初始化,对于MDK并不需要单独提供地址保存其初始化数据)
(图片详见附件二)
那么我之前的回答就有问题,.map文件中提供的信息才是正确的, ROM Totals不仅告诉了地址大小,还提供了数据在生成bin中的存储顺序。真实的结构是应该与上述保存一致code、RO-Data,(填充字节+attribute字段), RW-Data。
(图片详见附件三)
说了这么多,就是为了解释5楼的问题(为了方便查看改为16字节)_:
1. const u8 a[16] __attribute__((at(0x0800F000))) = {0x01, 0x10, 0x10, 0x01};
2. const u8 a[16] __attribute__((at(0x0800F000))) ; 语句1、2被定义为const类型的数据,即为RO-data,那么即便代码里没有初始化,也会被默认初始化为0, 所以一定会放在flash的指定字段(也就是attribute定义的地址中)。
这也是附件4在地址0x0800F000~0x0800F010处显示为0x01, 0x10, 0x10, 0x01, 0x00... 0x00而附件五为0x00......0x00原因
3. u8 a[16] __attribute__((at(0x0800F000))) = {0x01, 0x20, 0x10, 0x02}; 4. u8 a[16] __attribute__((at(0x0800F000))); 语句3可以看出变量a是RW-data, RW-data需要的初始化数据也是要写入flash的,因此也会在0x0800F000写下数据。至于清除flash地址及后续数据,相当于给所有RW-data都初始化为0xFF,出现hardfault也就正常了 语句4则是ZI-data, 而对于ROM中,ZI-data是没有初始化信息需要写入flash的,也就是 __attribute__((at(0x0800F000)))在这里没有意义,是无效语句,所以你清除并不影响。 这也是附件6在地址0x0800F000~0x0800F010处显示为0x01, 0x20, 0x10, 0x02, 0x00... 0x00, 而附件7中该语句并没有生效的原因。 |