- 当使用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等级进行优化代码。