自V4.6开始,数字转指针已实现自动处理,使用方法:工程属性》高级》替换》数字地址转为合法指针,选中“自动处理”。如自动处理产生问题,请阅读以下手动处理说明。
问题场景
部分嵌入式项目,变量地址由数字指定,将数字直接作为指针使用,常见方式类似于以下代码:
typedef struct
ObjectType
{
int a;
int b;
}ObjectType;
//基地址
#define BASE_ADDR 0x200000
//以基地址加偏移定义的基础类型指针,只需转换基地址。
#define Mem01 ((int*)(BASE_ADDR
+ 0x100)) //指针1
#define Mem02 ((int*)(BASE_ADDR
+ 0x200)) //指针2
//直接用数字定义的基础类型指针,需各自转换
#define Mem03 ((int*)(0x00200100))
#define Mem04 ((int*)(0x00200200))
//以基地址定义的复合类型指针,需各自转换
#define objData1
((ObjectType*)(BASE_ADDR + 0x1000))
#define objData2
((ObjectType*)(BASE_ADDR + 0x2000))
//直接用数字定义复合类型指针,需各自转换
#define objData3
((ObjectType*)0x00300100)
#define objData4
((ObjectType*)0x00300200)
以上,Mem01、Mem02、Mem03、Mem04,作为int*类型指针使用,objData1、objData2、objData3、objData4,作为ObjectType*类型指针使用。执行测试过程中,对这些指针进行读或写操作的代码行将崩溃。
解决办法
工程属性》高级》替换》数字地址转为合法指针,点击“添加”,如下图:
|
|
|
只需转换基地址的情形:
如果一系列地址是在一个基地址的基础上,加上偏移量来定义的,且为基本数据类型,则只需转换基地址,不必处理每个地址,如:
#define BASE_ADDR 0x200000
//基地址
#define Mem01 ((int*)(BASE_ADDR
+ 0x100)) //指针1
#define Mem02 ((int*)(BASE_ADDR
+ 0x200)) //指针2
......
只需转换BASE_ADDR,无需转换Mem01、Mem02。
此种情形下,需注意:
1)“替换为”不能手工修改。
2)“元素数”必须足免够大,以保证最大的地址有效。
标记
填写宏名称,如Mem03、objData1。对于只需转换基地址的情形,“标记”填写基地址的宏名。
数据类型
只能填写基本数据类型,且不含指针符号,如char、unsigned char、int,具体的类型要满足两个条件之一:
1)与宏义一致,如#define Mem01 ((int*)(BASE_ADDR
+ 0x100)),则数据类型为int,这种情形下,“替换为”输入框不需要手工填写,使用自动填写的内容即可。
2)可以转换为目标类型,如#define objData1
((ObjectType*)(BASE_ADDR + 0x1000)),数据类型可以使用unsigned
char、char、short、int等,这种情形下,“替换为”输入框需要手工修改,加入类型转换代码。
元素数
如果需要一大块的内存,应使用数组,这里填写数组的元素数,支持10进制和16进制。
变量名
用于生成变量定义Var,形成有效的内存空间。
指针名
用于生成指针变量,指向Var的地址,形成有效的指针,以代替原来的数字。
替换为
用于将代码中使用的数字指针替换为有效指针,填写时,可拷贝宏定义中宏名称后的内容,并将其中的数字改为指针名。如果不需要类型转换,此项可使用自动填写的内容。
如:#define Mem03
((int*)(0x00200100)),指针名为_Mem03,则替换为填写:((int*)_Mem03);
如:#define objData3
((ObjectType*)0x00300100),指针名为_objData3
,则替换为填写:((ObjectType*)_objData3)。
加入表格
完成转换后,“指针名”相当于一个普通的全局变量,可以加入表格并设置输入和判断输出。
自动生成的代码示例
添加转换后,VU自动生成变量定义以及指针定义,如:
//VuxInc/VuxNpi.h(实现)
int __BASE_ADDR[0x1000] = {0};
int* _BASE_ADDR =
&__BASE_ADDR[0];
int __Mem03 = 0;
int* _Mem03 = &__Mem03;
int __Mem04 = 0;
int* _Mem04 = &__Mem04;
int __objData1 = 0;
int* _objData1 = &__objData1;
int __objData2 = 0;
int* _objData2 = &__objData2;
unsigned
char __objData3[0x1000] = {0};
unsigned
char* _objData3 = &__objData3[0];
unsigned
char __objData4[0x1000] = {0};
unsigned
char* _objData4 = &__objData4[0];
//VuxInc/VuxNpd.h(声明)
extern int*
_BASE_ADDR;
extern int*
_Mem03;
extern int*
_Mem04;
extern int*
_objData1;
extern int*
_objData2;
extern
unsigned char*
_objData3;
extern
unsigned char*
_objData4;
自动替换的代码示例
红色为原始代码,紫红色为替换后的代码。
int _13_NumberPointer(int
a, int b)
{
int ret
= 0;
//基地址
//#define BASE_ADDR 0x200000
//以基地址加偏移定义的基础类型指针,只需转换基地址。
//#define Mem01 ((int*)(BASE_ADDR3 +
0x100)) //指针1
//#define Mem02 ((int*)(BASE_ADDR3 +
0x200)) //指针2
*Mem01 = a;
*Mem02 = b;
ret += *Mem01;
ret += *Mem02;
*((int*)( _BASE_ADDR + 0x100)) = a;
*((int*)( _BASE_ADDR + 0x200)) = b;
ret += *((int*)( _BASE_ADDR +
0x100));
ret += *((int*)( _BASE_ADDR +
0x200));
//直接用数字定义的基础类型指针,需各自转换
//#define Mem03 ((int*)(0x00200100))
//#define Mem04 ((int*)(0x00200200))
*Mem03 = a;
*Mem04 = b;
ret += *Mem03;
ret += *Mem04;
* _Mem03 = a;
* _Mem04 = b;
ret += * _Mem03;
ret += * _Mem04;
//以基地址加偏移定义的复合类型指针,需各自转换
//#define objData1
((ObjectType*)(BASE_ADDR + 0x1000))
//#define objData2
((ObjectType*)(BASE_ADDR + 0x2000))
objData1->a = a;
objData2->a = b;
ret += objData1->a;
ret += objData2->a;
((ObjectType*)(_objData1))->a = a;
((ObjectType*)(_objData2))->a = b;
ret += ((ObjectType*)(_objData1))->a;
ret += ((ObjectType*)(_objData2))->a;
//直接用数字定义的复合类型指针,需各自转换
//#define objData3
((ObjectType*)0x00300100)
//#define objData4
((ObjectType*)0x00300200)
objData3->a = a;
objData4->a = b;
ret += objData3->a;
ret += objData4->a;
((ObjectType*)(_objData1))->a = a;
((ObjectType*)(_objData2))->a = b;
ret += ((ObjectType*)(_objData1))->a;
ret += ((ObjectType*)(_objData2))->a;
return
ret;
}
|
|