ori*_*ena 18 c c++ gcc systems-programming
我正在为没有内存保护的嵌入式系统编写系统级代码(在ARM Cortex-M1上,使用gcc 4.3编译)并且需要直接读/写到内存映射寄存器.到目前为止,我的代码看起来像这样:
#define UART0 0x4000C000
#define UART0CTL (UART0 + 0x30)
volatile unsigned int *p;
p = UART0CTL;
*p &= ~1;
Run Code Online (Sandbox Code Playgroud)
有没有使用指针的更短路(代码更短,我的意思是)?我正在寻找一种方法来编写实际的赋值代码(如果我不得不使用更多的#defines,那就没关系):
*(UART0CTL) &= ~1;
Run Code Online (Sandbox Code Playgroud)
到目前为止我尝试过的任何东西最终都是因为gcc抱怨它无法为左值分配东西......
Chr*_*ung 21
#define UART0CTL ((volatile unsigned int *) (UART0 + 0x30))
Run Code Online (Sandbox Code Playgroud)
:-P
编辑添加:哦,响应所有关于如何标记C++和C的问题的评论,这里是一个C++解决方案.:-P
inline unsigned volatile& uart0ctl() {
return *reinterpret_cast<unsigned volatile*>(UART0 + 0x30);
}
Run Code Online (Sandbox Code Playgroud)
这可以直接插入头文件中,就像C风格的宏一样,但你必须使用函数调用语法来调用它.
Mat*_* M. 17
我想成为一个挑剔者:我们在谈论C或C++吗?
如果是C,我愿意顺从克里斯的回答(我希望删除C++标签).
如果是C++,我建议不要使用那些令人讨厌的C-Casts #define
.
惯用的C++方法是使用全局变量:
volatile unsigned int& UART0 = *((volatile unsigned int*)0x4000C000);
volatile unsigned int& UART0CTL = *(&UART0 + 0x0C);
Run Code Online (Sandbox Code Playgroud)
我声明了一个类型化的全局变量,它将遵循范围规则(与宏不同).
它可以很容易地使用(不需要使用*()
),因此更短!
UART0CTL &= ~1; // no need to dereference, it's already a reference
Run Code Online (Sandbox Code Playgroud)
如果你想让它成为指针,那么它将是:
volatile unsigned int* const UART0 = 0x4000C000; // Note the const to prevent rebinding
Run Code Online (Sandbox Code Playgroud)
但是使用const
不能为null 的指针有什么意义呢?这在语义上是为什么创建引用的原因.