You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内核中从无关驱动B检测驱动A是否成功探测

Linux驱动中通过驱动名称判断探测状态并触发函数的实现方法

可以实现,以下是几种常用的方案:

方案一:通过sysfs/class/总线查找设备状态

驱动A探测成功后会将对应的设备注册到系统的sysfs中,你可以通过驱动A关联的class或总线名称,查找对应的设备是否存在且已完成绑定:

#include <linux/device.h>
#include <linux/class.h>

// 检查驱动A是否已探测成功
static int drvA_is_probed(void) {
    struct class *target_cls;
    struct device *found_dev;

    // 替换为驱动A所属的class名称(比如"i2c-dev"、"gpio"或自定义class)
    target_cls = class_find(THIS_MODULE, "drvA_class");
    if (!target_cls)
        return -EINVAL;

    // 替换为驱动A注册的设备名称
    found_dev = class_find_device(target_cls, NULL, "drvA_device", device_match_name);
    class_put(target_cls);

    if (found_dev) {
        put_device(found_dev);
        return 0; // 驱动A已完成探测
    }
    return -ENODEV; // 未探测或失败
}

// 驱动B中需要触发的函数
void drvB_run_target_func(void) {
    if (!drvA_is_probed()) {
        pr_info("Driver A probed successfully, executing B's function\n");
        // 这里写驱动B的业务逻辑
    } else {
        pr_warn("Driver A not ready, skip B's function\n");
    }
}

如果驱动A没有自定义class,也可以用总线类型(比如platform、i2c)调用bus_find_device来查找。

方案二:针对Platform驱动的专属检查

如果驱动A是platform类型的驱动,可直接通过platform总线查询设备与驱动的绑定状态:

#include <linux/platform_device.h>

static int drvA_platform_is_probed(void) {
    struct platform_device *pdev;

    // 替换为驱动A绑定的platform设备名称
    pdev = platform_device_find("drvA_platform_dev", NULL);
    if (!pdev)
        return -ENODEV;

    // 检查设备是否已与驱动绑定
    bool probed = (pdev->driver != NULL);
    put_device(&pdev->dev);
    return probed ? 0 : -ENODEV;
}

方案三:自定义同步标志(最可靠的方式)

如果上述依赖系统总线的方式存在延迟或不确定性,可在驱动A中添加同步标志,直接告知驱动B自身状态:

驱动A侧(需导出符号)

#include <linux/completion.h>
#include <linux/module.h>

// 定义全局探测完成标志和完成量
static bool drvA_probed_flag = false;
DECLARE_COMPLETION(drvA_probe_done);

// 驱动A的probe函数
static int drvA_probe(struct platform_device *pdev) {
    // 驱动A的探测逻辑
    // ...

    // 标记探测完成
    drvA_probed_flag = true;
    complete(&drvA_probe_done);
    return 0;
}

// 导出符号供驱动B访问
EXPORT_SYMBOL_GPL(drvA_probed_flag);
EXPORT_SYMBOL_GPL(drvA_probe_done);

驱动B侧

// 引用驱动A导出的符号
extern bool drvA_probed_flag;
extern struct completion drvA_probe_done;

void drvB_run_target_func(void) {
    // 非阻塞检查:直接判断标志位
    if (drvA_probed_flag) {
        // 执行驱动B的逻辑
    }

    // 阻塞等待(如果需要等驱动A完成探测再执行)
    // wait_for_completion_timeout(&drvA_probe_done, msecs_to_jiffies(2000));
    // if (drvA_probed_flag) {
    //     // 执行逻辑
    // }
}

方案对比

  • 方案一/二无需修改驱动A,但依赖驱动A的设备注册信息,可能存在系统同步延迟;
  • 方案三最直接可靠,但需要修改驱动A代码,且要注意模块加载顺序(确保驱动A先于B加载,或B处理依赖)。

内容的提问来源于stack exchange,提问作者fmuller1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 13:17:35