您的位置:首页 > 编程语言 > Qt开发

Qt flash_eraseall nandwrite 进度条显示擦除、烧录

2015-10-07 11:53 405 查看
/*****************************************************************************
*              Qt flash_eraseall nandwrite 进度条显示擦除、烧录
* 声明:
*   当我们在 Linux shell中执行nand擦除、烧入程序时,我们可以通过终端查看
* 过程,但是有时候我们可能希望能够有个界面,这样会更直观的提供当前的程序
* 的执行状态,于是个人写了这个Demo,目前暂时使用。
*
*                                   2015-10-7 雨 深圳 南山平山村 曾剑锋
****************************************************************************/

|\\\\\\\\-*- 目录 -*-///////
|  一、cat main.cpp
|  二、cat mainwindow.h
|  三、cat mainwindow.cpp
|  四、cat thread.h
|  五、cat thread.cpp
\\\\\\\\\\\\\\/////////////

一、cat main.cpp
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

/**
* 窗口最大化,不允许最小化
*/
MainWindow w;
w.setWindowFlags(w.windowFlags()& ~Qt::WindowMaximizeButtonHint& ~Qt::WindowMinimizeButtonHint);
w.showMaximized();
w.show();

return a.exec();
}

二、cat mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "thread.h"

/**
* shell command:
*    nandwrite -p /dev/mtd7 ubi.img
* ......
* Writing data to block 724 at offset 0x5a80000
* Writing data to block 725 at offset 0x5aa0000
* Writing data to block 726 at offset 0x5ac0000
* Writing data to block 727 at offset 0x5ae0000
* Writing data to block 728 at offset 0x5b00000
* Writing data to block 729 at offset 0x5b20000
* Writing data to block 730 at offset 0x5b40000
*
* 这个值要设置得相对大一点比较好,这样就不会出现比100%还大得情况
*/
#define NANDWRITEBLOCKCOUNTS 740

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

protected:
void moveEvent(QMoveEvent *);
void resizeEvent(QResizeEvent *);
void closeEvent(QCloseEvent *);

public slots:
/**
* 与线程对应的三个信号处理函数
*/
void dealNandEraseMesg(QString string);
void dealNandWriteMesg(QString string);
void dealTitleMesg(QString string);

private:
Ui::MainWindow *ui;
Thread *thread;
};

#endif // MAINWINDOW_H

三、cat mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QProcess>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

/**
* 创建线程来处理nand的擦除、写入,主要是避免在MainWindow的UI线程中处理事务,
* 这样可以避免UI界面不能及时显示改变的数据界面,这在Android的开发中也会
* 遇到这种情况,类似的处理方式。
*/
thread = new Thread();
connect(thread, SIGNAL(nandEraserMesg(QString)), this, SLOT(dealNandEraseMesg(QString)));
connect(thread, SIGNAL(titleMesg(QString)), this, SLOT(dealTitleMesg(QString)));
connect(thread, SIGNAL(nandWriteMesg(QString)), this, SLOT(dealNandWriteMesg(QString)));
thread->start();
}

void MainWindow::dealNandEraseMesg(QString string) {
ui->progressBar->setValue(string.toInt());
}

void MainWindow::dealNandWriteMesg(QString string) {
int rate = string.toInt()*100/NANDWRITEBLOCKCOUNTS;
/**
* 由于最后为了确保显示了100,我传了1000过来这个远大于NANDWRITEBLOCKCOUNTS的值
* 所以这里需要这样操作来避免显示大于100的值
*/
rate = rate >= 100 ? 100 : rate;
ui->progressBar->setValue(rate);
}

