嵌入式编程之变量移植!
在单片机编程中少不了要用到SRAM(6116,6264,62256等)来保存一些数据。直接在开发板上来编写代码当然可以用指针直接指向,但是如果前期是在PC上进行编写调试的话以后的移植比较麻烦。前一段时间看到了allegro的开发库源码,为了可移植allegro将变量的定义形式全部用宏定义方式来实现(例如类似:#define DEFINE_VAR(type,name) type name ),忽得灵感将其应用到我的实际开发中,还是觉得比较方便的。所以把它写下来当作个人的应用笔记,若能为他人带来方便也是一件幸事!(从学校出来后一直没有写过文字,不通顺,见笑了!)
首先应该注意的是所有用宏定义定义的符号不能与所有任意变量、函数名冲突!
/*
假设PC上变量的原型是这样的
S8 Flag[FLAGNUMBER];
S16 GameState;
PARRTYPE *pArr[PLAYERNUMBER];
U8 state[PLAYERNUMBER][POKERNOPER];
## 表示连接
__LINE__,_LINE_ 该语句所在的行号
注意文件包含!
*/
#define _USE_SRAM //表示是否使用SRAM
//#undef _USE_SRAM
#define BASE_OF_RAM 0x01000000
#define SIZE_OF_RAM (0x7fff+1)
//---------------------------------------------------------------------
//---------------------------------------------------------------------
"type_ex.h"//接口定义
#ifdef _USE_SRAM
//-------------------------------使用SRAM------------------------------------
//单独变量
#define DEFINE_VAR(type,name) type name //不需要保存到SRAM的可以使用这个
#define DEFINE_PVAR(type,name) type *p##name //需要保存到SRAM的可以使用这个
//一维数组
#define DEFINE_ARRAY(type,array,n) type array[n]
#define DEFINE_PARRAY(type,array,n) type *p##array
//二维数组
#define DEFINE_2ARRAY(type,array,m,n) type array[m][n]
#define DEFINE_2PARRAY(type,array,m,n) type (*p##array)[n] //数组指针
//指针数组
#define DEFINE_POINTARRAY(type,array,n) type *array[n]
#define DEFINE_PPOINTARRAY(type,array,n) type *(*p##array)
//------------------------------------------------------------------------------
#define EXTERN_VAR(type,name) extern type name
#define EXTERN_PVAR(type,name) extern type *p##name
#define EXTERN_ARRAY(type,array,n) extern type array[n]
#define EXTERN_PARRAY(type,array,n) extern type *p##array
#define EXTERN_2ARRAY(type,array,m,n) extern type array[m][n]
#define EXTERN_2PARRAY(type,array,m,n) extern type (*p##array)[n]
#define EXTERN_POINTARRAY(type,array,n) extern type *array[n]
#define EXTERN_PPOINTARRAY(type,array,n) extern type *(*p##array)
//-------------------------------------------------------------------------------
#define PNAME(name) p##name
#define XPNAME(name) (*p##name)
#define TURN(name) (*p##name)
#define LINK(point,address) point=address
//==============================不使用SRAM======================================
#else
//单独变量
#define DEFINE_VAR(type,name) type name
#define DEFINE_PVAR(type,name) type name
//一维数组
#define DEFINE_ARRAY(type,array,n) type array[n]
#define DEFINE_PARRAY(type,array,n) type array[n]
//二维数组
#define DEFINE_2ARRAY(type,array,m,n) type array[m][n]
#define DEFINE_2PARRAY(type,array,m,n) type array[m][n]
//指针数组
#define DEFINE_POINTARRAY(type,array,n) type *array[n]
#define DEFINE_PPOINTARRAY(type,array,n) type *array[n]
//-------------------------------------------------------------------
#define EXTERN_VAR(type,name) extern type name
#define EXTERN_PVAR(type,name) extern type name
#define EXTERN_ARRAY(type,array,n) extern type array[n]
#define EXTERN_PARRAY(type,array,n) extern type array[n]
#define EXTERN_2ARRAY(type,array,m,n) extern type array[m][n]
#define EXTERN_2PARRAY(type,array,m,n) extern type array[m][n]
#define EXTERN_POINTARRAY(type,array,n) extern type *array[n]
#define EXTERN_PPOINTARRAY(type,array,n) extern type *array[n]
#define PNAME(name) name
#define XPNAME(name) name
#define TURN(name) name
#define LINK(point,address) point=address
#endif
//---------------------------------------------------------------------------
"var.c"定义变量
DEFINE_PARRAY( S8, Flag, FLAGNUMBER ); //一维数组
DEFINE_PVAR( S16, GameState ); //变量
DEFINE_PPOINTARRAY( PARRTYPE, pArr, PLAYERNUMBER );//指针数组
DEFINE_2PARRAY( U8, state, PLAYERNUMBER, POKERNOPER );//二维数组
//-----------------------------------------------------------------
//externlist.h声明变量
EXTERN_PARRAY( S8, Flag, FLAGNUMBER );
EXTERN_PVAR( S16, GameState );
EXTERN_PPOINTARRAY( PARRTYPE, pArr, PLAYERNUMBER );//指针数组
EXTERN_2PARRAY( U8, state, PLAYERNUMBER, POKERNOPER );//二维数组
//---------------------------------------------------------------------------
//define_var.h定义替代符号
原始程序中使用的是PC上定义的名称,用接口定义变量时加了前缀 ‘p’ ,所以要把原有的变量名定义成宏定义符号,内容是她后面的语句
例如:
PC上定义变量GameState,使用的当然也是GameState;而移植后定义的是 *pGameState ,要一至就应该 用(*pGameState)来代替 GameState
#ifdef _USE_SRAM
//变量
#define GameState XPNAME( GameState )
//数组
#define Flag PNAME( Flag )
#define pArr PNAME( pArr )
#define state PNAME( state )
#endif
//---------------------------------------------------------------------------
//_alloc.c自己简单分配SRAM
void *SYSTEM_MEMORY=NULL;
S32 SYSTEM_MEMORY_MAX_SIZE=0;
void Init_alloc()
{
SYSTEM_MEMORY = (void*)BASE_OF_RAM;
SYSTEM_MEMORY_MAX_SIZE = SIZE_OF_RAM;
}
void *allocSRAM(S32 size)
{
static S8 alloc_flag=0;
void *oldpoint=NULL;
if(alloc_flag==0){
Init_alloc();
alloc_flag=1;
}
if(SYSTEM_MEMORY_MAX_SIZE-size<=0) {
SystemMsg( "alloc SRAM Fail: SRAM Is zero" , 1, True );
return NULL;
}
oldpoint=SYSTEM_MEMORY;
if(SYSTEM_MEMORY_MAX_SIZE-size<0) return NULL;
SYSTEM_MEMORY_MAX_SIZE-=size;
(U8*)SYSTEM_MEMORY+=size;
return (void*)oldpoint;
}
#undef isizeof
#define isizeof(size) (sizeof(size)<<1) //我的SRAM很大, 所以我使用了两倍
void alloc_globalVar(void)
{
#ifdef _USE_SRAM
S16 errorcounter=0;
SystemMsg( "alloc SRAM" , 1, True );
if((PNAME( Flag )=(S8*)allocSRAM(isizeof(S8)*FLAGNUMBER))==NULL){errorcounter=__LINE__;goto errorlab;}//一维数组
if((PNAME( GameState )=(S16*)allocSRAM(isizeof(S16)))==NULL){errorcounter=__LINE__;goto errorlab;}//变量
if((PNAME( pArr )=( PARRTYPE ** )allocSRAM(isizeof(PARRTYPE*)*PLAYERNUMBER))==NULL) {errorcounter=__LINE__;goto errorlab;}//指针数组
if((PNAME( state )=( U8 (*)[POKERNOPER] )allocSRAM(isizeof(U8)*PLAYERNUMBER*POKERNOPER))==NULL) {errorcounter=__LINE__;goto errorlab;}//二维数组
errorlab:
if(errorcounter){
ClearScreen();
SystemErrorMsg("alloc SRAM Fail",1,FALSE);
Put2x2((SCREENX-15*16)/2+16*16,(SCREENY-16)/2,errorcounter,5,errorcounter&3);
Put2x2((SCREENX-15*16)/2+16*16,(SCREENY-16)/2+30,SYSTEM_MEMORY_MAX_SIZE,8,0);
AssertFileLineE(0,True);
}
#endif
}