简体   繁体   English

将32位寄存器拆分为可变大小的字节

[英]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: 您的示例中的一些小技巧:

  • Always ensure that all hex literals in your code have a type that makes sense. 始终确保代码中的所有十六进制文字都具有有意义的类型。 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. “草率类型”会引起各种细微的错误,尤其是与各种形式的整数提升结合使用时。
  • Move the volatile qualifier out of the struct. 将volatile限定符移出结构。 Avoid using type qualifiers inside structs if possible - they usually cause lots of type compatibility hiccups. 尽可能避免在结构内部使用类型限定符-它们通常会引起很多类型兼容性问题。
  • Pointer notation for hardware registers is a bit peculiar. 硬件寄存器的指针符号有点特殊。 The most common style is to regard registers as declared variables. 最常见的样式是将寄存器视为声明的变量。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM