从/ dev / input / event *读取时QT GUI线程卡住

时间:2015-06-18 10:00:40

标签: qt gpio

我正在运行QT嵌入式应用程序(4.8.5),发现导致GUI线程挂起的问题。

下面是按钮代码。

const char* PushButtonService::m_eventfile = "/dev/input/event1";
PushButtonService::PushButtonService(QObject *parent): m_stop(false), m_pressed(false)
{
    m_sockfd = open(m_eventfile, O_RDONLY);
    m_notifier = new QSocketNotifier(m_sockfd, QSocketNotifier::Read, this);
    connect(m_notifier, SIGNAL(activated(int)), this, SLOT(readBtnEvts()));
    m_notifier->setEnabled(true);    
} 
void PushButtonService::readBtnEvts()
{
    QLOG_TRACE() << "read evts";
    struct input_event events[64];

QMutexLocker locker(&m_mutex);
int bytes = read(m_sockfd, events, sizeof(struct input_event));
if (bytes < (int) sizeof(struct input_event)) {
    QLOG_TRACE() << "no evts";
    return;
}

for (int i = 0; i < bytes / sizeof(struct input_event); i++){
    if (events[i].type == EV_KEY ) {
        if (events[i].value == 2) {
            if ( ! m_pressed ) {
                QLOG_TRACE() << "Emergency Pressed";
                emit emergencyPressed();
                m_pressed = true;
            }
        }else if (events[i].value == 0){
            if (m_pressed){
                QLOG_TRACE() << "Emergency Released";
                emit emergencyReleased();
                m_pressed = false;
            }
        }
    }
}
}
PushButtonService::~PushButtonService()
{
    close(m_sockfd);
    delete m_notifier;
}

以下是GUI框架:

m_emergency_frame = new EmergencyFrame(this, m_language);
m_emergency_frame->hide();

m_push_button = new PushButtonService(this);
connect(m_push_button, SIGNAL(emergencyPressed()), this,    SLOT(emergencyPressed()));
connect(m_push_button, SIGNAL(emergencyReleased()), this, SLOT(emergencyReleased()));

void MainFerryFrame::emergencyPressed(){
QLOG_TRACE() << "Button pressed";
m_emergency_frame->show();
m_emergency_frame->raise();
}

 void MainFerryFrame::emergencyReleased()
{
    QLOG_TRACE() << "Button released";
    m_emergency_frame->hide();
}

我可以在开始时获得按钮事件,但是在重复一些之后,GUI应用程序挂起,并且在应用程序出现时回溯:

(gdb) bt
#0  0xb650a378 in read () from /lib/arm-linux-gnueabihf/libpthread.so.0
#1  0xb69c81c0 in ?? () from /usr/lib/libQtGui.so.4
#2  0xb6632bf4 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /usr/lib/libQtCore.so.4
#3  0xb6667f2a in QSocketNotifier::activated(int) () from /usr/lib/libQtCore.so.4
#4  0xb6638106 in QSocketNotifier::event(QEvent*) () from /usr/lib/libQtCore.so.4
#5  0xb69cf818 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/libQtGui.so.4
#6  0xb69d123a in QApplication::notify(QObject*, QEvent*) () from /usr/lib/libQtGui.so.4
#7  0x000d7028 in ?? ()
Cannot access memory at address 0x2044
#8  0x000d7028 in ?? ()
Cannot access memory at address 0x2044
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

任何线索?

1 个答案:

答案 0 :(得分:0)

m_sockfd = open(m_eventfile, O_RDONLY);

我相信这将执行阻止读取,除非设置了O_NONBLOCK。这是因为当您收到通知时,无法保证有64个事件可用。

您应该在自己的Qthread中执行PushButtonService个对象。

m_push_button = new PushButtonService(0);
m_service_thread = new QThread();

m_push_button->moveToThread(m_service_thread);

您必须在插槽中移动PushButtonService构造函数的所有设置(即bootstrap),并将其连接到QThread的开始信号。