OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2738|回复: 1

STM32F103_遇到怪事了!求助!我要疯了,搞不懂.hex和.bin的生成原理,详看下文

[复制链接]

2

主题

4

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2019-5-23
在线时间
5 小时
发表于 2019-7-12 22:20:48 | 显示全部楼层 |阅读模式
1金钱
芯片是STM32F103ZET6 ,开发环境:keil 5


首先:

我定义了两个指定位置的变量,一个指定在0x8024020,另一个指定在0x8024000
防止图看不见,我把设置变量的代码贴出来:

u16 aim __attribute__((at(0x8024020))) = 2088;

u16 gTEC3_ParamSave __attribute__((at(0x8024000))) =999; //const volatile


然后我用printf输出,语句是这样的:
printf("%x \r\n",*(u32 *)0X8024020);
printf("%x \r\n",*(u32 *)0x8024000);

然后程序下载,观察串口输出     输出是这样的:

文字描述:3e7
                 828
换算可知:0x3e7=999;
                 0x828=2088;
输出是没有问题的

接下来,修改这两个的初始值,重新下载看能否改写:

改写为:

u16 aim __attribute__((at(0x8024020))) = 1500;

u16 gTEC3_ParamSave __attribute__((at(0x8024000))) =777; //const volatile

同样用printf输出值

printf("%x \r\n",*(u32 *)0X8024020);
printf("%x \r\n",*(u32 *)0x8024000);

输出结果为:

文字描述:309
                 5dc
换算可知:0x309=777;
                 0x5dc=1500;

这两个地址里的值被成功改写

!!!!!看到这,是平淡无奇的,接下来就是怪事了,

F103ZET6片内FLASH有512K,地址0x8000000 - 0x8080000

现在,我改变其中一个的地址值,我把  0X8024020  改为  0X8074020,地址改写到很远的地方,但没有超出FLASH范围

同时把初始值改变,来观察值的改变效果

代码被改为这样:

u16 aim __attribute__((at(0x8074020))) = 2888;

u16 gTEC3_ParamSave __attribute__((at(0x8024000))) =566; //const volatile

还是用printf()输出,代码为:

printf("%x \r\n",*(u32 *)0X8074020);
printf("%x \r\n",*(u32 *)0x8024000);

观察输出结果:


文字描述:309
                 b48

换算出来:0x309=777;
                 0xb48=2888;

!!!!!强调看一下 0x309    这个数据,
在前面,我在改其中一个地址的同时,已经把他们两个都重新赋值,一个为2888 ,一个为566,
地址0X8074020 里面的值是被成功改写成了 2888 ,而0x8024000 里面的值依然是 上一个 777;


百思不得其解!!!

看一下生成的.hex文件
先看
u16 aim __attribute__((at(0x8024020))) = 2088;

u16 gTEC3_ParamSave __attribute__((at(0x8024000))) =999; //const volatile
先看这个的 .hex文件,
在生成的.hex文件中,可以找到:
:10400000E7030000000000000000000000000000C6
:1040200028080000410538A06D01083A0102211A54
为了不误导,没有对这两行做任何改动,
可以看到  : 4000 这个地址写着  E703 ,也就是 0x3E7,也就是 999
                    4020 这个地址写着  2808, 也就是0x828 ,也就是 2088

接下来看
u16 aim __attribute__((at(0x8024020))) = 1500;

u16 gTEC3_ParamSave __attribute__((at(0x8024000))) =777; //const volatile

这个的 .hex文件,
同样的地方可以看到:
:1040000009030000000000000000000000000000A4
:10402000DC050000410538A06D01083A0102211AA3

可以看到  : 4000 这个地址写着  0903 ,也就是 0x309,也就是 777
                    4020 这个地址写着  DC05, 也就是0x5DC ,也就是 1500

看到值是被成功改写的,

************************************************************************************


u16 aim __attribute__((at(0x8074020))) = 2888;

u16 gTEC3_ParamSave __attribute__((at(0x8024000))) =566; //const volatile

看一下这个的“异常的”.hex文件:


文字描述:
:10754000212808C0A80178FFFFFF081B0172011164
:0C755000600808DC111111214E00000041

:020000040807EB

:04402000480B000049
:040000050800A1311D
:00000001FF

在这个的.hex文件最后几行,看到0x08074020  的地址里放了一个 480B ,也就是0xb48,也就是 2888
但是   0x8024000  这个地址在哪呢?数据在哪呢?
看完整的.hex文件就可以看到  在0x0801???? 段 在 7550 这里就结束了,下面就直接跳到  0x0807???? 段 的4020 了,
中间并没有  关于0x08024000 的二进制段,


