/********************************************************************************
*
********************************************************************************/
/********************************************************************************
* head files *
********************************************************************************/
#include "hex2bin.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/********************************************************************************
* user define *
********************************************************************************/
/********************************************************************************
* private variables *
********************************************************************************/
/********************************************************************************
* Global variables *
********************************************************************************/
/********************************************************************************
* functions *
********************************************************************************/
/********************************************************************************
input:
c:单个字符('0'~'9' 'a'~'f', 'A'~'F')
output:
单个字符转化为单个字符
********************************************************************************/
static uint8_t char2hex(char c)
{
switch(c >> 4) {
case 0x03:
return(c - '0');
break;
case 0x04:
return(c - '7');
break;
case 0x06:
return(c - 'W');
break;
default:
return 0;
break;
}
}
/********************************************************************************
input:
str: 十六进制字符串
str: 十六进制数组
output:
数组长度
********************************************************************************/
static int string2array(char *str)
{
int len, ret;
uint8_t *hex;
len = strlen(str);
hex = (uint8_t *)str;
len >>= 1;
ret = len;
while(len--) {
*hex = char2hex(*str++);
*hex <<= 4;
*hex |= char2hex(*str++);
hex++;
}
return ret;
}
/********************************************************************************
input:
fb: FILE指针
startAddr: 开始填充地址
endAddr: 填充结束地址
fill: 填充的数据
output:
文件填充结果
********************************************************************************/
enumHex2BinResult_t data_filling(FILE *fb, uint32_t startAddr, uint32_t endAddr, uint8_t fill)
{
int count, remainder;
uint8_t temp[HEX2BIN_FILL_SIZE];
memset(temp, fill, HEX2BIN_FILL_SIZE);
count = HEX2BIN_FILL_COUNT(endAddr - startAddr);
remainder = HEX2BIN_FILL_REMAINDER(endAddr - startAddr);
// fseek(fb, 0, SEEK_END);
while(count--) {
if(fwrite((const uint8_t*)temp, HEX2BIN_FILL_SIZE, 1, fb) != 1) {
return RES_WRITE_ERROR;
}
}
if(remainder != 0) {
if(fwrite((const uint8_t*)temp, remainder, 1, fb) != 1) {
return RES_WRITE_ERROR;
}
}
return RES_OK;
}
/********************************************************************************
input:
src: hex单行字符串
pack->type: 如果函数返回结果正确,这里就存着转化后的类型
pack->len: 如果函数运行正确,这里就存着转化后的bin数据长度
pack->data: 如果函数运行正确,长度并且不为0,该指针就只想转化后的数据
pack->addr[0]: 如果函数返回结果正确,这里就存着地址的低字节
pack->addr[1]: 如果函数返回结果正确,这里就存着地址的低字节
output:
返回hex格式流分析的结果
********************************************************************************/
static enumHex2BinResult_t hex_format_line(const char *src, structHexPackage_t *pack)
{
int i, length;
uint8_t sum, *ptr;
length = strlen(src);
// 长度
if(length < HEX2BIN_LINE_MIN) {
return RES_DATA_TOO_SHORT;
}
if(length > HEX2BIN_LINE_MAX) {
return RES_DATA_TOO_LONG;
}
// 数据头
if(src[0] != ':') {
return RES_NO_COLON;
}
// 长度奇偶性检查
if (((length - 1) & 1) != 0) {
return RES_LENGTH_ERROR; //hexLen的长度应该为奇数
}
// 字符串转十六进制数组
length = string2array((char *)&src[1]);
// 数据校验
sum = 0;
i = length;
ptr = (uint8_t *)&src[1];
while(i--) {
sum += *ptr++;
}
if(sum != 0) {
return RES_CHECK_ERROR;
}
pack->len = (uint8_t)src[1];
pack->addr = (uint8_t)src[2];
pack->addr <<= 8;
pack->addr |= (uint8_t)src[3];
pack->type = (uint8_t)src[4];
memcpy(pack->data, &src[5], pack->len);
//检查hex格式流的长度和数据的长度是否一致
if (pack->len != (length - 5)) {
return RES_LENGTH_ERROR;
}
return RES_OK;
}
/********************************************************************************
input:
src: hex文件
dest: bin文件
output:
转换结果
********************************************************************************/
enumHex2BinResult_t hex_file_to_bin_file(char *src, char *dest)
{
FILE *src_file, *dest_file;
uint32_t addr_high = 0, addr_low = 0;
uint32_t addr_curr, start_addr, end_addr;
structHexPackage_t gBinFor;
enumHex2BinResult_t res;
char buffer[HEX2BIN_LINE_MAX];
//以文本的形式打开一个hex文件
src_file = fopen(src, "r");
if (!src_file) {
return RES_HEX_FILE_NOT_EXIST;
}
//以二进制写的方式打开文件,文件不存在也没影响
dest_file = fopen(dest, "wb");
if (!dest_file) {
fclose(src_file);
return RES_BIN_FILE_PATH_ERROR;
}
fseek(src_file, 0, SEEK_SET); //定位到开头,准备开始读取数据
end_addr = 0;
start_addr = 0xFFFFFFFF;
while (!feof(src_file))
{
// 读取一行数据
fscanf(src_file, "%s\r\n", buffer);
// 解析行
res = hex_format_line((const char *)buffer, &gBinFor);
if (res != RES_OK) {
fclose(src_file);
fclose(dest_file);
return res;
}
switch (gBinFor.type) {
case 0: //数据记录
addr_low = (uint32_t)gBinFor.addr;
addr_curr = addr_high + addr_low;
if(start_addr == 0xFFFFFFFF) {
start_addr = end_addr = addr_high + addr_low;
}
//数据指针偏移
// fseek(dest_file, (addr_curr - start_addr), SEEK_SET);
if(addr_curr != end_addr) {
if(data_filling(dest_file, end_addr, addr_curr, 0xFF) == RES_OK) {
end_addr = addr_curr;
} else {
fclose(src_file);
fclose(dest_file);
return RES_WRITE_ERROR;
}
}
end_addr += gBinFor.len;
if (fwrite((const uint8_t*)gBinFor.data, gBinFor.len, 1, dest_file) != 1) {
fclose(src_file);
fclose(dest_file);
return RES_WRITE_ERROR;
}
break;
case 1: //数据结束
fclose(src_file);
fclose(dest_file);
return RES_OK;
case 2: // ??
addr_high = ((uint32_t)gBinFor.ad
评论0