#include "stdafx.h"
#include "csv.h"
#include "string"
#include "vadefs.h"
#include "stdlib.h"
#include "stdio.h"
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
#define PLATFORM PC_MS
//#define PLATFORM UNIX
//#define PLATFORM ARM
#define Isgraph(c) ((c) <= 0x7e && (c) >= 0x21)
#define Isdigit(c) ((c) >= '0' && (c) <= '9')
#define IsHexChar(ch) (Isdigit(ch) || ((ch) >= 'a' && (ch) <= 'f') || ((ch) >= 'A' && (ch) <= 'F'))
#define Isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\v' || (c) == '\n' || (c) == '\f' || (c) == '\r')
typedef char CHAR;
typedef unsigned char BYTE;
typedef int INT;
int ReadLine(FILE* file, char *Buf); //excluding the Line Feed
char* ItoC(INT i, char *str, INT radix); //converts integeral variable to string
BYTE HexToByte(char *hex); //convert 2 hex character to BYTE
BYTE CalcRecChkSum(char *str, int len);
int WriteBin(FILE* fp, UINT32 Addr, BYTE *Buf, int Len);
int IteraRecord(char *Record, UINT32 *Addr, BYTE *BinBuf, BYTE *BinLen);
/**************** Write Hex file For PowerBoard**************/
//void WriteHexFile(UINT32 Addr, BYTE Buf, int Len);
#define BUF_SIZE 1024
char Buf[BUF_SIZE] = {0};
#define SUB_LINE_SIZE 100
#define WAVE_LINE_NUM 33
int WriteBin(FILE* fp, UINT32 Addr, BYTE *Buf, int Len)
{
long pos;
if(!fp || !Buf || Len < 0)
return -1;
fseek(fp, 0, SEEK_END);
pos = ftell(fp);
if(Addr > pos) //stuff the dummy data 0xff
{
const BYTE dummy = 0xff;
while(pos++ < Addr)
fputc(dummy, fp);
}
else
fseek(fp, Addr, SEEK_SET);
while(Len--)
fputc(*Buf++, fp);
fflush(fp);
}
void ConvHexToBin(FILE *fpIn, FILE *fpOut)
{
#define SIZE_PER_REC 16
char Record[50];
UINT32 AbsoAddr = 0;
BYTE BinBuf[SIZE_PER_REC] = {0};
BYTE BinLen;
int RecIndex = 0;
if(!fpIn)
return;
fseek(fpIn, 0, SEEK_SET);
ReadLine(fpIn, Record);
while(IteraRecord(Record, &AbsoAddr, BinBuf, &BinLen))
{
if(BinLen > 0)
WriteBin(fpOut, AbsoAddr, BinBuf, BinLen);
ReadLine(fpIn, Record);
}
fclose(fpIn);
fclose(fpOut);
printf("Convert hex to Bin done.");
}
int _tmain()
{
FILE* fInput;
FILE* fOutput;
int len = 0;
int ItemNum = 0;
int i = 0;
int lineLen = 0;
char hex0[] = {'2', '3'};
char hex1[] = {'0', '9'};
char hex2[] = {'E', 'F'};
char hexErr[] = {'a', '4'};
char hexErr1[] = {'9', '\r'};
BYTE rtn = 0xff;
char HexFileName[] = "KJ_Boot.hex";
char BinFile[] = "BinFile.bin";
if((fInput = fopen(HexFileName, "r")) == NULL || (fOutput= fopen(BinFile, "w+b")) == NULL)
{
printf("Open input or output file:%s failed!!!\n", HexFileName);
getchar();
return -1;
}
else
{
ConvHexToBin(fInput, fOutput);
}
getchar();
return 0;
}
char* ItoC(INT i, char *str, INT radix)
{
char *pos = str;
char *start = str;
if(radix == 0 || str == NULL)
return NULL;
if(i < 0)
{
i = -i;
*pos++ = '-';
start++;
}
while(i / radix)
{
*pos++ = i % radix + '0';
i /= radix;
}
*pos++ = i + '0';
*pos-- = '\0';
while(pos > start)
{
char tmp = *start;
*start++ = *pos;
*pos-- = tmp;
}
return str;
}
int ReadLine(FILE* file, char *buf)
{
char ch;
char *pos = buf;
if(!file)
return 0;
while((ch = fgetc(file)) != EOF)
{
if(!(Isgraph(ch) || Isspace(ch))) //the input character invalid
return 0;
if(ch == '\n')
{
*pos = '\0'; //the string terminal charater
return pos - buf;
}
*pos++ = ch;
}
return (int)(pos - buf);
}
BYTE HexToByte(char *hex) //convert 2 hex character to BYTE
{
BYTE h[2];
if(!hex)
return 0;
if(IsHexChar(hex[0]) && IsHexChar(hex[1]))
{
BYTE i;
for(i = 0; i < 2; i++)
{
if(Isdigit(hex[i]))
h[i] = hex[i] - '0';
else if(hex[i] >= 'a' && hex[i] <= 'z')
h[i] = hex[i] - 'a' + 10;
else
h[i] = hex[i] - 'A' + 10;
}
return h[0] * 16 + h[1];
}
return 0;
}
BYTE CalcRecChkSum(char *str, int len)
{
BYTE ChkSum = 0;
do {
ChkSum += HexToByte(str);
str += 2;
}while((len -= 2) > 0); //don't check whether the value is equal to 0,because the program will crash if the input len is a odd value.
return ~ChkSum + 1;
}
//Record Format:
//:llaaaatt[dd...]cc
int IteraRecord(char *Record, UINT32 *Addr, BYTE *BinBuf, BYTE *BinLen)
{
const BYTE HeaderSize = 1; //colon
const BYTE DataLenSize = 2;
const BYTE OffsetAddrSize = 4;
const BYTE TypeSize = 2;
const BYTE CkSumSize = 2;
int rtn = 1;
static UINT32 BaseAddr = 0;
BYTE Type;
BYTE RecLen;
RecLen = strlen(Record);
if(CalcRecChkSum(Record + HeaderSize, RecLen - HeaderSize - CkSumSize) != HexToByte(Record + RecLen - CkSumSize))
{
printf("Record CheckSum failed!!!\n");
return 0;
}
Type = Record[HeaderSize + DataLenSize + OffsetAddrSize + 1];
switch(Type)
{
case '0':{//data record
BYTE i, DataLen;
DataLen = HexToByte(Record + HeaderSize);
char *a = Record + HeaderSize + DataLenSize;
*Addr = BaseAddr + ((HexToByte(a) << 8) | HexToByte(a + 2));
for(i = 0; i < DataLen; i++)
*BinBuf++ = HexToByte(Record + HeaderSize + DataLenSize + OffsetAddrSize + TypeSize + i*2);
*BinLen = DataLen;
}
break;
case '1':{ //end-of-file record
BaseAddr = 0;
*BinLen = 0;
rtn = 0;
}
break;
case '2':{ //extended segment address record
char *a = Record + HeaderSize + DataLenSize + OffsetAddrSize + TypeSize;
BaseAddr = ((HexToByte(a) << 8) | HexToByte(a + 2)) << 4;
*BinLen = 0;
}
break;
case '4':{ //extended linear address record
char *a = Record + HeaderSize + DataLenSize + OffsetAddrSize + TypeSize;
BaseAddr = ((HexToByte(a) << 8) | HexToByte(a + 2)) << 16;
*BinLen = 0;
}
break;
case '5':{ //start linear Address Records(MDK-ARM only),this record can be ignored
*BinLen = 0;
}
break;
default:{
*BinLen = 0;
}
}
return rtn;
}
//Record Format:
//:llaaaatt[dd...]cc
//void WriteHexFile(FILE* fp, UINT32 Addr, char *HexBuf, int Len)//write the the ascii characters,not the value bytes
//{
//#define SIZE_PER_REC 16
// char Record[50];
// UINT32 AbsoAddr = 0;
// BYTE BinBuf[SIZE_PER_REC] = {0};
// BYTE BinLen;
// int RecIndex = 0;
//
// if(!fp)
// return -1;
//
// fseek(fp, 0, SEEK_SET);
// ReadLine(fp, Record);
//
// while(IteraRecord(Record, &AbsoAddr, BinBuf, &BinLen))
// {
// char *HexData = Record + 9; // Record format :llaaaatt[dd...]cc,the hex_data offset is 9
//
// printf("Target Record:%s\n", Record);
//
// if(BinLen <= 0) //the AbsoAddr is effictive when the BinLen is larger than 0 which means that this Record is Data Record.
// continue;
// if(Addr >= AbsoAddr && Addr < AbsoAddr + BinLen)
// {
// if(Len <= (BinLen - Addr)* 2) //data in one record,2 hex char corresponding to 1 byte
// {
// memcpy(HexData + (Addr -AbsoAddr) * 2, HexBuf, Len);
// return 0;
// }
// else //data in multiple records
// {
// memcpy(HexData + (Addr - AbsoAddr) * 2, HexBuf, (BinLen - Addr) * 2);
// Len -= (BinLen - Addr) * 2;
// Addr += BinLen;
// HexBuf += (BinLen - Addr) * 2;
// }
// }
// }
//
// fclose(fpIn);
// fclose(fpOut);
//}
//
#include "csv.h"
#include "string"
#include "vadefs.h"
#include "stdlib.h"
#include "stdio.h"
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
#define PLATFORM PC_MS
//#define PLATFORM UNIX
//#define PLATFORM ARM
#define Isgraph(c) ((c) <= 0x7e && (c) >= 0x21)
#define Isdigit(c) ((c) >= '0' && (c) <= '9')
#define IsHexChar(ch) (Isdigit(ch) || ((ch) >= 'a' && (ch) <= 'f') || ((ch) >= 'A' && (ch) <= 'F'))
#define Isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\v' || (c) == '\n' || (c) == '\f' || (c) == '\r')
typedef char CHAR;
typedef unsigned char BYTE;
typedef int INT;
int ReadLine(FILE* file, char *Buf); //excluding the Line Feed
char* ItoC(INT i, char *str, INT radix); //converts integeral variable to string
BYTE HexToByte(char *hex); //convert 2 hex character to BYTE
BYTE CalcRecChkSum(char *str, int len);
int WriteBin(FILE* fp, UINT32 Addr, BYTE *Buf, int Len);
int IteraRecord(char *Record, UINT32 *Addr, BYTE *BinBuf, BYTE *BinLen);
/**************** Write Hex file For PowerBoard**************/
//void WriteHexFile(UINT32 Addr, BYTE Buf, int Len);
#define BUF_SIZE 1024
char Buf[BUF_SIZE] = {0};
#define SUB_LINE_SIZE 100
#define WAVE_LINE_NUM 33
int WriteBin(FILE* fp, UINT32 Addr, BYTE *Buf, int Len)
{
long pos;
if(!fp || !Buf || Len < 0)
return -1;
fseek(fp, 0, SEEK_END);
pos = ftell(fp);
if(Addr > pos) //stuff the dummy data 0xff
{
const BYTE dummy = 0xff;
while(pos++ < Addr)
fputc(dummy, fp);
}
else
fseek(fp, Addr, SEEK_SET);
while(Len--)
fputc(*Buf++, fp);
fflush(fp);
}
void ConvHexToBin(FILE *fpIn, FILE *fpOut)
{
#define SIZE_PER_REC 16
char Record[50];
UINT32 AbsoAddr = 0;
BYTE BinBuf[SIZE_PER_REC] = {0};
BYTE BinLen;
int RecIndex = 0;
if(!fpIn)
return;
fseek(fpIn, 0, SEEK_SET);
ReadLine(fpIn, Record);
while(IteraRecord(Record, &AbsoAddr, BinBuf, &BinLen))
{
if(BinLen > 0)
WriteBin(fpOut, AbsoAddr, BinBuf, BinLen);
ReadLine(fpIn, Record);
}
fclose(fpIn);
fclose(fpOut);
printf("Convert hex to Bin done.");
}
int _tmain()
{
FILE* fInput;
FILE* fOutput;
int len = 0;
int ItemNum = 0;
int i = 0;
int lineLen = 0;
char hex0[] = {'2', '3'};
char hex1[] = {'0', '9'};
char hex2[] = {'E', 'F'};
char hexErr[] = {'a', '4'};
char hexErr1[] = {'9', '\r'};
BYTE rtn = 0xff;
char HexFileName[] = "KJ_Boot.hex";
char BinFile[] = "BinFile.bin";
if((fInput = fopen(HexFileName, "r")) == NULL || (fOutput= fopen(BinFile, "w+b")) == NULL)
{
printf("Open input or output file:%s failed!!!\n", HexFileName);
getchar();
return -1;
}
else
{
ConvHexToBin(fInput, fOutput);
}
getchar();
return 0;
}
char* ItoC(INT i, char *str, INT radix)
{
char *pos = str;
char *start = str;
if(radix == 0 || str == NULL)
return NULL;
if(i < 0)
{
i = -i;
*pos++ = '-';
start++;
}
while(i / radix)
{
*pos++ = i % radix + '0';
i /= radix;
}
*pos++ = i + '0';
*pos-- = '\0';
while(pos > start)
{
char tmp = *start;
*start++ = *pos;
*pos-- = tmp;
}
return str;
}
int ReadLine(FILE* file, char *buf)
{
char ch;
char *pos = buf;
if(!file)
return 0;
while((ch = fgetc(file)) != EOF)
{
if(!(Isgraph(ch) || Isspace(ch))) //the input character invalid
return 0;
if(ch == '\n')
{
*pos = '\0'; //the string terminal charater
return pos - buf;
}
*pos++ = ch;
}
return (int)(pos - buf);
}
BYTE HexToByte(char *hex) //convert 2 hex character to BYTE
{
BYTE h[2];
if(!hex)
return 0;
if(IsHexChar(hex[0]) && IsHexChar(hex[1]))
{
BYTE i;
for(i = 0; i < 2; i++)
{
if(Isdigit(hex[i]))
h[i] = hex[i] - '0';
else if(hex[i] >= 'a' && hex[i] <= 'z')
h[i] = hex[i] - 'a' + 10;
else
h[i] = hex[i] - 'A' + 10;
}
return h[0] * 16 + h[1];
}
return 0;
}
BYTE CalcRecChkSum(char *str, int len)
{
BYTE ChkSum = 0;
do {
ChkSum += HexToByte(str);
str += 2;
}while((len -= 2) > 0); //don't check whether the value is equal to 0,because the program will crash if the input len is a odd value.
return ~ChkSum + 1;
}
//Record Format:
//:llaaaatt[dd...]cc
int IteraRecord(char *Record, UINT32 *Addr, BYTE *BinBuf, BYTE *BinLen)
{
const BYTE HeaderSize = 1; //colon
const BYTE DataLenSize = 2;
const BYTE OffsetAddrSize = 4;
const BYTE TypeSize = 2;
const BYTE CkSumSize = 2;
int rtn = 1;
static UINT32 BaseAddr = 0;
BYTE Type;
BYTE RecLen;
RecLen = strlen(Record);
if(CalcRecChkSum(Record + HeaderSize, RecLen - HeaderSize - CkSumSize) != HexToByte(Record + RecLen - CkSumSize))
{
printf("Record CheckSum failed!!!\n");
return 0;
}
Type = Record[HeaderSize + DataLenSize + OffsetAddrSize + 1];
switch(Type)
{
case '0':{//data record
BYTE i, DataLen;
DataLen = HexToByte(Record + HeaderSize);
char *a = Record + HeaderSize + DataLenSize;
*Addr = BaseAddr + ((HexToByte(a) << 8) | HexToByte(a + 2));
for(i = 0; i < DataLen; i++)
*BinBuf++ = HexToByte(Record + HeaderSize + DataLenSize + OffsetAddrSize + TypeSize + i*2);
*BinLen = DataLen;
}
break;
case '1':{ //end-of-file record
BaseAddr = 0;
*BinLen = 0;
rtn = 0;
}
break;
case '2':{ //extended segment address record
char *a = Record + HeaderSize + DataLenSize + OffsetAddrSize + TypeSize;
BaseAddr = ((HexToByte(a) << 8) | HexToByte(a + 2)) << 4;
*BinLen = 0;
}
break;
case '4':{ //extended linear address record
char *a = Record + HeaderSize + DataLenSize + OffsetAddrSize + TypeSize;
BaseAddr = ((HexToByte(a) << 8) | HexToByte(a + 2)) << 16;
*BinLen = 0;
}
break;
case '5':{ //start linear Address Records(MDK-ARM only),this record can be ignored
*BinLen = 0;
}
break;
default:{
*BinLen = 0;
}
}
return rtn;
}
//Record Format:
//:llaaaatt[dd...]cc
//void WriteHexFile(FILE* fp, UINT32 Addr, char *HexBuf, int Len)//write the the ascii characters,not the value bytes
//{
//#define SIZE_PER_REC 16
// char Record[50];
// UINT32 AbsoAddr = 0;
// BYTE BinBuf[SIZE_PER_REC] = {0};
// BYTE BinLen;
// int RecIndex = 0;
//
// if(!fp)
// return -1;
//
// fseek(fp, 0, SEEK_SET);
// ReadLine(fp, Record);
//
// while(IteraRecord(Record, &AbsoAddr, BinBuf, &BinLen))
// {
// char *HexData = Record + 9; // Record format :llaaaatt[dd...]cc,the hex_data offset is 9
//
// printf("Target Record:%s\n", Record);
//
// if(BinLen <= 0) //the AbsoAddr is effictive when the BinLen is larger than 0 which means that this Record is Data Record.
// continue;
// if(Addr >= AbsoAddr && Addr < AbsoAddr + BinLen)
// {
// if(Len <= (BinLen - Addr)* 2) //data in one record,2 hex char corresponding to 1 byte
// {
// memcpy(HexData + (Addr -AbsoAddr) * 2, HexBuf, Len);
// return 0;
// }
// else //data in multiple records
// {
// memcpy(HexData + (Addr - AbsoAddr) * 2, HexBuf, (BinLen - Addr) * 2);
// Len -= (BinLen - Addr) * 2;
// Addr += BinLen;
// HexBuf += (BinLen - Addr) * 2;
// }
// }
// }
//
// fclose(fpIn);
// fclose(fpOut);
//}
//