打印
[AVR单片机]

讨论:AVRGCC读取FLASH区(结构体成员)变量

[复制链接]
2352|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ATmega16|  楼主 | 2007-6-5 20:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <avr/pgmspace.h>


#define pgm8(A)
((typeof(A))pgm_read_byte(&(A)))

#define pgm8_p(A)
((typeof(*(A)))pgm_read_byte(A))

#define pgm16(A)
((typeof(A))pgm_read_word(&(A)))

#define pgm16_p(A)
((typeof(*(A)))pgm_read_word(A))

#define pgm32(A)
((typeof(A))pgm_read_dword(&(A)))

#define pgm32_p(A)
((typeof(*(A)))pgm_read_dword(A))


/* 使用pgm(A)读取flsah区指针,会产生一个警告,
   原因是将32位整型变量转换成16位指针。
   : warning: cast to pointer from integer of different size
*/
#define pgm(A)   
(__extension__({                
    uint32_t __result;           
    if(sizeof(typeof(A))==1)
    {
         __result=pgm_read_byte(&(A));
    }
    else if(sizeof(typeof(A))==2)
    {
         __result=pgm_read_word(&(A));
    }
    else if(sizeof(typeof(A))==4)
    {
         __result=pgm_read_dword(&(A));
    }
  (typeof(A))__result;
}))


/* 使用pgm_p(&A)读取flsah区指针,会产生一个警告,
   原因是将32位整型变量转换成16位指针。
   : warning: cast to pointer from integer of different size  */
#define pgm_p(A)   
(__extension__({           
    uint32_t __result;           
    if(sizeof(typeof(*(A)))==1)
    {
         __result=pgm_read_byte(A);
    }
    else if(sizeof(typeof(*(A)))==2)
    {
         __result=pgm_read_word(A);
    }
    else if(sizeof(typeof(*(A)))==4)
    {
         __result=pgm_read_dword(A);
    }
    (typeof(*(A)))__result ;                  
}))



typedef struct Item_t   

    uint8_t             a; 
    uint16_t            b;
    uint32_t            c;
    const uint8_t  *     d ;
    uint8_t                e[2][2];
    void                 (*f)(); 
}Item_t; 

typedef    void (*F_t)(void) ;


#define NullSub (void (*)(void))0x0
#define NullStr ( const uint8_t * )0x1234


void Sub_Test(void)
{
uint8_t i=1;
while(i--);
}

//#define PROGMEM         __attribute__((__progmem__))
Item_t item PROGMEM ={0x64,0x3000,0x12345678,NullStr,{{1,2},{3,4,}},Sub_Test};
const uint8_t * str PROGMEM =NullStr;



int main(void)
{

    uint8_t temp8;
    const uint8_t * temp_p;
    uint16_t temp16;
    uint32_t temp32;
    F_t    fun;        //    void (*fun)(void) ;


//读取flash区1字节变量
    temp8=0;
    temp8=pgm(item.a);

    temp8=0;
    temp8=pgm_p(&item.a);

    temp8=0;
    temp8=pgm8(item.a);

    temp8=0;
    temp8=pgm8_p(&item.a);




//读取flash区16位指针变量    
    temp_p=0;
    temp_p=pgm(item.d);//warning: cast to pointer from integer of different size


    temp_p=0;
    temp_p=pgm_p(&item.d);//warning: cast to pointer from integer of different size

    temp_p=0;
    temp_p=pgm16(item.d);

    temp_p=0;
    temp_p=pgm16_p(&item.d);


    temp_p=0;
    temp_p=pgm(str);//warning: cast to pointer from integer of different size


    temp_p=0;
    temp_p=pgm_p(&str);//warning: cast to pointer from integer of different size

    temp_p=0;
    temp_p=pgm16(str);

    temp_p=0;
    temp_p=pgm16_p(&str);

    
//读取flash区2字节变量
    temp16=0;
    temp16=pgm(item.b);

    temp16=0;
    temp16=pgm_p(&item.b);

    temp16=0;
    temp16=pgm16(item.b);

    temp16=0;
    temp16=pgm16_p(&item.b);



    
//读取flash区4字节变量
    temp32=0;
    temp32=pgm(item.c);

    temp32=0;
    temp32=pgm_p(&item.c);

    temp32=0;
    temp32=pgm32(item.c);

    temp32=0;
    temp32=pgm32_p(&item.c);




//读取flash区数组元素
    temp8=0;
    temp8=pgm(item.e[1][1]);

    temp8=0;
    temp8=pgm_p(&item.e[1][1]);

    temp8=0;
    temp8=pgm8(item.e[1][1]);

    temp8=0;
    temp8=pgm8_p(&item.e[1][1]);



//读取flash区16位函数指针
    fun=0;
    fun=pgm(item.f);//warning: cast to pointer from integer of different size
    if(fun!=NullSub)
    {
        pgm(item.f)();//warning: cast to pointer from integer of different size
    //    item.f();           //错误
        fun();
    }

    fun=0;
    fun=pgm_p(&item.f);//warning: cast to pointer from integer of different size
    if(fun!=NullSub)
    {
        pgm_p(&item.f)();//warning: cast to pointer from integer of different size
//        item.f();        //错误
        fun();
    }



    fun=0;
    fun=pgm16(item.f);
    if(fun!=NullSub)
    {
        pgm16(item.f)();
//        item.f();        //错误
        fun();
    }


    fun=0;
    fun=pgm16_p(&item.f);
    if(fun!=NullSub)
    {
        pgm16_p(&item.f)();
//        item.f();            //错误
        fun();
    }


while(1);

}

/*
读取FLSH区1字节变量A可以用pgm(A),pgm_p(&A),pgm8(A),pgm8_p(&A);
读取FLSH区2字节变量A可以用pgm(A),pgm_p(&A),pgm16(A),pgm16_p(&A);
读取FLSH区4字节变量A可以用pgm(A),pgm_p(&A),pgm32(A),pgm32_p(&A);
读取FLASH区16位指针A可以用pgm16(A),pgm16_p(&A),用pgm(A),pgm_p(&A)会产生一个警告,结果仍然正确;
读取FLASH区16位函数指针A可以用pgm16(A),pgm16_p(&A),用pgm(A),pgm_p(&A)会产生一个警告,结果仍然正确。
*/

相关帖子

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

本版积分规则

109

主题

229

帖子

0

粉丝