#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)会产生一个警告,结果仍然正确。 */
|