QT编程:S19转BIN
在做嵌入式单片机的bootloader功能时,通常需要将HEX格式或S19格式的烧录程序转成纯数据的BIN文件。在学QT过程中,决定自己做一个S19转BIN文件的小工具。
关于S19文件的格式,网上有很多资料,这里不再赘述。在实际使用中生成的BIN文件中,除了S19的中有用数据,在BIN文件开头添加了一段信息数据。
如上表所示,在BIN文件的开头添加1K的的信息区。信息区中包含有效数据块数,有效数据大小,CRC值及程序版本日期等,后面是各个数据块对于的地址,数据格式,及CRC值等。
下面晒出代码:
s19tobin.h
#ifndef S19TOBIN_H
#define S19TOBIN_H
#include <QMainWindow>
#include <QTimer> /* 定时器 */
#include <QDebug> /* 调试诊断接口 */
#include <QTime> /* 系统时间 */
#include <QDebug>
#include "QFileDialog"
class s19tobin
{
public:
s19tobin();
~s19tobin();
/* analyze s19 file, get bin data, generate bin file */
int s19tobin_pro(QString fpath,QString sv_str);
private:
/* bin file information area */
#define BIN_INFO_AREA_SEIZ (1024)
#define BIN_INFO_BASE_SEIZ (256)
#define BIN_INFO_BLOCK_NUM (48)
#define BIN_INFO_SV_SEIZ (16)
#define BIN_INFO_DATE_SEIZ (32)
typedef union
{
quint8 buf[BIN_INFO_BASE_SEIZ];
struct
{
quint8 head;
quint8 bnum[2];
quint8 dlen[4];
quint8 dcrc[4];
quint8 resv1[5];
char soft_version[BIN_INFO_SV_SEIZ];
char date[BIN_INFO_DATE_SEIZ];
}fd;
}BIN_BASE_INFO_DEF;
typedef struct
{
quint8 index;
quint8 addr[4];
quint8 dlen[4];
quint8 dcrc[4];
quint8 resv[2];
quint8 crc;
}BIN_BLOCK_INFO_DEF;
typedef union
{
quint8 buf[BIN_INFO_AREA_SEIZ];
struct
{
BIN_BASE_INFO_DEF base;
BIN_BLOCK_INFO_DEF block[BIN_INFO_BLOCK_NUM];
}fd;
}BIN_INFO_DEF;
/* S19 TO BIN CONTROL CONTEXT */
#define BIN_LINE_DATA_SIZE (256)
typedef struct
{
/* initialize flag */
int initflag; /* 1: initialzed */
char rl_draw[BIN_LINE_DATA_SIZE]; /* a s19 file line data */
quint8 rl_draw_len; /* a s19 file line data size */
quint8 rl_sindex; /* the first 's' position in a s19 file line data size */
quint8 rl_data[BIN_LINE_DATA_SIZE]; /* the valid data in a s19 file line data */
quint8 rl_dlen; /* the valid data size */
quint32 rl_addr; /* the valid data addr */
quint32 rl_block_flag; /* 1: first block have been got */
quint32 rl_block_addr; /* the current block addr */
quint32 rl_block_dcnt; /* the current block data counter */
quint32 rl_block_dcrc; /* the current block data crc */
/* bin file information area */
BIN_INFO_DEF bin_info;
quint32 block_addr[BIN_INFO_BLOCK_NUM]; /* record all block addr */
quint32 block_dlen[BIN_INFO_BLOCK_NUM]; /* record all block data len */
quint32 block_dcrc[BIN_INFO_BLOCK_NUM]; /* record all block crc */
quint16 block_cnt; /* block cnt */
quint32 total_dcrc; /* total data crc */
quint32 total_dlen; /* total data len */
}S19TOBIN_CONTEXT_DEF;
QString fpath_s19;
QFile fs19;
QFile fbin;
QFile flog;
QTextStream login;
QString logstr;
S19TOBIN_CONTEXT_DEF ctx;
uint8_t change_CharToHex(char ch); /* 将字符转换成16进制数据 */
char change_HexToChar(uint8_t hex); /* 将16进制数据转换成字符 */
uint8_t change_CharToU8(char byteh,char bytel); /* 将两字节字符数据转换成一个字节HEX,第一个字符是高位 */
quint8 calc_crc8(quint8 *buf,quint32 len); /* calculate crc8 , add all data , left lowest 8 byte */
quint32 calc_crc32(quint8 *buf,quint32 len); /* calculate crc32 , add all data , left lowest 32 byte */
int open_fs19(QString p_fpath);
int open_flog(QString p_fpath);
int open_fbin(QString p_fpath);
int analyze_line_check_len_and_crc(QString str,int *p_sindex);
int analyze_line_check_addr_and_data(QString str);
int analyze_line_write_valid_data_to_bin_file(void);
int analyze_a_line(QString str);
int analyze_write_bin_info_to_bin_file(QString sv);
int analyze_fs19(QString sv_str);
};
#endif // S19TOBIN_H
s19tobin.cpp
#include "s19tobin.h"
s19tobin::s19tobin()
{
memset(&ctx,0,sizeof(ctx));
}
s19tobin::~s19tobin()
{
fs19.close();
fbin.close();
flog.close();
}
/*
*****************************************************************
*name: change_CharToHex
*descrip: 将字符转换成16进制数据
*input: 字符
*return: 对应数值
*****************************************************************
*/
uint8_t s19tobin::change_CharToHex(char ch)
{
uint8_t hex = 0;
switch (ch)
{
case '0': hex = 0; break;
case '1': hex = 1; break;
case '2': hex = 2; break;
case '3': hex = 3; break;
case '4': hex = 4; break;
case '5': hex = 5; break;
case '6': hex = 6; break;
case '7': hex = 7; break;
case '8': hex = 8; break;
case '9': hex = 9; break;
case 'a': hex = 10; break;
case 'b': hex = 11; break;
case 'c': hex = 12; break;
case 'd': hex = 13; break;
case 'e': hex = 14; break;
case 'f': hex = 15; break;
case 'A': hex = 10; break;
case 'B': hex = 11; break;
case 'C': hex = 12; break;
case 'D': hex = 13; break;
case 'E': hex = 14; break;
case 'F': hex = 15; break;
default:break;
}
return hex;
}
/*
*****************************************************************
*name: change_HexToChar
*descrip: 将16进制数据转换成字符
*input: 16进制数值
*return: 字符
*****************************************************************
*/
char s19tobin::change_HexToChar(uint8_t hex)
{
char ch = 0;
switch (hex & 0x0f)
{
case 0x00U: ch = '0'; break;
case 0x01U: ch = '1'; break;
case 0x02U: ch = '2'; break;
case 0x03U: ch = '3'; break;
case 0x04U: ch = '4'; break;
case 0x05U: ch = '5'; break;
case 0x06U: ch = '6'; break;
case 0x07U: ch = '7'; break;
case 0x08U: ch = '8'; break;
case 0x09U: ch = '9'; break;
case 0x0aU: ch = 'A'; break;
case 0x0bU: ch = 'B'; break;
case 0x0cU: ch = 'C'; break;
case 0x0dU: ch = 'D'; break;
case 0x0eU: ch = 'E'; break;
case 0x0fU: ch = 'F'; break;
default:break;
}
return ch;
}
/*
*****************************************************************
* name: change_CharToU8
* descrip: 将两字节字符数据转换成一个字节HEX,第一个字符是高位
* input: byteh - high part of a byte,
* bytel - low part of a byte
* output: result byte
*****************************************************************
*/
uint8_t s19tobin::change_CharToU8(char byteh,char bytel)
{
return (uint8_t)(((uint8_t)change_CharToHex(byteh) << 4u) | ((uint8_t)change_CharToHex(bytel)));
}
/*
*****************************************************************
* name: calc_crc8
* descrip: calculate crc8 , add all data , left lowest 8 byte
* input: buf - data buf,
* len - size of data
* output: result byte
*****************************************************************
*/
quint8 s19tobin::calc_crc8(quint8 *buf,quint32 len)
{
quint8 crc = 0