打印
[技术问答]

M051芯片使用分散加载后全局变量异常,如何解决

[复制链接]
993|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Hyman2017|  楼主 | 2017-3-4 10:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
M051芯片添加了scatter文件,进行分散加载。分散加载前全局变量的值还是正常的,只要添加这个文件全局变量值都是乱的。这是什么原因?麻烦有牛人帮忙解决一下,多谢!

加载文件如下:
/* 说明SRAM的基地址和SIZE ,并且将RW和ZI Data放到.SRAM中*/
RAM1 0x20000000 0x1000  {    ; load region size_region  
RW_IRAM1 +0  {  ; RW data
.ANY (+RW +ZI)
}
}

/* 说明应用程序基地址,也就是向量表RESET段的地址,如果不是0x00000000 ,例如:是0x1000,这里就填0x1000 */
ROM1 0x00000000
{
    IROM1 +0 {  ; load address = execution address
           *.o (RESET, +First)
           __main.o(+R0); cope code
           *(Region$$Table);RO/RO
           *(ZISection$$Table); ZI addresses to zero
                   *(InRoot$$Sections);
        }

}
/* 其它程序都放到0x1200后面 */
FLASH1 0x00000200
{
        FLASH1 0x00000200
      {               
                 .ANY (+RO)       
      }   
}
沙发
Hyman2017|  楼主 | 2017-3-4 21:14 | 只看该作者
???

使用特权

评论回复
板凳
玛尼玛尼哄| | 2017-3-8 20:43 | 只看该作者
一个映像文件里可以包含多个域(region),它们在装载和运行时可以有不同的地址。这个地址可以用armlink的两个参数来确定:
ro-base 设置代码段(RO)在装载域(load view)和运行域(execution view)里的地址。
rw-base 设置数据段(RW)在运行域里的地址。
实际上,当域的内存映射关系比较简单时,可以使用这两个参数,但它们不能处理更为复杂的内存映射(memeory map),在这种情况下,就要用分散装载(scatter loading)技术。
分散装载技术可以把应用程序分割成多个RO域和RW域,并且给它们指定不同的地址。这在嵌入式的实际应用中,有很大好处。在一个嵌入式系统中,Flash16RAM32RAM都可能存在于系统中,所以,将不同功能的代码定位在特定的位置大大地提高系统的效率。下面是最为常用的两种情况:
第一种情况:32位的RAM速度最快,那么就把中断程序作为一单独的运行域,放在32位的RAM中,使它的响应时间缩到最短,这在startup_M051.s文件中有体现。
第二种情况:将启动代码(bootloader)以外的所有代码都复制到RAM中运行。
那么,分散装载是如何实现的呢?它通过一个文本文件作为armlink的参数来实现,文件里描述了分散装载需要的两个信息。
① 如何分散,就是输入段如何组成输出段和域:分组信息
② 如何装载,就是装载域和每个运行域的地址是多少:定位信息

19.6.1 scatter文件简介
Scatter文件是一个文本文件,它描述了装载域和运行域的基本属性。

一、对装载域的描述

scatter文件里,描述了装载域的名字、起始地址、最大尺寸、属性和运行域集合。其中最大尺寸和属性是可选的。如下例M051Simple.scf所示:

程序清单19.6-1 M051Simple.scf装载域
LR_IROM1 0x00000000  
{   
  ER_IROM1 0x00000000   
  {  
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }

  RW_IRAM1 0x20000000   
  {  
   .ANY (+RW +ZI)
  }
}

在上面的scatter文件里,装载域的名字为LR_IROM1,起始地址为0x00000000,包含两个运行域:ER_IROM1RW_IRAM1。编写好这个scatter文件后,就可以作为armlink的参数来使用它。

二、对运行域的描述
scatter里,描述了运行域的名字、起始地址、最大尺寸、属性和输入段的集合,如下例所示:

程序清单19.6-2 M051Simple.scf运行域
LR_IROM1 0x00000000 0x2000  
{   
  ER_IROM1 0x00000000 0x2000  
  {  
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }

  RW_IRAM1 0x20000000 0x1000  
  {  
   .ANY (+RW +ZI)
  }

FLASH1 0x800 0x1F0
{
    FLASH1 +0
    {
         Led1Ctrl.o
    }
}

FLASH2 0x1000 0xFF0
{
    FLASH2 +0
    {
         Led7Ctrl.o
    }
}
}

在这个文件里描述了两个运行域,分别为FLASH1 FLASH2FLASH1的起始地址为0x800,长度为0x1F0Led1Ctrl.o里的所有代码和只读数据都放在这个运行域里,FLASH2亦然。

三、对输入段的描述
scatter文件里,描述了输入段的模块名字(比如目标文件名)和输入段的属性(RORWZI等)。比如:uart.o+ZI),其中,uart.o为模块名;+ZI为输入段的属性。模块名字可以用通配符号,比如:*“*+RO+RW+ZI表示所有的代码和数据段。


………………………………………………

书籍下载地址(复制到下载工具进行下载):



使用特权

评论回复
地板
玛尼玛尼哄| | 2017-3-8 20:43 | 只看该作者
我觉得按照上面温老师的方法应该就可以了。

使用特权

评论回复
5
wahahaheihei| | 2017-3-11 22:56 | 只看该作者
没用过这个功能,这个功能可以实现什么呢?不都是按照系统默认的吗

使用特权

评论回复
6
heisexingqisi| | 2017-3-12 23:57 | 只看该作者
从来没搞过这个,见过不少人修改这个文件,那么这个文件修改后可以实现什么特别的功能吗

使用特权

评论回复
7
dongnanxibei| | 2017-3-13 09:44 | 只看该作者
是否你配置的这个跟实际的内存分布不对应?

使用特权

评论回复
8
稳稳の幸福| | 2017-3-13 22:34 | 只看该作者
搞好了没,我们做的时候没动过这个地方。。

使用特权

评论回复
9
huangcunxiake| | 2017-3-14 19:11 | 只看该作者
10
598330983| | 2017-3-14 20:36 | 只看该作者
如果默认可以完成就行了,这个比较复杂。

使用特权

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

本版积分规则

2

主题

6

帖子

0

粉丝