Linux udev 检测U盘插拔

Linux检测U盘热插拔,插入拔出会发送信号,父类的槽需要自己实现接收逻辑。

USBWatcher.h  

#include <libudev.h>
#include <QObject>
class QSocketNotifier;
class USBWatcher : public QObject {
    Q_OBJECT
public:
    explicit USBWatcher(QObject *parent = nullptr) ;
    void CheckConnectedUSBDevices(); //程序启动首次监测 U盘是否插入
signals:
    void usbDeviceConnected();
    void usbDeviceDisconnected();

private slots:
    void handleDeviceChange();

private:
    struct udev *udev;
    struct udev_monitor *monitor;
    QSocketNotifier *notifier;
};

USBWatcher.cpp

#include "USBWatcher.h"
#include <QDebug>
#include <QFile>
#include <QSocketNotifier>
USBWatcher::USBWatcher(QObject *parent): QObject(parent)
{
    udev = udev_new();
    if (!udev) {
        qWarning() << "Failed to create udev context";
        return;
    }
    // 创建一个udev监视器,监听所有设备事件
    monitor = udev_monitor_new_from_netlink(udev, "udev");
    udev_monitor_filter_add_match_subsystem_devtype(monitor, "usb", NULL);
    udev_monitor_enable_receiving(monitor);

    // 获取监视器的文件描述符,并设置为Qt的信号触发器
    int fd = udev_monitor_get_fd(monitor);
    notifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
    connect(notifier, &QSocketNotifier::activated, this, &USBWatcher::handleDeviceChange);
    connect(this, SIGNAL(usbDeviceConnected()), parent, SLOT(USBDeviceConnected())); // 父类接收信号槽函数需自己实现。
    connect(this, SIGNAL(usbDeviceDisconnected()), parent, SLOT(USBDeviceDisconnected())); // 父类接收信号槽函数需自己实现。
    CheckConnectedUSBDevices();
}


void USBWatcher::CheckConnectedUSBDevices()
{
    QFile file("/proc/mounts");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
       qDebug() << "Error opening /proc/mounts";
    }

    file.seek(0);
    QTextStream in(&file);
    QString line = in.readLine();
    if(line.contains("/usb/sd"))
    {
         emit usbDeviceConnected();
         file.close();
         return ;
    }
    while(!line.isNull())
    {
       line= in.readLine();
       if(line.contains("/usb/sd"))
       {
           emit usbDeviceConnected();
           file.close();
           return ;
       }
    }

    file.close();
}

void USBWatcher::handleDeviceChange()
{
   // 从udev监视器接收设备事件
   struct udev_device *dev = udev_monitor_receive_device(monitor);
   if (dev) {
       const char *action = udev_device_get_action(dev);
       if (action) {
           QString devnode = udev_device_get_devnode(dev);
           if (devnode.startsWith("/dev/bus/usb")) {
               if (QString(action) == "add")
                   emit usbDeviceConnected();
               else if (QString(action) == "remove")
                   emit usbDeviceDisconnected();
           }
       }
       udev_device_unref(dev);
   }
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux 对于 TF(MicroSD)卡的支持相对较好,允许在系统运行过程中安全地插入和移除这些存储设备。热插拔(Hot Swap)是指在不关闭电源或重启系统的情况下更换硬件设备的能力,对于 TF 卡而言,这意味着你可以无需重启设备就能读写数据。 在 Linux 中实现 TF 卡热插拔,通常涉及以下几个步骤: 1. **USB 驱动支持**:确保你的系统已经加载了适当的 USB 驱动程序,如 U盘驱动,因为 MicroSD 卡通常是通过 USB 适配器连接到计算机的。 2. **挂载点设置**:你需要创建一个自动挂载点,当卡被插入时,Linux 会自动识别并将其添加到文件系统的某个目录中。可以在 `/etc/fstab` 文件中配置这个挂载点,或者使用 `udisksctl` 命令动态管理。 ```sh sudo nano /etc/fstab ``` 在这里添加类似这样的条目: ``` /dev/mmcblk0p1 /mnt/tfcard auto defaults,users,nofail,ro 0 0 ``` 其中 `/dev/mmcblk0p1` 是你的 TF 卡设备名,`/mnt/tfcard` 是挂载点。 3. **启用自动挂载**:可以通过修改 `/etc/crypttab` 或者使用 `udevd` 规则文件(如 `/etc/udev/rules.d/60-tfcard.rules`),使得系统在检测到新插入的 TF 卡时自动挂载。 4. **权限验证**:确保用户有足够的权限访问这个挂载点,可以通过 `chmod` 和 `chown` 命令调整文件夹权限。 5. **监控和安全**:尽管 Linux 支持热插拔,但为了保证数据完整性和系统稳定性,建议在操作后检查设备是否已成功挂载,并确认无数据丢失的情况。 需要注意的是,虽然大部分现代 Linux 发行版都支持 TF 卡热插拔,但在某些老旧版本、定制系统或者特定设备上可能存在兼容性问题。如果遇到问题,可以查阅文档或搜索解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值