Я пытаюсь интегрировать функциональность обновления прошивки в приложение Witty.
Приложение связывается с внешним устройством с помощью /dev/ttyUSB0
этот же порт используется для обновления прошивки, при этом приложение освобождает порт и вызывает приложение внешней командной строки через popen()
,
Основная проблема заключается в том, что он отлично работает при выполнении в основном, но не при выполнении из примера события:
m_pUploadButton->clicked().connect(std::bind([=] () {
pComputer->firmwareUpgrade();
}));
Вот определения соответствующих функций:
bool ComputerV2::upgradeFirmware()
{
m_oMutex.lock();
std::string sFile = "/home/alextown/MPLABXProjects/ordinateur_V2/dist/default/production/ordinateur_V2.production.hex";
std::string sResult = "";
std::string sCommand = "/home/alextown/QtProjects/build-pic32ubl-qt-qt5-Release/pic32ubl-qt --headless --port=/dev/" + m_sPort + " --file=" + sFile + " --erase --program --verify --jump-application";
std::cout << sCommand << std::endl;
int nResult = exec(sCommand,sResult);
std::cout << sResult << std::endl;
m_oMutex.unlock();
return nResult == 0;
}
int exec(std::string p_sCommand, std::string &p_sResult)
{
FILE *pipe = popen(p_sCommand.c_str(),"r");
p_sResult = "";
if(!pipe) return -1;
char buffer[128];
while(!feof(pipe))
{
if(fgets(buffer,128,pipe) != NULL)
{
p_sResult += buffer;
}
}
return pclose(pipe);
}
Из того, что я наблюдал, при запуске обновления из main
, все работает отлично (перепрыгнуть устройство в режиме апгрейда, обновить и перепрыгнуть в обычном режиме) При запуске из виджета данные отправляются через порт /dev/ttyUSB0
это не то же самое, что вызывает проблемы со связью и обновление не удалось.
Насколько я понимаю, в виджете Witty работает поток, отличный от потока, запущенного для основного приложения.
Я настоятельно рекомендую сделать это обновление во внешней теме или std::launch::async'ed
std :: future`, поскольку потоки Wt действительно специальный.
Специальные средства, они могут быть запущены в каком-то пуле потоков, а также могут быть запущены в контексте, то есть в процессе веб-сервера (хотя я думаю, что вы в настоящее время развернули его через встроенный http-сервер, но представьте, что вы хотите повторно использовать свой код ).
Так есть ли в вашем USB-драйвере какой-то специфический процесс (глобальные переменные, состояние и т. Д.). Тогда лучше всего сделать это обновление в новом созданном процессе, помимо вашего веб-приложения (некоторые называют этот подход микросервиса, чтобы сделать эту старую технику более нарядной).
Wt предлагает методы для синхронизации с внешними событиями, если требуется.
Увидеть Wt::WApplication::bind
а также Wt::Server::post
,
Разделение этой работы также имеет то преимущество, что ваше веб-приложение все еще отвечает во время обновления, что, вероятно, займет некоторое время. Кроме того, если обновление вызывает некоторые серьезные проблемы, вашему веб-приложению намного проще доставлять диагностические сообщения или выполнять более эффективные действия.
Других решений пока нет …