这里还有一个奇怪的事情:


u16 aim __attribute__((at(0x8024020))) = 2088;                                                           u16 aim __attribute__((at(0x8024020))) = 1500;
                                                                                                      和
u16 gTEC3_ParamSave __attribute__((at(0x8024000))) =999;                u16 gTEC3_ParamSave __attribute__((at(0x8024000))) =777;

小偏移量生成的.hex 文件中,可以看到  含有大量的 00 段,
3371行           :1072800000000000000000000000000000000000FE

6660行           :104000003602000000000000000000000000000078

基本都是 00  ,偶尔有几个其他地方定义的数,

*********************************************************************
但是,
u16 aim __attribute__((at(0x8074020))) = 2888;

u16 gTEC3_ParamSave __attribute__((at(0x8024000))) =566; //const volatile

他生成的.hex文件 就非常紧致,完全没大面积的 00  段

最后几行可以看到:



3415行      :10754000212808C0A80178FFFFFF081B0172011164
3416行      :0C755000600808DC111111214E00000041

3417行      :020000040807EB

3418行      :04402000480B000049
3419行      :040000050800A1311D
3420行      :00000001FF


这个.hex     我的理解是 :在3416行 代码段结束后 ,直接跳到0x8074020 定义了 我在那里设置的数,

那为什么小偏移量生成的 .hex  文件  就要在代码段结束后,到 我定义的放数据地址 之前 ,要用大量的 00 段 来填充呢?

而我这个大偏移量的地址 生成的文件这么紧致,没有用 00 段 一直填充到0x8074020,而是直接跳到0x8074020 定义了 我在那里设置的数,但是却没有实现 我在0x8024000 定义的数呢?

???????这是为什么????????????????????????


我猜想,可能就是我在程序中  在有了 0x8074020这样的大偏移地址,把 0x8024000 这段给折叠了,或者说 省略了,使我无法这样用这个地址,
我以为是 keil 优化的问题,但是default 到 Lv3  我都试过,没用的,有了大偏移量,小偏移地址的值就定义不了



******************************************************************************************


最后来看一下我生成 .bin 文件的奇怪现象:

首先是小偏移量生成的.bin文件,如下:

Program Size: Code=51760 RO-data=2120 RW-data=53220 ZI-data=46040  
这里看到代码段  Code=51760    50KB,  FLASH的数据段  RO-data=2120  这么大,  但是这个.bin文件却有 105KB大 ,应该都是用 00 段填充的

接下来看 大偏移量生成的.bin文件:
不是一个文件,是一个文件夹

里面是这样的:



这里可以说是两个.bin文件,而且没有后缀
一个名为   ER$$.ARM.__AT_0x08074020   ,一个名为  ER_IROM1

ER$$.ARM.__AT_0x08074020 这应该是我在 0x08074020 定义的 数据,

为什么.bin 文件 会这样生成???


*************************************************************************
最后的最后 ,说一下   
在我定义了   0x8074020  地址的数据后  ,在定义  0x8024000地址 的前面加上 const ,就可以把他编进 .hex文件

代码这样的:
u16 aim __attribute__((at(0x8074020))) = 2888;

const u16 gTEC3_ParamSave __attribute__((at(0x8024000))) =566; //const volatile

代码段到 0x8024000 之前 还是用大量 00 段 来填充的



为什么不能让 0x8024000 的地址定义 像 0x8074020 一样 ,直接跳过去呢?
******************************************************************************************************
再补充一些:


还有const  比起 直接 __attribute__((at(0x8024000)))  定义到 FLASH 中有什么更多的作用吗?加const  但不指定 位置的话,  系统自己找的位置是直接在 FLASH代码段后面  加个数据吗?


我想上面的情况(有大偏移量,就隐藏了小偏移量的位置)是 C的编译系统 设计不合理吗? 还是 keil优化的问题? 还是片内 FLASH 物理上的结构所使然?
const u16 aim __attribute__((at(0x8074020))) = 2888;

const u16 gTEC3_ParamSave __attribute__((at(0x8024000))) =566; //const volatile

这样子写,.hex 也不会用 00 段 一直填充到 0x8074020 地址前面 ,还是直接跳到 0x8074020 里面定义      **************这就更奇怪了!!!!!






**********************************************  猜想  ************************************************************
生成 .hex    .bin   文件的规则就是地址大范围跳,就直接跳过去定义,小范围跳就用 00 填充过去    ..................................这是什么逻辑?????


反正这也太底层了,没人能解答也不管了,向LINUX进发



004.JPG
003.JPG
002.JPG
001.JPG
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2019-7-13 02:37:56 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-11 11:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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