Qt5hex转binC++·

基于QT5的.hex转.bin的C++实现

Hugh

Hugh

78 0

1.头文件hex2bin.h

// hex2bin.h
#ifndef HEX2BIN_H
#define HEX2BIN_H

#include <QString>
#include <QList>
#include <QByteArray>

typedef unsigned char uint8_t;
typedef unsigned int  uint32_t;

struct Section {
uint32_t startAddr;
uint32_t endAddr;
QByteArray data;
};

enum IntelCommand : uint8_t {
UNKNOWN         = 0xFF,
DATA            = 0x00,
EOF_RECORD      = 0x01,
EXT_SEGMENT_ADDR= 0x02,
SEGMENT_ADDR    = 0x03,
EXTEND_ADDR     = 0x04,
LINEAR_ADDR     = 0x05,
};

bool ry_hex2bin(const QString& hexFilePath, const QString& binFilePath, quint32& startAddress);

#endif // HEX2BIN_H

2.源代码hex2bin.cpp


C++
// hex2bin.cpp
#include "hex2bin.h"
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QList>
#include <algorithm>

static bool parseHexLine(const QString& line, uint32_t& address, uint8_t& type, QByteArray& data, uint8_t& checksum)
{
if (line.length() < 11 || line[0] != ':') {
return false;
}
bool ok;uint32_t byteCount = line.mid(1, 2).toUInt(&ok, 16);

if (!ok) return false;

address = line.mid(3, 4).toUInt(&ok, 16);
if (!ok) return false;

type = static_cast<uint8_t>(line.mid(7, 2).toUInt(&ok, 16));
if (!ok) return false;

data.clear();
for (uint32_t i = 0; i < byteCount; ++i) {
QString byteStr = line.mid(9 + i * 2, 2);
uint8_t byteVal = static_cast<uint8_t>(byteStr.toUInt(&ok, 16));
if (!ok) return false;
data.append(static_cast<char>(byteVal));
}

checksum = static_cast<uint8_t>(line.right(2).toUInt(&ok, 16));
if (!ok) return false;

return true;

}

static uint8_t calculateChecksum(const QString& line)
{
uint8_t sum = 0;
for (int i = 1; i < line.length() - 2; i += 2) {
bool ok;
uint8_t val = static_cast<uint8_t>(line.mid(i, 2).toUInt(&ok, 16));
if (!ok) break;
sum += val;
}
return static_cast<uint8_t>(0x100 - sum);
}

bool ry_hex2bin(const QString& hexFilePath, const QString& binFilePath, quint32& startAddress)
{
QFile file(hexFilePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "无法打开.hex文件:" << hexFilePath;
return false;
}

QTextStream in(&file);
QList<Section> sections;
Section currentSection;
bool firstSection = true;
uint32_t extendAddress = 0;
uint32_t segmentAddress = 0;

while (!in.atEnd()) {
QString line = in.readLine().trimmed();
if (line.isEmpty()) continue;

uint32_t address;
uint8_t type;
QByteArray data;
uint8_t checksum;
if (!parseHexLine(line, address, type, data, checksum)) {
qDebug() << "无效的HEX行:" << line;
continue;
}

if (calculateChecksum(line) != checksum) {
qDebug() << "校验失败:" << line;
continue;
}

switch (type) {
case IntelCommand::EXTEND_ADDR: {
if (data.size() >= 2) {
extendAddress = (static_cast<uint32_t>(static_cast<uint8_t>(data[0])) << 8 |
static_cast<uint8_t>(data[1])) << 16;
}
break;
}
case IntelCommand::SEGMENT_ADDR: {
if (data.size() >= 2) {
segmentAddress = (static_cast<uint32_t>(static_cast<uint8_t>(data[0])) << 12 |
static_cast<uint8_t>(data[1]) << 4);
}
break;
}
case IntelCommand::DATA: {
uint32_t physicalAddress = extendAddress + segmentAddress + address;
if (firstSection) {
startAddress = physicalAddress;
currentSection.startAddr = physicalAddress;
currentSection.endAddr = physicalAddress;
firstSection = false;
} else if (physicalAddress != currentSection.endAddr + 1) {
sections.append(currentSection);
currentSection.startAddr = physicalAddress;
currentSection.endAddr = physicalAddress;
currentSection.data.clear();
}

currentSection.data.append(data);
currentSection.endAddr = physicalAddress + data.size() - 1;
break;
}
case IntelCommand::EOF_RECORD: {
if (!currentSection.data.isEmpty()) {
sections.append(currentSection);
}
file.close();
break;
}
default:
break;


}

}

file.close();

if (sections.isEmpty()) {
qDebug() << "未找到有效数据段";
return false;
}

// 合并所有段,生成BIN
uint32_t minAddr = sections[0].startAddr;
uint32_t maxAddr = sections.last().endAddr;
int binSize = maxAddr - minAddr + 1;
QByteArray binData(binSize, 0xFF);

foreach (const Section& sec, sections) {
int offset = sec.startAddr - minAddr;
memcpy(binData.data() + offset, sec.data.constData(), sec.data.size());
}

QFile outFile(binFilePath);
if (!outFile.open(QIODevice::WriteOnly)) {
qDebug() << "无法写入.bin文件:" << binFilePath;
return false;
}

outFile.write(binData);
outFile.close();

return true;

}


相关文章

优先推荐同专题、同标签和同作者内容,补足热门文章。

评论 0

登录 后参与评论

评论

成为第一个评论的人