我试图在Witty应用程序中集成固件升级功能。
应用程序使用/dev/ttyUSB0
与外部设备通信,相同的端口用于固件升级,这样,应用程序释放端口并通过popen()
调用外部命令行应用程序。
主要问题是它在main中执行时完全正常,但不是从事件示例执行时:
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小部件的线程运行方式与主要应用程序的线程运行方式有所不同。
答案 0 :(得分:1)
我强烈建议在外部线程或std::launch::async'ed
std :: future`中进行此更新,因为Wt线程确实是特殊。
特殊意味着,它们可能在某种线程池中运行,也可能在上下文中运行,即web服务器的进程(虽然我猜你当前通过内置的http-server部署它,但想象你想要重用你的代码。)
你的USB驱动程序是否有特定的进程(全局,状态等?)然后最好是在新的创建过程中进行升级,除了你的web应用程序(有人称之为微服务)方法,让这种旧技术看起来更加花哨)。
如果需要,Wt提供与外部事件同步的方法。
请参阅Wt::WApplication::bind
和Wt::Server::post
。
分离此工作还有一个好处,即您的Web应用程序在升级时仍会响应,这可能需要一些时间。此外,如果升级导致一些重大问题,您的Web应用程序可以更轻松地发送诊断消息或接管更好的问题。