ba_wang_mao 发表于 2009-4-28 12:02:42

请教傻孩子大侠:从ICC7.14升级到ICC7.19,从ROM的结构体中取数错误的问题

在ICC7.14下程序运行正常。但是用ICC7.19后,程序运行不正常。

    现象为:从ROM的结构体中取出的“数据”是乱的。

(1)、以下是定义了一个结构体,保存默认参数到ROM中(用于键盘设定)。

typedef struct tagFORMAT_STRUCT
{
        INT8U Name;          // 参数名称
        INT8U Decimal;          // 参数的格式(小数点位置)
        INT16S Min;             // 参数的最小值
        INT16S Max;             // 参数的最大值
        INT16S Default;         // 参数的默认值
} FORMAT_STRUCT , *FORMAT_STRUCT_PTR;

(2)、以下是结构体初始化部分

flash FORMAT_STRUCT DEFAULT_BUFFER = {
        { {0x00,0x00,0x39,0x38,0x7A}, 0x10 ,   0 ,   9999 ,   0},
        { {0x00,0x00,0x00,0x00,0x73}, 0x13 ,   0 ,   9999 ,   500},
        { {0x00,0x00,0x00,0x00,0x30}, 0x13 ,   0 ,   9999 ,    10},       
        { {0x00,0x00,0x00,0x00,0x5E}, 0x13 ,   0 ,   9999 ,   0},
        { {0x00,0x5C,0x7C,0x31,0x06}, 0x00 ,   0 ,15000 ,   0},
        { {0x00,0x00,0x6D,0x38,0x6D}, 0x10 ,   100 ,   2000 ,   240},
        { {0x00,0x5C,0x7C,0x31,0x5B}, 0x11 ,   0 ,   1000 ,   0},
        { {0x00,0x00,0x6D,0x38,0x7D}, 0x40 ,   1 ,      9 ,   7},
        { {0x00,0x00,0x6D,0x38,0x07}, 0x10 ,   100 ,   2000 ,   240},};


(3)、以下是从ROM结构体中取出当前键盘设定参数的“参数名”

void DISPLAY_NAME(INT8U number,INT8U ch_type)
{
   INT8U *p = BUFFER_ADDR_POINTER(ch_type);

        *p++ = DEFAULT_BUFFER.Name;
        *p++ = DEFAULT_BUFFER.Name;
        *p++ = DEFAULT_BUFFER.Name;
        *p++ = DEFAULT_BUFFER.Name;
        *p   = DEFAULT_BUFFER.Name;
}

ba_wang_mao 发表于 2009-4-28 12:28:48

(4)、if (DEFAULT_BUFFER.Decimal & 0x80)        //        如果当前参数允许输入负数
(5)、bit_number = (DEFAULT_BUFFER.Decimal >> 4) & 0x07;

  好象也不对。

Gorgon_Meducer 发表于 2009-4-28 13:29:34

修改INT8U *p = BUFFER_ADDR_POINTER(ch_type);
为__flash INT8U *p = BUFFER_ADDR_POINTER(ch_type);

ba_wang_mao 发表于 2009-4-28 14:34:34

我试试

ba_wang_mao 发表于 2009-4-28 15:11:37

经过测试,还是不行。

 1、定义一个INT8U bit_number;
   每按一下SET键,执行
    bit_number = DEFAULT_BUFFER.Max
      if (i >= SET_BUFFER_LENGTH)
         i=0
   然后将bit_number 送显示单元,竟然全部显示=0

2、定义一个INT8U bit_number;
   每按一下SET键,执行
    bit_number = DEFAULT_BUFFER.Decimal
      if (i >= SET_BUFFER_LENGTH)
         i=0
   然后将bit_number 送显示单元,竟然全部显示=0

ba_wang_mao 发表于 2009-4-28 15:16:56

改为:

INT8U dis;

void DISPLAY_NAME(INT8U number,INT8U ch_type)
{
   ch_type = ch_type;

   dis = DEFAULT_BUFFER.Name;
   dis = DEFAULT_BUFFER.Name;
   dis = DEFAULT_BUFFER.Name;
   dis = DEFAULT_BUFFER.Name;
   dis = DEFAULT_BUFFER.Name;
}

也不行。

 同时从ROM的结构体中取出成员的数值“竟然”全部等于=“0”,为什么呢?

Gorgon_Meducer 发表于 2009-4-28 15:25:34

你不明白我的意思……
ROM和SRAM不是同一个地址空间,你不能这样访问的。

BUFFER_ADDR_POINTER()原型是什么……

ba_wang_mao 发表于 2009-4-28 15:47:18

 1、定义一个RAM中的int变量,访问ROM的结构体中的成员,得到的值竟然“全部”=0
   定义一个INT16S bit_number;

    每按一下SET键,执行
      bit_number = DEFAULT_BUFFER.Max
        if (i >= SET_BUFFER_LENGTH)
            i=0
     然后将bit_number 送显示单元,竟然全部显示=0

