[英]Splitting 32 bit register in variable size bytes
I want to split a general purpose register into three separate registers; 我想将通用寄存器分为三个单独的寄存器; two 8 bit registers & one 16 bit register. 2个8位寄存器和1个16位寄存器。 This is the approach I am using but I think it may be wrong. 这是我正在使用的方法,但我认为这可能是错误的。
typedef struct {
volatile uint8_t reg_0;
volatile uint8_t reg_1;
volatile uint16_t reg_2;
} reg_split;
#define REG_BASE (0xA040000C)
#define REG ((reg_split *)REG_BASE)
And this is how I am accessing the register: 这就是我访问寄存器的方式:
REG->reg_0 = 0xFF;
Is this the wrong approach or is their a cleaner solution? 这是错误的方法还是更干净的解决方案?
What's most important for all kinds of memory mappings like these, is that you verify that the C code yields the expected result. 对于所有这些类型的内存映射,最重要的是验证C代码是否产生了预期的结果。 You have to consider padding and alignment. 您必须考虑填充和对齐方式。
Some minor nit-picks with your example: 您的示例中的一些小技巧:
0xA040000C
in your case is of a signed type, most likely unsigned int
. 在您的情况下, 0xA040000C
是带符号的类型,很可能是unsigned int
。 Had you used a literal like 0x5040000C
however, it would be of (signed) int
type. 如果您使用了像0x5040000C
这样的文字,那么它将是(带符号的) int
类型。 On most systems it doesn't make sense to have signed addresses. 在大多数系统上,没有签名地址是没有意义的。 "Sloppy types" can cause all manner of subtle bugs, particularly when combined with various forms of integer promotion. “草率类型”会引起各种细微的错误,尤其是与各种形式的整数提升结合使用时。 With the above remarks in mind, your code could be re-written as: 考虑到上述注意事项,您的代码可以重写为:
typedef struct {
uint8_t reg_0;
uint8_t reg_1;
uint16_t reg_2;
} reg_split;
#define REG_BASE (0xA040000Cu)
#define REG (*(volatile reg_split *)REG_BASE)
_Static_assert(sizeof(reg_split) == 4, "Unwanted padding detected");
...
REG.reg_0 = 0xFF;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.