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