c - 使用 select() 检测 UIO 设备文件上的 block

标签 c select blocking

我正在研究运行 Yocto 的嵌入式处理器。我有一个修改过的 uio_pdrv_genirq.c UIO 驱动程序。

我正在编写一个库来控制 DMA。有一个函数写入设备文件并启动 DMA。第二个函数旨在通过调用 select() 等待 DMA 完成。当 DMA 正在进行时,设备文件 block 。完成后,DMA Controller 发出一个中断,释放设备文件上的 block 。

我使用 read() 让系统按预期工作,但我想切换到 select() 以便我可以包括超时。然而,当我使用 select() 时,它似乎没有识别 block 并且总是立即返回(在 DMA 完成之前)。我包含了一个简单版本的代码:

int gannet_dma_interrupt_wait(dma_device_t *dma_device,
        dma_direction dma_transfer_direction) {

    fd_set rfds;
    struct timeval timeout;
    int select_res;

    /* Initialize the file descriptor set and add the device file */
    FD_ZERO(&rfds);
    FD_SET(dma_device->fd, &rfds);

    /* Set the timeout period. */
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;

    /* The device file will block until the DMA transfer has completed. */
    select_res = select(FD_SETSIZE, &rfds, NULL, NULL, &timeout);

    /* Reset the channel */
    gannet_dma_reset(dma_device, dma_transfer_direction);

    if (select_res == -1) {
        /* Select has encountered an error */
        perror("ERROR <Interrupt Select Failed>\n");
        exit(0);
    }
    else if (select_res == 1) {
        /* The device file descriptor block released */
        return 0;
    }
    else {
        /* The device file descriptor block exceeded timeout */
        return EINTR;
    }
}

我的代码有什么明显的错误吗?或者有人可以建议选择的替代方案吗?

最佳答案

事实证明,UIO 驱动程序包含两个计数器。一个记录 事件数(event_count),另外记录了多少个事件 调用函数知道 (listener->event_count)。

当您在 UIO 驱动程序上执行 read() 时,它会返回事件数和 使 listener->event_count 等于 event_count。 IE。听众是 现在更新所有已发生的事件。

当您在 UIO 驱动程序上使用 poll()select() 时,它会检查这两个 数字不同并返回(如果它们相同) 等到它们不同然后返回)。它不更新 listener->event_count.

显然,如果您在调用 select() 之间不执行 read(),那么 listener->event_count 将与 event_count 和第二个不匹配 select() 将立即返回。 因此有必要调用 read() 在调用 select() 之间。

事后看来,select() 应该以这种方式工作似乎很清楚,但当时对我来说并不明显。

关于c - 使用 select() 检测 UIO 设备文件上的 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38304715/

相关文章:

java - 暂停通过 JNI 运行的 native C 代码

php - PHP 如何准确地回显 MySQL 字段中存储的内容?

macos - 使用命令行工具确定 OSX 上的进程被什么阻塞?

c - 是否有可能找出 strcpy 的当前语法何时添加到 C 标准中?

c - printf() 精度

grails - grails g:选择i18n

java - Expect4j 不等待完整输出

c - 有没有办法在 POSIX 线程中到达 ‘join’ (阻止),而不退出加入者?

c - 在 main 中声明的函数原型(prototype) - 最佳实践?

postgresql - 在 Postgres 中使用限制选择更新