我一直在阅读有关访问外围设备的内存映射寄存器的信息,看来你可以采取多种方式。例如:
方法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个字节。
答案 0 :(得分:5)
*ptrMyReg = 0x7FFFFFFF;
在第二种情况下,*ptrMyReg
的类型为unsigned char
,因此0x7FFFFFFF
将转换为unsigned char
(即转化后的值为0xFF
)在赋值之前,只写一个字节。如果您原本打算写4个字节,我不认为这是您想要的。
答案 1 :(得分:2)
好吧,第二个例子不是有效代码,因为你的类型转换不匹配。如果您将其修复为:
ptrMyReg = (volatile unsigned char *)MyReg;
然后,是的,他们是不同的。在第二种情况下,该常量被截断,并且您将仅0xFF
写入0x30610000
的单词的最高或最低有效字节,具体取决于字节顺序。无论如何,它是0x30610000
的单字节将被写入,而不是其他字节。
答案 2 :(得分:1)
CPU体系结构可能要求对perihperal寄存器的所有访问都是例如32位宽。如果是这样,执行字节访问可能会导致CPU异常或无提示错误执行。许多ARM SoC都是这种情况。
答案 3 :(得分:0)
在方法2中,您不会通过取消引用指向int
的指针来访问整个char
(当然,除非您的平台上sizeof(int)
= 1)。< / p>
除此之外,你应该看看你的硬件。使用不同大小的内存操作数进行访问时,它的行为可能会有所不同。