void MainWindow::dealTitleMesg(QString string) {
ui->title->setText(string);
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::moveEvent(QMoveEvent *)
{
/**
* 防止窗口被移动
*/
this->move(QPoint(0,0));
}

void MainWindow::resizeEvent(QResizeEvent *)
{
this->showMaximized();
}

void MainWindow::closeEvent(QCloseEvent *)
{
exit(0);
}

四、cat thread.h
#ifndef THREAD_H
#define THREAD_H

#include <QThread>
#include <QProcess>
#include <QDebug>

class Thread : public QThread
{
Q_OBJECT
public:
explicit Thread(QObject *parent = 0);

signals:
/**
* 数据处理过程中,需要用到的三个信号
*/
void titleMesg(QString string);
void nandEraserMesg(QString string);
void nandWriteMesg(QString string);

public slots:
void run();
/**
* 判断字符串是不是数字组成的:
* 返回值:
*    0:表示是纯数字组成的;
*    1:表示不是纯数字组成的。
*/
int isDigitStr(QString src);
};

#endif // THREAD_H

五、cat thread.cpp
#include "thread.h"
#include <stdio.h>
#include <unistd.h>
#include <QByteArray>
#include <QStringList>

Thread::Thread(QObject *parent) :
QThread(parent)
{
}

/**
* 重写的run()方法
*/
void Thread::run()
{
QString readBuffer;

/**
* 擦除的时候使用QProcess来处理
*/
QProcess process;
process.start("flash_eraseall /dev/mtd7");
process.waitForFinished(-1); // will wait forever until finished

/**
* 显示正在做的事
*/
emit titleMesg("erase rootfs...");
while ( !process.atEnd() ) {                // 没有到数据末尾
if ( process.canReadLine() ) {          // 有数据可读
readBuffer = process.readLine(512); // 读取数据

/**
* Erasing 128 Kibyte @ ca40000 -- 81 % complet"
* Erasing 128 Kibyte"  e560000 -- 92 % complete
* " asing 128 Kibyte @ e980000 -- 93 % complete
* Erasing 128 Kibyte @ eae0000 -- 94 % comp" te
* Erasing 128 Kibyt" @ f040000 -- 96 % complete
* Erasing 128 Kibyte @ f460000 -- 98 % complete "
*
* 以下代码主要是为了获取上面输出中的百分比数值
*/
// 正则表达式分割数据
QStringList currentLine = readBuffer.split(QRegExp("[\\s]+"));
if ( currentLine.length() > 7 ) {   // 我们需要第六个字段
// 第六个字段是否是由纯数字组成
if ( !isDigitStr( currentLine[6]) ) {
// 将数据发送给UI线程去处理
emit nandEraserMesg(currentLine[6]);
//qDebug() << readBuffer;
}
}
}
}
emit nandEraserMesg(QString(100));          // 擦除数据完毕

/**
* 1. shell命令行下执行 nandwrite -p /dev/mtd7 ubi.img 的输出:
*      Writing data to block 47 at offset 0x5e0000
*      Writing data to block 48 at offset 0x600000
*      Writing data to block 49 at offset 0x620000
*      Writing data to block 50 at offset 0x640000
*      Writing data to block 51 at offset 0x660000
* 2. 在编码测试过程中发现使用QProcess无法获取到nandwrite执行过程中的数据,
*     仅仅在处理完毕的时候才会收到数据,所以处理效果不好;
* 3. 所以改用popen来做这件事,但是popen也仅仅是比QProcess好那么一点,每次
*     都是以12%的梯度增长,虽然还是没有像shell中运行的效果,但目前勉强还
*     是能用,所以这里也就暂时这么做;
* 4. 目前没找到更好的办法在解决这个事情。
*/
char buff[64];
FILE *fp = popen("nandwrite -p /dev/mtd7 ubi.img", "r");

int count = 0;
emit titleMesg("update rootfs...");
while (!feof(fp)) {
fgets(buff, 64, fp );
emit nandWriteMesg(QString::number(count++));
}
pclose(fp);
// 这里仅仅是为了保证processor bar一定显示100%才这么做的,没其他的意思
emit nandWriteMesg("1000");

// 显示更新完毕
emit titleMesg("rootfs update over.");
}

int Thread::isDigitStr(QString src)
{
//QString 转换为 char*
QByteArray ba = src.toLatin1();
const char *s = ba.data();

/**
* 字符的二进制值是否在'0'、'9'之间
*/
while(*s && *s>='0' && *s<='9') s++;

if (*s) {     //不是纯数字
return -1;
} else {     //纯数字
return 0;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: