Keil中使用arm section进行绝对地址定位并进行O2等级代码优化时报错: Error: L6982E

本文探讨了在O2优化等级下使用armsection指定数据存储位置时遇到的内存重叠错误,通过调整结构体的放置位置解决了问题,同时介绍了Keil中不同优化等级的特点。
  1. 当使用O0优化时,可以正常进行编译

 

2、当选择O2优化时,编译会报错

 3、在motor_id.c文件中,使用arm section来将数据指定到特定位置

#pragma arm section rwdata = ".ARM.__at_0x1100CE00"

 

Parameter1             _Parameter1 =

{

  ……

};

 

Parameter2             _Parameter2=

{

  ……

};

Parameter3             _Parameter3 =

{

  ……

};

 

Parameter4            _Parameter4=

{

  ……

};

#pragma arm section

程序原意是将_Parameter1、_Parameter2、_Parameter3、_Parameter4四个结构体中的数据都指定到0x1100CE00起始的位置,在O0优化等级下程序这样写没有问题,但在O2优化等级下程序会报错。

错误详细信息如下:

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce04 overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce13.

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce04 overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce0c.

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce04 overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce30.

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce04 overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce28.

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce04 overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce28.

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce13 overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce0c.

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce13 overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce30.

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce13 overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce28.

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce13 overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce28.

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce0c overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce30.

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce0c overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce28.

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce0c overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce28.

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce30 overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce28.

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce30 overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce28.

.\Objects\Test 9843_2QX.axf: Error: L6982E: AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce28 overlaps address range with AT section motor_id.o(.ARM.__at_0x1100CE00) with base 0x1100ce00 limit 0x1100ce28.

 

分析编译时的输出log,可以大概看出是几个结构体的位置分配发生错乱,如果想在O0优化等级下使用arm section将几个结构体指定到特定存储地址,需要将程序进行修改。

4、修改步骤3中的程序

#pragma arm section rwdata = ".ARM.__at_0x1100CE00"

 

Parameter1             _Parameter1 =

{

  ……

};

 

#pragma arm section

 

#pragma arm section rwdata = ".ARM.__at_0x1100CE04"  //04是_Parameter1结构体的大小

 

 

Parameter2             _Parameter2=

{

  ……

};

 

 

#pragma arm section

 

#pragma arm section rwdata = ".ARM.__at_0x1100CE08"  //08是_Parameter1 + _Parameter2结构体的大小

 

 

Parameter3             _Parameter3 =

{

  ……

};

 

#pragma arm section

 

#pragma arm section rwdata = ".ARM.__at_0x1100CE0C"  //0C是_Parameter1 + _Parameter2+ _Parameter3结构体的大小

 

 

Parameter4            _Parameter4=

{

  ……

};

#pragma arm section

 

此时再进行编译就会正常,而且程序大小也会变小。

 

5、Keil中几个代码优化等级的说明

Keil中代码优化等级主要有四个O0、O1、O2、O3,默认的优化等级为O2

O0:使用最低优化,多数优化都被关闭,生成的代码具有最多的调试信息。

O1:使用有限优化,未使用的内联函数、未使用的静态函数以及冗余代码

          都会被移除,指令会被重新排序以避免互锁的情况。生成的代码会被

          适度优化,并且比较适合调试。

O2:使用高度优化,根据处理器的特定行为优化程序代码,生成的代码为

         高度优化的,并且具有有限的调试信息。

O3:使用极端优化,根据时间/空间选项进行优化,默认为多文件编译,它

          可以提供最高等级的优化,但编译时间会稍微长些,软件调试信息也

          比较少。

一般情况下采用default即O2等级的代码优化即可,如果采用O1、O2,则代码空间会变大,但会多很多调试信息,而使用O3的话有时候会对代码业务逻辑产生影响,所以一般采用O2等级进行优化代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WangLanguager

您的鼓励是对我最大的支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值