2013-04-21 53 views
4

我一直在阅读关于访问外围设备的内存映射寄存器的问题,看起来您可以采用多种方式。例如:使用char和int访问内存映射寄存器的区别

方法1:

#define MyReg 0x30610000 

volatile int *ptrMyReg; 
ptrMyReg = (volatile int *) MyReg; 
*ptrMyReg = 0x7FFFFFFF; /* Turn ON all bits */ 

方法2:

#define MyReg 0x30610000 

volatile unsigned char *ptrMyReg; 
ptrMyReg = (volatile unsigned char *) MyReg; 
*ptrMyReg = 0x7FFFFFFF; /* Turn ON all bits */ 

问:是否有任何具体的原因,为什么人会选择一个比另一个?

假设:体系结构上的int大小为4个字节。

+1

第一个选择第二个的原因是第一个会编译,第二个不会(因为你试图给'char *'分配一个int *')。 – Praetorian 2013-04-21 17:13:28

+0

@Praetorian - 这是一个错字。修复。谢谢。 – modest 2013-04-21 17:17:50

回答

5

*ptrMyReg = 0x7FFFFFFF;

在第二种情况下,*ptrMyRegunsigned char类型,以便将0x7FFFFFFF分配之前被转换为unsigned char(即,转换后的值将是0xFF)和只有一个字节将被写入。如果你最初打算写4个字节,我不认为这是你想要的。

2

那么,第二个例子不是有效的代码,因为你的类型转换不匹配。如果你解决这个问题:

ptrMyReg = (volatile unsigned char *)MyReg; 

然后,是的,他们是不同的。在第二种情况下,该常量会被截断,并且您将只写入0xFF至该字的最高或最低有效字节0x30610000,具体取决于字节顺序。无论如何,这是在0x30610000的单个字节,将被写入,而不是其他人。

1

CPU体系结构可能要求所有对周围寄存器的访问都是例如。 32位宽。如果是这样,做字节访问可能会导致CPU异常或无声的错误执行。许多ARM SoC都是这种情况。

0

在方法2,你是不会提领的指针访问整个intchar(除非,当然,sizeof(int) = 1对您的平台)。

除此之外,你应该看看你的硬件。使用不同大小的内存操作数访问时,它的行为可能会有所不同。