用Qt读取字符设备
我不太擅长角色设计,所以我需要你的帮助。A有一个char设备,我们称之为/dev/my_light,它是一个光传感器。我必须从这个文件中读取数据,并将其转换为亮度值,然后将其传递给亮度管理器,以更改屏幕的亮度。问题是,当我读取一段时间的值时,我会从文件中获取旧值。我假设有一个缓冲区,但我不确定字符设备到底是如何工作的。然而,当我使用cat/dev/my_light时,我看到了新的数据!是否可以去掉缓冲区并读取刚刚写入文件的新值。以下是我在Qt中的代码:用Qt读取字符设备,qt,file,Qt,File,我不太擅长角色设计,所以我需要你的帮助。A有一个char设备,我们称之为/dev/my_light,它是一个光传感器。我必须从这个文件中读取数据,并将其转换为亮度值,然后将其传递给亮度管理器,以更改屏幕的亮度。问题是,当我读取一段时间的值时,我会从文件中获取旧值。我假设有一个缓冲区,但我不确定字符设备到底是如何工作的。然而,当我使用cat/dev/my_light时,我看到了新的数据!是否可以去掉缓冲区并读取刚刚写入文件的新值。以下是我在Qt中的代码: void MySensor::up
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得到的值是新的
提前谢谢你 我无法使用您的特定设备进行测试,但是,我将键盘用作只读设备 程序尝试连接到键盘并读取窗口内外按下的所有键。这是一个广泛的解决方案,你必须适应以满足你的需求 请注意,我正在使用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(¬ifier, &QSocketNotifier::activated, ¬ifier, [&](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();
}
我们不确定该设备的具体细节,因此无法对答案充满信心。当然,如果设备上没有更新,您可能会从中获得相同的值。我们如何知道新数据可用?根据我过去的经验,一些设备会发出新数据的信号,我们可以使用POSIX select或epoll对它们进行监视。看起来有点像相关文章:@Alexandev thanxs为您解答!问题是,对于cat,我现在可以看到新的值。在我的程序中,我在7秒后看到它们,正如我上面所说的。我不明白为什么。也许我的问题不是很清楚,它起作用了!非常感谢。但为什么有必要同时使用O_非块O_NDELAY?它们是一样的……还是我错了?QSocketNotifier就是那个使用基础select或epoll的东西。@PolinaBodnar:没错,O_NDELAY是O_NONBLOCK的过时名称,不应该在新的应用程序中使用。我将从答案中删除它!