2

对于一篇论文,我正在寻找一个使用 volatile 变量的真实C 函数。这本身并不难找到,但我正在寻找一个函数,其中 volatile 变量的值必须在函数执行过程中发生变化以便到达函数的特定分支。像这样的东西:

typedef struct {
    unsigned       :6;
    unsigned FLAG1 :1;
    unsigned FLAG2 :1;
} __attribute__ ((packed)) REGISTER;

volatile REGISTER * io_ = 0x1234;

int write_to_io()
{
    while (io_->FLAG1) {};
    //io_->FLAG1 is now 0

    io_->FLAG2 = 1;

    sleep(10);

    if (io->FLAG1)  
        return 1;  //io->FLAG1 has changed from 0 to 1
    else
        return 0;  //io->FLAG1 has not changed
 }

如果在函数执行期间结构的不同位发生变化就足够了,但我的主要标准是,对于要到达的某个分支,易失性变量的值在函数执行期间发生变化。

我会非常感谢任何现实生活中的例子。我无法在网上找到很多使用 volatile 的示例。

4

4 回答 4

8

规范(和可移植)示例是处理异步信号。(您可能可以使用 Ctrl-C 将 SIGINT 传递给您的程序)。

#include <signal.h>
#include <stdio.h>

volatile sig_atomic_t quit;

void signal_handler(int sig)
{
    signal(sig, signal_handler);
    quit = 1;
}

int main(void)
{
    signal(SIGINT, signal_handler);
    puts("Hit return to poll quit flag");
    while (!quit) getchar();
    return 0;
}
于 2008-12-22T23:37:50.973 回答
3

选择你最喜欢的开源操作系统,并寻找旧的设备驱动程序,你会发现一些没有其他工作方式的人。

于 2008-12-22T15:45:01.473 回答
2

我老师的一些例子,它使用一个编译器(lcc)在没有 volatile 的情况下工作,但是当我使用我的 gcc 端口为该处理器运行它时中断了。我不得不把volatile放进去。

static int volatile busTimeoutSeen;

int busTimeoutISR(int irq) {
  busTimeoutSeen = 1;
  return 1;  /* skip offending instruction */
}


int memsize(void) {
  unsigned char volatile *ptr;
  unsigned char b;
  ISR oldService;

  busTimeoutSeen = 0;
  oldService = getISR(16);
  setISR(16, busTimeoutISR);
  ptr = (unsigned char *) 0xC0000000;
  while (1) {
    b = *ptr;
    if (busTimeoutSeen) {
      break;
    }
    ptr += (1 << 12);
  }
  setISR(16, oldService);
  return (ptr - (unsigned char *) 0xC0000000) >> 12;
}

它从所有页面连续读取,直到我们超过最后一页,这会导致一个中断,该中断将设置busTimeoutSeen为 1。因为这发生在幕后,我们告诉编译器总是读取和写入数据到内存。

于 2008-12-22T18:06:24.637 回答
0

内存映射 IO 是一个示例,其中内存中的值实际上可能表示从诸如 COM 端口之类的设备读取。当我学习 C 时,这是使用 volatile 关键字给出的示例之一。

于 2008-12-23T00:30:11.023 回答