Я работаю над консольным приложением QT для выполнения на процессоре ARM, и я столкнулся с очень странным поведением QTimer: вместо запланированных 100 мс таймер истек через 1946 мс. Я изменил продолжительность, но наблюдаемое поведение не изменилось (около нескольких миллисекунд, например, 1958 мс вместо 40 мс). Когда тот же код выполняется на x86_AMD64 (я заглушил вызов конкретной функции HW API; выполнение этой функции без слота QTimer требует менее 3 мс), длительность таймера, как и ожидалось, составляет +/- 100 мс.
Примечание: версия встроенного QT — 5.4.1; версия ПК QT 5.9.5
Я пробовал разные длительности, в том числе 0. Срок действия примерно такой же продолжительности.
Я отслеживал загрузку ЦП (менее 30%) и среднюю нагрузку (менее 0,15).
Я также написал небольшое консольное приложение QT, которое запускает несколько таймеров разной продолжительности и регистрирует прошедшее время. Результаты правильные (прошедшее время дрейфует, как «ожидалось»;), поэтому я думаю, что buildchain и встроенная установка QT хороши.
Я добавил к своему исходному коду QElapsedTimer и зарегистрировал прошедшее время в методе слота 40 мс QTimer.
Я получил трассировку на ПК:
mDebugMessage = ("elapsed time = 42 ms - INPUT_DOOR_LOCKED_SENSOR=false - INPUT_DOOR_UNLOCKED_SENSOR=true - time = 46", "elapsed time = 81 ms - INPUT_DOOR_LOCKED_SENSOR=false - INPUT_DOOR_UNLOCKED_SENSOR=true - time = 81", "elapsed time = 122 ms - INPUT_DOOR_LOCKED_SENSOR=false - INPUT_DOOR_UNLOCKED_SENSOR=true - time = 122", "elapsed time = 162 ms - INPUT_DOOR_LOCKED_SENSOR=false - INPUT_DOOR_UNLOCKED_SENSOR=false - time = 163", "elapsed time = 201 ms - INPUT_DOOR_LOCKED_SENSOR=false - INPUT_DOOR_UNLOCKED_SENSOR=false - time = 201", "elapsed time = 242 ms - INPUT_DOOR_LOCKED_SENSOR=false - INPUT_DOOR_UNLOCKED_SENSOR=true - time = 242", "elapsed time = 281 ms - INPUT_DOOR_LOCKED_SENSOR=false - INPUT_DOOR_UNLOCKED_SENSOR=false - time = 281", ...
На ARM трассировка другая, вместо ожидаемых +/- 40 мс продолжительность около 2 секунд:
mDebugMessage = ("elapsed time = 1958 ms - INPUT_DOOR_LOCKED_SENSOR=false - INPUT_DOOR_UNLOCKED_SENSOR=false - time = 1961", "elapsed time = 3916 ms - INPUT_DOOR_LOCKED_SENSOR=false - INPUT_DOOR_UNLOCKED_SENSOR=false - time = 3919", "elapsed time = 5873 ms - INPUT_DOOR_LOCKED_SENSOR=false - INPUT_DOOR_UNLOCKED_SENSOR=false - time = 5876", "elapsed time = 7830 ms - INPUT_DOOR_LOCKED_SENSOR=false - INPUT_DOOR_UNLOCKED_SENSOR=false - time = 7833", "elapsed time = 9787 ms - INPUT_DOOR_LOCKED_SENSOR=false - INPUT_DOOR_UNLOCKED_SENSOR=false - time = 9790", "elapsed time = 11744 ms - INPUT_DOOR_LOCKED_SENSOR=false - INPUT_DOOR_UNLOCKED_SENSOR=false - time = 11747", "elapsed time = 13700 ms - INPUT_DOOR_LOCKED_SENSOR=false - INPUT_DOOR_UNLOCKED_SENSOR=false - time = 13705", ...
Мне нужна ваша помощь, чтобы понять, почему мой QTimer не истекает, как ожидалось, или любая подсказка, чтобы исследовать цель, что может помешать истечению моего таймера.
Спасибо за вашу идею.
С наилучшими пожеланиями,
РЕДАКТИРОВАТЬ: как и требовалось, код
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);
}
}