从Wt小部件信号事件运行popen()的问题

时间:2016-04-18 20:14:19

标签: c++ popen tty wt

我试图在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小部件的线程运行方式与主要应用程序的线程运行方式有所不同。

1 个答案:

答案 0 :(得分:1)

我强烈建议在外部线程或std::launch::async'ed std :: future`中进行此更新,因为Wt线程确实是特殊

特殊意味着,它们可能在某种线程池中运行,也可能在上下文中运行,即web服务器的进程(虽然我猜你当前通过内置的http-server部署它,但想象你想要重用你的代码。)

你的USB驱动程序是否有特定的进程(全局,状态等?)然后最好是在新的创建过程中进行升级,除了你的web应用程序(有人称之为微服务)方法,让这种旧技术看起来更加花哨)。

如果需要,Wt提供与外部事件同步的方法。 请参阅Wt::WApplication::bindWt::Server::post

分离此工作还有一个好处,即您的Web应用程序在升级时仍会响应,这可能需要一些时间。此外,如果升级导致一些重大问题,您的Web应用程序可以更轻松地发送诊断消息或接管更好的问题。