Unexpected QT5 QTimer duration on ARM
我正在QT控制台应用程序上执行以在ARM CPU上执行,并且遇到了QTimer的一个非常奇怪的行为:该计时器不是计划的100毫秒,而是在1946毫秒后过期。我更改了持续时间,但是观察到的行为没有改变(大约几毫秒,例如1958 ms,而不是40 ms)。
当在x86_AMD64上执行相同的代码时(我将调用搁置在特定的HW API函数上;在没有QTimer插槽的情况下执行该函数所需的时间少于3 ms),计时器持续时间为预期的+/- 100 ms。
注意:嵌入式QT版本为5.4.1; PC QT的版本是5.9.5
我尝试了不同的持续时间,包括0。到期时间大致相同。
我监视了CPU使用率(小于30%)和平均负载(小于0.15)。
我还编写了一个小型QT控制台应用程序,该应用程序启动了一些不同持续时间的计时器,并记录了经过的时间。结果是正确的(经过的时间漂移??,如"预期";),所以我认为buildchain和嵌入式QT安装是好的。
我在初始代码中添加了QElapsedTimer,并以40 ms QTimer的slot方法记录了经过的时间。
我在PC上获得了跟踪:
在ARM上,跟踪是不同的,持续时间约为2秒,而不是预期的+/- 40 ms:
我需要您的帮助来了解为什么我的QTimer不能按预期过期,或者有任何线索可以针对目标进行调查,这可能阻止我的计时器过期。
谢谢你的想法。
最好的祝福,
编辑:根据要求,代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | const int CDoorManagement::I_DOOR_LOCKING_DURATION_MS = 40; const int CDoorManagement::I_DOOR_LOCKING_ALARM_DURATION_MS = 12000; CDoorManagement::CDoorManagement(CInputOutputManagerPtr ioPtr) : QObject(nullptr) , mIOManagerPtr(ioPtr) , mOperationElapsedTimer() , mDoorLockingTimer() , mDebugMessages() { connect(&mDoorLockingTimer, SIGNAL(timeout()), this, SLOT(slotDoorLocking()), Qt::UniqueConnection); } void CDoorManagement::slotDoorLocking() { const auto elapsedTime = mOperationElapsedTimer.elapsed(); if (elapsedTime > I_DOOR_LOCKING_ALARM_DURATION_MS) { mDoorLockingTimer.stop(); mIOManagerPtr->setActuator(OUTPUT_DOOR_LOCKING_ACTUATOR, false); mDebugMessages << QString("elapsed time = %1 ms - INPUT_DOOR_LOCKED_SENSOR=%2 - INPUT_DOOR_UNLOCKED_SENSOR=%3 - time = %4") .arg(elapsedTime) .arg(mIOManagerPtr->getTorInputState(INPUT_DOOR_LOCKED_SENSOR)?"true":"false") .arg(mIOManagerPtr->getTorInputState(INPUT_DOOR_UNLOCKED_SENSOR)?"true":"false") .arg(mOperationElapsedTimer.elapsed()); qDebug() <<"door locking - mDebugMessage =" << mDebugMessages; abort(QSTR_LOCKING_ABORTED); } if(mIOManagerPtr->getTorInputState(INPUT_DOOR_LOCKED_SENSOR)) { mDoorLockingTimer.stop(); mIOManagerPtr->setActuator(OUTPUT_DOOR_LOCKING_ACTUATOR, false); syslog(LOG_INFO,"%s::%s() - locked: elapsedTime = %lld, max time=%d", LOG_PREFIX, __FUNCTION__, elapsedTime, I_DOOR_LOCKING_ALARM_DURATION_MS); mDebugMessages << QString("elapsed time = %1 ms - INPUT_DOOR_LOCKED_SENSOR=%2 - INPUT_DOOR_UNLOCKED_SENSOR=%3 - time = %4") .arg(elapsedTime) .arg(mIOManagerPtr->getTorInputState(INPUT_DOOR_LOCKED_SENSOR)?"true":"false") .arg(mIOManagerPtr->getTorInputState(INPUT_DOOR_UNLOCKED_SENSOR)?"true":"false") .arg(mOperationElapsedTimer.elapsed()); qDebug() <<"door locking - mDebugMessage =" << mDebugMessages; emit signalDoorLocked(); } else { mDebugMessages << QString("elapsed time = %1 ms - INPUT_DOOR_LOCKED_SENSOR=%2 - INPUT_DOOR_UNLOCKED_SENSOR=%3 - time = %4") .arg(elapsedTime) .arg(mIOManagerPtr->getTorInputState(INPUT_DOOR_LOCKED_SENSOR)?"true":"false") .arg(mIOManagerPtr->getTorInputState(INPUT_DOOR_UNLOCKED_SENSOR)?"true":"false") .arg(mOperationElapsedTimer.elapsed()); } } void CDoorManagement::startLocking() { mDebugMessages.clear(); qDebug() <<"start of mDoorLockingTimer using" << I_DOOR_LOCKING_DURATION_MS <<" ms delay"; mOperationElapsedTimer.start(); mDoorLockingTimer.start(I_DOOR_LOCKING_DURATION_MS); if(!mIOManagerPtr->setActuator(OUTPUT_DOOR_LOCKING_ACTUATOR, true)) { mIOManagerPtr->setActuator(OUTPUT_DOOR_LOCKING_ACTUATOR, false); syslog(LOG_WARNING,"%s::%s() - failed to activate OUTPUT_DOOR_LOCKING_ACTUATOR", LOG_PREFIX, __FUNCTION__); abort(QSTR_LOCKING_ACTIVATION_FAILURE); } } |
我发现了观察到的行为的根本原因:在示例插槽中,我读取了一个数字输入,并且此读取需要3毫秒。 在另一个插槽中,我读取了两个RTD输入,而这些读数最多需要2000毫秒。 数字量和RTD输入的读取使用相同的库,其中有一个互斥锁来访问硬件,无论是访问数字量还是访问RTD :(