发新帖我要提问
12
返回列表
打印
[C语言]

“u8 buf[200]={0};”为什么会使.bin文件由7k变成8M?

[复制链接]
楼主: feilusia
手机看帖
扫描二维码
随时随地手机跟帖
21
john_lee| | 2014-10-23 11:01 | 只看该作者 回帖奖励 |倒序浏览
很像 GNU ld script,如果就是的话,那么文件中有几处不正确的地方:
1、        Startup.c                (.text)
              Core_Entry.c        (.text)
这种语法是输出“指定的文件”中的 .text 段,你指定的都是 .c 文件,这是不正确的,链接器的输入文件都是目标文件 *.o 或 *.a,而 C 文件是给编译器的,链接器是不接受的。

2、.data 段的输出描述,语法是:
section [address] [(type)] :
[AT(lma)]
[ALIGN(section_align)]
[SUBALIGN(subsection_align)]
[constraint]
{
output-section-command
output-section-command
...
} [>region] [AT>lma_region] [:phdr :phdr ...] [=fillexp]
你的.data 段描述,缺少了 AT 属性的定义,根据你文件中的上下文情况,应该这样修改:
  .data : AT(ADDR(.main_application) + SIZEOF(.main_application))
   {
            . = ALIGN(0x4);
           ....

你先试试,如果还有问题再来继续。

使用特权

评论回复
22
Mcuzone_xyz| | 2014-10-23 13:42 | 只看该作者
声明、定义、赋值,绕不过的坎啊

使用特权

评论回复
23
feilusia|  楼主 | 2014-10-23 15:52 | 只看该作者
john_lee 发表于 2014-10-23 11:01
很像 GNU ld script,如果就是的话,那么文件中有几处不正确的地方:
1、        Startup.c                ...

第一点暂时没改,因为我看厂家给的程序是这么写的,暂时先不管它。
按照你说的第二点,改成“.data:AT(ADDR(.main_application) + SIZEOF(.main_application))”,编译出来的就是8K,没有这句就是8M。
这是什么情况?看不懂……
这句的意思是把.data段分配在应用空间?应用空间不是存储代码吗。

使用特权

评论回复
24
feilusia|  楼主 | 2014-10-23 16:00 | 只看该作者
Mcuzone_xyz 发表于 2014-10-23 13:42
声明、定义、赋值,绕不过的坎啊

以前没绕过,现在正在努力绕

使用特权

评论回复
25
john_lee| | 2014-10-23 18:04 | 只看该作者
你先要了解两个基本术语:LMA 和 VMA,详解LMA(装载内存地址)与VMA(虚拟内存地址)
AT 的作用就是定义该段(你的.data)的 LMA,而后面的 > region(就是你文件中的 >DATA)则是输出到 DATA 区并计算其 VMA。
需要注意一点:.data 虽然有了 LMA,但把数据从 LMA 复制到 VMA 的过程,是由“启动代码”来实现的,如果启动代码中没有这个复制的操作,.data (全局变量)仍然不会被初始化。

使用特权

评论回复
26
feilusia|  楼主 | 2014-10-24 10:37 | 只看该作者
john_lee 发表于 2014-10-23 18:04
你先要了解两个基本术语:LMA 和 VMA,详解LMA(装载内存地址)与VMA(虚拟内存地址)
AT 的作用就是定义该段( ...

多看了几遍思考很久才回复,回复的慢了,不好意思。

你说“.data:AT(ADDR(.main_application) + SIZEOF(.main_application))”这样是在设置LMA,
那“DATA (RW)  : ORIGIN = 0x0080C000,     LENGTH = 0x00000000 ”这一句又是在做什么呢?
0x00800000以后的一段空间是RAM,在这里不就是把DATA段直接放在内存里了吗,似乎跟你那句是等效的在设置LMA。


使用特权

评论回复
27
john_lee| | 2014-10-24 14:21 | 只看该作者
DATA (RW)  : ORIGIN = ....,     LENGTH = .... 是定义memory area,但你给出 LENGTH 为 0 是不正确的。

memory area 是各个 section 的输出空间,其中的地址就是 VMA,比如你的 map 文件中这一行:
0080C000 000000C8 .data     g_spi1_buf   (Global_Var.c)
指明了 g_spi1_buf 的 VMA 为 0080C000,长度为 000000C8,段名是 .data。

虽然说是“直接放在了内存里”,但由于你的 VMA 是位于 RAM,即使能把 bin 内容写到芯片里,当 VMA 断电后,内容也会全部丢失,所以这种直接写 VMA 的方法基本没有意义。

通常的正确的方法都是在 ROM (LMA)中存放一个 .data 的初始映像,在上电或复位时,由启动代码把该映像从 LMA 复制到 VMA 完成初始化。AT 的作用就是生成这个 .data 的映像,位于 .main_application 之后,可用 LOADADDR(.data) 求出其 LMA 以供启动代码使用,你可以把新的 map 中的 .data 输出信息贴出来看看,应该可以看到与以前不同的信息。

另,看情况我估计你的启动代码里很可能没有这个复制(LMA to VMA)的操作。

使用特权

评论回复
28
feilusia|  楼主 | 2014-10-24 16:01 | 只看该作者
john_lee 发表于 2014-10-24 14:21
DATA (RW)  : ORIGIN = ....,     LENGTH = .... 是定义memory area,但你给出 LENGTH 为 0 是不正确的。

...

是的,启动代码里没有复制LMA到VMA的过程。
但是这个步骤似乎也不是必要步骤,因为我的TEST等段也没有做放到内存里去运行,说明这块芯片的flash应该是支持读写。
于是我试了试把BSS段和DATA段放在flash里,编译出来也是正常的8K。
    GLOBAL_BSS                   (RW)  : ORIGIN = AFTER(TEXT),         LENGTH = 0x00001000
    DATA                           (RW)  : ORIGIN = AFTER(GLOBAL_BSS),         LENGTH = 0x00001000
    BSS                           (RW)  : ORIGIN = AFTER(DATA),         LENGTH = 0x00001000

把DATA段虚拟到内存里和直接放在flash的区别,应该就是放在内存里的数组初始值会掉电清零、而flash里的数组初始值不会掉电清零。
不知道我这样理解的对不对?

使用特权

评论回复
29
john_lee| | 2014-10-24 16:21 | 只看该作者
你把DATA和 bss放进flash,那么其中的“变量”,实际上就变成“只读”了。而且,我不知道你的stack定位在哪个地方,如果stack在DATA或bss中,那你自己想想会发生什么。

使用特权

评论回复
30
feilusia|  楼主 | 2014-10-24 17:05 | 只看该作者
john_lee 发表于 2014-10-24 16:21
你把DATA和 bss放进flash,那么其中的“变量”,实际上就变成“只读”了。而且,我不知道你的stack定位在哪 ...

你说的对,我忘了flash要写的话还得先擦除,确实变成“只读”了……
在链接文件里设置了堆在内存里,倒是不会跟BSS或DATA起冲突。
__stack_begin   = 0x00805ff8;
而内存范围是0x800000~0x805fff.
我感觉我快明白了,但是还有一个问题= =……

你之前写的.data:AT(ADDR(.main_application) + SIZEOF(.main_application))中的“.main_application”又是哪里来的?我百度搜到别人有用“.main_application_data”,但是我一用就报错。
如果我bss段也要定义一个LMS,该用什么地址呢?

使用特权

评论回复
31
john_lee| | 2014-10-24 17:13 | 只看该作者
.main_application 是你的 lcf 文件中的啊(我说了是根据你文件内容的上下文修改的),那是 flash 中的最后一个段了(一般都把 LMA 定义在 flash 中最后一个段的末尾 )。

bss 不用 load(只需要清 0),所以不需要定义 LMA。

使用特权

评论回复
32
feilusia|  楼主 | 2014-10-24 19:26 | 只看该作者
john_lee 发表于 2014-10-24 17:13
.main_application 是你的 lcf 文件中的啊(我说了是根据你文件内容的上下文修改的),那是 flash 中的最后 ...

没注意到.main_application是我的段名……
我明白了。只是放在flash中,我启动代码里没有搬移LMA到VMA的代码,所以初始化数组仍然会有问题。
想要初始化个数组还真不容易。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则