【发布时间】:2017-03-20 11:39:25
【问题描述】:
我正在为 Cortex-M0 CPU 和 gcc 编写代码。我有以下结构:
struct {
volatile unsigned flag1: 1;
unsigned flag2: 1;
unsigned foo; // something else accessed in main loop
} flags;
flag1 从 GPIO 中断处理程序和主循环中读取和写入。 flag2 只能在主循环中读写。
ISR 如下所示:
void handleIRQ(void) {
if (!flags.flag1) {
flags.flag1 = 1;
// enable some hw timer
}
}
主循环如下所示:
for (;;) {
// disable IRQ
if (flags.flag1) {
// handle IRQ
flags.flag1 = 0;
// access (rw) flag2 many times
}
// wait for interrupt, enable IRQ
}
在主循环中访问flag2 时,编译器是否会优化对它的访问,使其不会在每次在代码中读取或写入时都被提取或存储到内存中?
我不清楚,因为要在 ISR 中设置 flag1,它需要加载整个 char,设置一个位并将其存储回来。
【问题讨论】:
-
什么是
sizeof(struct flags)? -
我已经更新了答案。在位域之后有一个 int 。所以大小应该是8。
-
您很可能不想为此使用位域。它们是实现定义行为的雷区。即使这是在某个地方定义的,我也不相信编译器会做正确的事情。
-
@user694733 - 这是一个奇怪的位置。如果它是由标准定义的,那么为什么要信任编译器来实现标准所说的任何其他内容?如果它是定义的实现,如果您不信任它的文档,为什么还要使用它?
-
@StoryTeller 我的措辞很差。应该把最后一句话删掉。我的意思是;即使它是由编译器供应商(非 C 标准)定义并在编译器手册中提到的,它也可能在下一次主要的编译器更新中更改,并且在更新过程中很容易被忽视。跨度>
标签: c arm volatile bit-fields