使用volatile变量的C语言示例函数

3

我正在寻找一个使用volatile变量的实际C函数,与IT技术相关。这并不难找到,但我正在寻找一个函数,在执行函数期间,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
 }

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

如果有任何现实生活中的示例将非常感激。我在网上找不到许多使用易失性变量的示例。

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;
}

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

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。由于这在幕后发生,因此我们告诉编译器始终将数据读写到内存中。


非常感谢litb,这个例子非常合适。在函数memsize中,变量busTimeoutSeen必须在函数执行过程中从0变为非零值,才能使函数完成。 - undefined

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接