Heng30的博客
搜索 分类 关于 订阅

如何在Linux驱动中使用完成量进行同步?

2025-03-15

在Linux驱动中,可以使用completion进行同步。下面的例子就使用完成量等待定时器回调函数返回。

驱动代码

// simple.c

#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/timer.h>

static struct timer_list my_timer;
static struct completion comp;

static void _cb(struct timer_list *data) {
    pr_info("timer callback\n");

    complete(&comp);
}

static int __init simple_init(void) {
    int status;

    pr_info("simple_init\n");

    timer_setup(&my_timer, _cb, 0);
    init_completion(&comp);

    mod_timer(&my_timer, jiffies + msecs_to_jiffies(50));

    status = wait_for_completion_timeout(&comp, msecs_to_jiffies(100));
    if (!status) {
        pr_info("completion 100ms timeout\n");
    } else {
        pr_info("completion 100ms finished\n");
    }

    reinit_completion(&comp);
    mod_timer(&my_timer, jiffies + msecs_to_jiffies(500));
    status = wait_for_completion_timeout(&comp, msecs_to_jiffies(200));
    if (!status) {
        pr_info("completion 200ms timeout\n");
        wait_for_completion(&comp);
        pr_info("timer 500ms finished\n");
    }

    return 0;
}

static void __exit simple_exit(void) {
    pr_info("simple_exit\n");

    del_timer(&my_timer);
}

module_init(simple_init);
module_exit(simple_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("heng30");
MODULE_VERSION("v0.0.1");
MODULE_DESCRIPTION("A simple kernel module");

编译脚本

#!/bin/sh

top-dir = $(shell pwd)
kernel-version = $(shell uname -r)
kernel-dir ?= /lib/modules/$(kernel-version)/build

obj-m += simple.o

all:
        make -C $(kernel-dir) modules M=$(top-dir)

clean:
        rm -f *.o *.ko *.mod *.mod.c *.order *.symvers *.dtbo
        make -C $(kernel-dir) clean m=$(top-dir)

测试

  • 编译程序:make

  • 安装驱动:insmod simple.ko

  • 查看输出:dmesg

[15020.885739] simple_init
[15020.940938] timer callback
[15020.941016] completion 100ms finished
[15021.156710] completion 200ms timeout
[15021.452921] timer callback
[15021.453149] timer 500ms finished
[15049.731981] simple_exit
  • 移除驱动:rmmod simple.ko