通过子线程接收数据,发送到每个页面之后,接收函数解析数据,定时器根据解析结果下发。
当前未加入校验代码,可正常运行。
主要函数如下:
/**
* @brief UpdateWidget::onBrowserBtnClicked
*/
void UpdateWidget::onBrowserBtnClicked()
{
qDebug() << "onBrowserBtnClicked";
QFileDialog dlg;
QStringList filters;
//获取用户选择文件,显示路径
fileName = QFileDialog::getOpenFileName(this, ("打开文档文件"),"./",tr("文档后缀(*.*)"));
qDebug()<<fileName;
label_selepath->clear();
label_selepath->setText(fileName);
textdis->append(QString("%1,%2:%3").arg(QTime::currentTime().toString("HH:mm:ss")).arg("已选择文件").arg(fileName));
//获取并显示文件大小
QFileInfo *pcsfileInfo = new QFileInfo(fileName);
dataLen = pcsfileInfo->size ();
textdis->append(QString("%1,%2:%3").arg(QTime::currentTime().toString("HH:mm:ss")).arg("文件大小").arg(dataLen));
}
/**
* @brief UpdateWidget::onBtnLoadClicked
*/
void UpdateWidget::onBtnLoadClicked()
{
if(fileName.isEmpty())
{
textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("请先选择文件!"));
}
else
{
readfile();
DLoadBar->setRange(0,total); //设置进度条最小值和最大值(取值范围)
textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("开始下载!"));
emit viewTransmitData("FirmWare", "Download", loadStringList->at(0), 1);
// downLoadFlag = true; //打开下载标志位
timer->start(100); //打开定时器
}
}
void UpdateWidget::readfile()
{
//读取文件
binFile = new QFile(fileName);
binFile->open (QIODevice::ReadOnly);
allDataArray = binFile->readAll();
//1.初始化计数参数和存储容器
int crc=0, length=512, listSeq=1;
QString datastring;
QByteArray temdata;
loadStringList = new QStringList;
int binfileseek = 0;
//计算下载数据包数量total
if(dataLen%512 >0)
{ total = (dataLen/512)+1; }
else
{ total = dataLen/512; }
textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("开始读取!"));
//2.1 装填发送包
for(int i=0; i<=total; i++)
{
if(binfileseek >= dataLen) //2.1.1 已经全部装填
{
textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("读取完成!"));
binfileseek = 0;
allDataArray.clear();
binFile->close();
}
else if((dataLen-binfileseek) > length) //2.1.2 还有大于一包没装填
{
for (int i=0; i<length; i++, binfileseek++)
{ temdata[i] = allDataArray.at(binfileseek); }
}
else //2.1.3 还有最后一包没装填
{
int lastdata = dataLen-binfileseek;
for (int i=0; i<lastdata; binfileseek++, i++)
{ temdata[i] = allDataArray.at(binfileseek); }
}
//2.1.4 发送包格式转换
datastring.prepend(temdata);
temdata.clear();
Command *cmd = new Command;
QString loadData = cmd -> prepareLoadingData(QString(total), QString(listSeq), QString(crc), datastring);
datastring.clear();
loadStringList->append(loadData);
loadData.clear();
listSeq++;
qDebug() << "loadStringList:" << loadStringList->at(i);
}
}
/**
* @projectName TBoxSoft
* @brief 定时器处理子函数,定时发送数据
* @author chenfuhao
* @date 2019-12-11
*/
void UpdateWidget::timerSend()
{
static int seq=1, sendHistory=0;
//3 判断对方上一个包回复结果,决定是否发送当前包
if(resultValue ==0 && seqValue == seq && nextValue == seq+1) // 3.1 收到正常回复,继续判断是否发送下一个包
{
if(seqValue < total) // 发送未结束,发送下一个包
{
seq++; // 包序号增加
emit viewTransmitData("FirmWare", "Download", loadStringList->at(seq-1), 1);
DLoadBar->setValue(seqValue); //设置当前进度条值
textdis->append(QString("%1,已发送:当前/总数= %2/%3").arg(QTime::currentTime().toString("HH:mm:ss")).arg(seq).arg(total));
textdis->moveCursor(QTextCursor::End); //textdis显示最新消息
}
else // 发送完成,更新状态,停止发送
{
DLoadBar->setValue(int(total)); //设置当前的运行值为100%
textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("下载完成!"));
textdis->moveCursor(QTextCursor::End); //textdis显示最新消息
loadStringList->clear();
seq = 1;
retryNum = 0;
timer->stop();
return;
}
}
else if(resultValue == 1) //3.2 设备处理结果为“失败”
{
textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("接收设备处理数据包失败,终止下载!"));
loadStringList->clear();
seq = 1;
retryNum = 0;
timer->stop();
return;
}
if(signalType == 4) //3.3 接收回复超时处理,signalType为超时标志位
{
signalType = 0;
//判断是否为当前包超时,是当前包则继续计数,不是当前包则重新计数
if(sendHistory != nextValue)
{
sendHistory = nextValue;
retryNum = 0;
retryNum++;
textdis->append(QString("%1,当前包回复超时次数为:%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg(retryNum));
}
else {
retryNum++;
textdis->append(QString("%1,当前包回复超时次数为:%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg(retryNum));
}
//判断当前包超时次数,超过5次则放弃下载
if(retryNum > 5)
{
textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("对方无回复,终止下载!"));
loadStringList->clear();
retryNum = 0;
timer->stop();
return;
}
//判断当前下载包序号,有针对性重发,nextValue初始为0,收到第一个回复则变为2
if(nextValue == 0)
{
emit viewTransmitData("FirmWare", "Download", loadStringList->at(0), 1);
}
else
{
emit viewTransmitData("FirmWare", "Download", loadStringList->at(nextValue-1), 1);
}
}
}