tomhe666 发表于 2014-4-18 14:04:04

求助: 请搞手指点,程序空间不够了, 这是否是IAR编译器的BUG?()

当我芯片选用 ATMEGA168PA时, iar(IAR EWAVR 5.51.0), 编译通过,在链接时出错, 提示空间不足,如下图所示


于是我把芯片选择了管脚兼容的328P, 这时编译通过了, 如下图


然后问题来了:
编译器提示用了9858个字节, 很明显这并没有超出168pa的FLASH空间大写, 最少还有7K可用的, 难道是编译器的BUG?

我重复了以下过程: 当我去掉以下函数后(该函数单独编译,显示300多字节), 即使我再申请一个3K的FLASH数组,也不会报错,真心不懂了,下面
就是这个个引起错误的函数
//==============================================================================
//获取星期序数
UINT8 GetGregorianWeekDay(const CALENDAR_DATE* gc)//UINT16 gc_year, UINT8 gc_month, UINT8 gc_day)
{
      static __flash UINT8 month_adj={0,6,2,2,5,0,3,5,1,4,6,2,4};

      INT16 Y,C,M,D;
      C = gc->year / 100;
        Y = gc->year % 100;   //gc_year -(gc_year/100)*100;
      M = month_adj;      
      D = gc->day;
      
      UINT8 w = ( (Y/4) + (Y%7) - (2*(C%4)) + M + D)%7;
      return w;
}

tomhe666 发表于 2014-4-18 14:59:54

换了最新的IAR EWAVR 6.30还是一样结果

xiaolaba 发表于 2014-4-18 15:14:24

到底是數組大了
還是程序大了 ?
看看你的LST

tomhe666 发表于 2014-4-18 15:32:41

本帖最后由 tomhe666 于 2014-4-18 15:36 编辑

从总数上看,程序空间是够的,我现在查到有一个函数编译后长度是769字节, 然后这个函数注释掉就可以, 还没搞清楚为什么, 似乎168PA没有长跳转指令?

修改: 刚才看了下, 168PA和328P的指令集是一样的,都有JMP 和 CALL指令, MEGA88PA这两条指令都无

gonboy 发表于 2014-4-19 09:33:48

static __flash UINT8 month_adj={0,6,2,2,5,0,3,5,1,4,6,2,4};

UINT8 GetGregorianWeekDay(const CALENDAR_DATE* gc)//UINT16 gc_year, UINT8 gc_month, UINT8 gc_day)
{
   
      INT16 Y,C,M,D;
      C = gc->year / 100;
      Y = gc->year % 100;   //gc_year -(gc_year/100)*100;
      M = month_adj;      
      D = gc->day;
      
      UINT8 w = ( (Y/4) + (Y%7) - (2*(C%4)) + M + D)%7;
      return w;
}

试下

tomhe666 发表于 2014-4-19 12:43:26

gonboy 发表于 2014-4-19 09:33
static __flash UINT8 month_adj={0,6,2,2,5,0,3,5,1,4,6,2,4};

UINT8 GetGregorianWeekDay(const CAL ...

和这个没有关系了,现在已经解决, 我不好说这是不是编译器的一个BUG, 出错的原因是因为我使用绝对定位的方式在0x1FFF处放置了一个FLASH变量:

__root __flash UINT8 OSCCAL_VALUE @ 0x1FFF = 0xFF;

这个变量用来给编程器放置RC校准值用的,因为最开始用的mega88PA,所以放在此位置,后来程序空间不够了,改成mega168PA,但是这个定位的位置忘了改了.
可能是某个函数比较长, 编译器链接时, 这个位置放不下这个长函数,然后报错了, 但是, 我的整个程序只有9K多的空间, 而mega168PA是16K, 所以事实上
从0x2000开始还有很多空间没用上, 而编译器给的提示来看,从0x2000-0x2FdF他作为保留空间, 而没有使用, 所以程序只有9K, 但却不能放在16K的空间里了
, 当换了328P编译后, 他又重新从0x4000处开始放置程序, 所以能编译通过.

所以现在有一个结论, 当你使用绝对定位在程序空间中某处放置一个变量时,IAR编译器有可能会把他附近的一片连续空间作为保留, 规则是什么,还没搞清规则律
, 有可能会导致大量空闲的程序空间不能使用, 而导致因空间不足而报错, 我这个程序实际上最后编完成只用了9958字节, 就是因为1FFF处有个变量而导致空间
不足报错. 事实上从0x2000开始还有约6000多字节未使用

gonboy 发表于 2014-4-21 13:51:15

这种问题,编译的时候。 编译结果会提示的。
一般会提示XX 被填充。

细心就可以发现。
页: [1]
查看完整版本: 求助: 请搞手指点,程序空间不够了, 这是否是IAR编译器的BUG?()