Чтение с символьного устройства с помощью Qt - PullRequest
0 голосов
/ 10 января 2019

Я не очень хорош в символических устройствах, поэтому мне нужна ваша помощь. У нас есть устройство char (назовем его /dev/my_light), которое является датчиком света. Я должен прочитать данные из этого файла и преобразовать их в значение яркости, а затем передать их диспетчеру яркости, который изменяет яркость моего экрана. Проблема в том, что когда я читаю значение в течение некоторого периода времени, я получаю старые значения из файла. Я предполагаю, что есть буфер (опять же, не уверен, как именно работают символьные устройства). Тогда как при использовании cat /dev/my_light я вижу новые данные! Можно ли избавиться от буфера и прочитать новые значения, которые были записаны в файл прямо сейчас. Вот мой код в Qt:

    void MySensor::updateMySensor()
    {
        Packet packet;
        packet.startByte = 0;
        packet.mantissa = 0;
        packet.exp = 0;

        d->device = ::open(d->path.toStdString().c_str(), O_RDONLY);
        if (d->device == -1)
        {
            qDebug() << Q_FUNC_INFO << "can't open the sensor";
            return;
        }

        ssize_t size = ::read(d->device, &packet, sizeof(packet));
        close(d->device);

        if (size == -1)
        {
            qDebug() << errno;
            return;
        }

        packet.exp &= 0x0F;

        float illumination = pow(2, packet.exp) * packet.mantissa * 0.045;

        if(d->singleShot) emit lightSensorIsRunning(true);
        emit illuminationRead(illumination);
    }

Функция mySensor вызывается каждую секунду. Я пытался называть это каждые 200 мсек, но это не помогло. Значение освещения остается старым в течение примерно 7 секунд (!), Тогда как значение, которое я получаю из cat, является новым сразу же.

Заранее спасибо!

1 Ответ

0 голосов
/ 11 января 2019

Я не могу проверить ваше конкретное устройство, однако я использую клавиатуру в качестве устройства только для чтения.

Программа пытается подключиться к клавиатуре и прочитать все клавиши, нажимаемые внутри и снаружи окна. Это широкое решение, которое вам нужно будет адаптировать под свои требования.

Обратите внимание, что я открываю файл с помощью O_RDONLY | O_NONBLOCK, что означает открытие в режиме только для чтения и не нужно ждать запуска события (какой-то уведомитель должен был знать, когда данные готовы!) Соответственно.

Для запуска этого примера вам понадобятся привилегии суперпользователя!

#include <QtCore>
#include <fcntl.h>
#include <linux/input.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    const char *device_name = "/dev/input/by-path/platform-i8042-serio-0-event-kbd";

    int descriptor = open(device_name, O_RDONLY | O_NONBLOCK);

    if (descriptor < 0)
    {
        qDebug() << "Error" << strerror(errno);
        return a.exec();
    }

    QFile device;

    if (!device.open(descriptor, QFile::ReadOnly))
    {
        qDebug() << "Error" << qPrintable(device.errorString());
        return a.exec();
    }

    QSocketNotifier notifier(device.handle(), QSocketNotifier::Read);

    QObject::connect(&notifier, &QSocketNotifier::activated, &notifier, [&](int socket){
        Q_UNUSED(socket)

        struct input_event ev;

        QByteArray data = device.readAll();

        qDebug() << "Event caught:"
                 << "\n\nDATA SIZE" << data.size()
                 << "\nSTRUCT COUNT" << data.size() / int(sizeof(input_event))
                 << "\nSTRUCT SIZE" << sizeof(input_event);

        qDebug() << ""; //New line

        while (data.size() >= int(sizeof(input_event)))
        {
            memcpy(&ev, data.data(), sizeof(input_event));

            data.remove(0, int(sizeof(input_event)));

            qDebug() << "TYPE" << ev.type << "CODE" << ev.code << "VALUE" << ev.value << "TIME" << ev.time.tv_sec;
        }

        qDebug() << ""; //New line
    });

    return a.exec();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...