我有以下问题:我正在尝试定义一些基本结构,这有助于我映射控制器内存的一部分以更有效的方式使用它。让我举个例子:
typedef struct
{
ICR1_t ICR1_dByte; /* 0x46 - 0x47 */
OCR1B_t OCR1B_dByte; /* 0x4A - 0x4B */
OCR1A_t OCR1A_dByte; /* 0x48 - 0x49 */
TCNT1_t TCNT1_dByte; /* 0x4C - 0x4D */
TCCR1B_t TCCR1B_Byte; /* 0x4E */
TCCR1A_t TCCR1A_Byte; /* 0x4F */
uint8_t Filler[8]; /* 0x50-0x57 */
TIFR1_t TIFR1_Byte; /* 0x58 */
TIMSK1_t TIMSK1_Byte; /* 0x59 */
}Timer1_str;
用法定义:
#define TIMER1str (*(volatile Timer1_str *)(TIMER1_START_ADDRESS))
TIMER1_START_ADDRESS定义为
的位置(uint8_t *)&ICR1
(ICR1是基本定义的一部分,有些地址,从不介意)
所以,我的具体问题是如何填补位于0x50-0x57地址下的内存空白?在当前的解决方案中,变量“填充程序”在所有自动补充工具下都可见,因此可以调用字段:
TIMER1str.Filler[0] = 0xAA;
我希望隐藏该填充程序的实现。我的第一个想法是将此填充程序实现为匿名联合,如下所示:
...
TCCR1A_t TCCR1A_Byte; /* 0x4F */
union { Filler[8]; }; /* 0x50-0x57 as anonymous */
TIFR1_t TIFR1_Byte; /* 0x58 */
....
但是这个解决方案没有用......
如何隐藏成员的结构?它应该设置内存但不应该是可访问的。
答案 0 :(得分:2)
看起来你正在为AVR编码。
不要这样做。使用编译器提供的这些寄存器的定义。
如上所述,您的代码指定Timer1_str
结构将存在于系统内存中由链接器确定的某个位置。在没有任何额外支持的情况下,此代码将无法工作,因为此结构将映射到SRAM,导致写入没有特殊效果。即使您使用链接器将此结构映射到适当的地址(可能或可能不可能),编译器生成的代码也不是最理想的,因为它将无法使用{{1} }和IN
指令来操纵这些寄存器。 (要生成这些指令,必须在编译时知道要写入的地址。)此外,编译器可能会生成不能正确访问这些寄存器的代码 - 例如,这里它可能会以错误的顺序生成对TCNT的写入。 / p>
答案 1 :(得分:0)
C不支持此功能。匿名嵌套结构和联合不会隐藏该成员,它们只允许您访问该成员,就像它们是包含类的成员一样。
如果编译器支持C ++编译,则有一种可能性:
struct Timer1_str
{
public :
ICR1_t ICR1_dByte; /* 0x46 - 0x47 */
OCR1B_t OCR1B_dByte; /* 0x4A - 0x4B */
OCR1A_t OCR1A_dByte; /* 0x48 - 0x49 */
TCNT1_t TCNT1_dByte; /* 0x4C - 0x4D */
TCCR1B_t TCCR1B_Byte; /* 0x4E */
TCCR1A_t TCCR1A_Byte; /* 0x4F */
private :
uint8_t Filler[8]; /* 0x50-0x57 */
public :
TIFR1_t TIFR1_Byte; /* 0x58 */
TIMSK1_t TIMSK1_Byte; /* 0x59 */
} ;