/// 也就是说:
    从ROM的结构体中取出成员的数值“竟然”全部等于=“0”,
    在ICC7.14下,我显示出来,全部正确。

 2、INT8U *BUFFER_ADDR_POINTER(INT8U ch_type)

Gorgon_Meducer 发表于 2009-4-29 12:20:57

to【7楼】 ba_wang_mao
   把INT8U *BUFFER_ADDR_POINTER(INT8U ch_type)
修改为:__flash INT8U *BUFFER_ADDR_POINTER(INT8U ch_type) ,
你把这个函数的实体也贴出来。

ba_wang_mao 发表于 2009-4-29 13:18:41

Gorgon Meducer 傻孩子:

  现在的问题是:
   (1)把ROM中结构体成员的值读到RAM中,竟然不成功,读出的全部=0,而在ICC7.14下是正确的。
      在ICC7.19下,INT16S bit_number;
        bit_number = DEFAULT_BUFFER.Max   ----> 读出的全部=0
   (2)、
      INT8U dis1;
      INT8U dis2;
      INT8U dis3;

    INT8U *BUFFER_ADDR_POINTER(INT8U ch_type)
    {
          INT8U *p;

         switch (ch_type)
         {
                case enum_CHA_TYPE:
                        p = dis1;
                        break;
                case enum_CHB_TYPE:
                        p = dis2;
                        break;
                case enum_CHC_TYPE:
                        p = dis3;
                        break;
        }
        return (p);
   }


void DISPLAY_NAME(INT8U number,INT8U ch_type)
{
        INT8U *p = BUFFER_ADDR_POINTER(ch_type);

        *p++ = DEFAULT_BUFFER.Name;
        *p++ = DEFAULT_BUFFER.Name;
        *p++ = DEFAULT_BUFFER.Name;
        *p++ = DEFAULT_BUFFER.Name;
        *p        = DEFAULT_BUFFER.Name;
}

Gorgon_Meducer 发表于 2009-4-29 19:01:29

to 【9楼】 ba_wang_mao
    从你的函数来看问题很明显。
    ROM里面的数据,必须用__flash关键字来声明,其指针也必须声明为__flash类型,
而你的指针类型显然不符合要求,都是指向RAM空间的。

ba_wang_mao 发表于 2009-4-30 08:50:06

【10楼】 Gorgon Meducer 傻孩子

  (1)、先不讨论指针问题,因为ICC7.19从ROM结构体数组中取“整型变量”的成员值都是错误的
               INT16S bit_number;
        bit_number = DEFAULT_BUFFER.Max   是错误的

  (2)、定义在ROM空间中的“非结构体数组”的取值,则是正确的
         flash INT8U BLACK_ROM = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
         INT8U a=BLACK_ROM;           是正确的

  当采用ICC7.14编译,上述(1)、(2)结果全部正确,
  当采用ICC7.19编译,上述(1)是错误的,(2)是正确的
  也就是说ICC7.19从ROM空间的“结构体数组”中取数是错误的。

void_c 发表于 2009-4-30 12:59:18

ICC从来不用。

不过很明显,ICC的flash用法在向IAR靠拢。

Gorgon_Meducer 发表于 2009-4-30 13:23:22

to 【11楼】 ba_wang_mao
    你更换成7.20看看。我最近一直使用7.20,只在程序代码空间大于64K时,遇到过类似的
情况。
    我帮你查阅了一下:
- Added support for __flash
    - If the command line flag -const_is_flash is used, then "const" is
      treated as the same as __flash
    从7.15版本开始,才正式把const和__flash分开,所以建议你把所有的flash修改为__flash
再看一看效果?从7.15开始ICC编译器处理__flash关键字有了质的变化,所以7.14能够运行的
程序在7.15以后的版本中可能都是会存在问题的。你要注意,在7.15版本以后__flash和普通变量
是严格进行类型检测的。指针不可以混用。但是,基本的变量赋值操作应该是正常的。所以,你
可以先从你提出的结构体变量赋值开始测试。把flash都更换为__flash。

ba_wang_mao 发表于 2009-4-30 17:37:23

【13楼】 Gorgon Meducer 傻孩子
  给个ICC7.20的破解版的链接吧!

void_c 发表于 2009-4-30 20:38:32

傻孩子 大人 是ATMEL的工程师,难道还用所谓“破解”?

Gorgon_Meducer 发表于 2009-5-1 01:01:40

- -b 8小时俺是ATMEL的人,8小时以后俺是俺……

Gorgon_Meducer 发表于 2009-5-1 01:02:18

to 【14楼】 ba_wang_mao
    就在这个论坛上……我不好公开给你……
页: [1]
查看完整版本: 请教傻孩子大侠:从ICC7.14升级到ICC7.19,从ROM的结构体中取数错误的问题