搜索
bottom↓
回复: 12

Bootloader 用到的hex 转 bin程序

[复制链接]

出0入0汤圆

发表于 2006-5-22 16:45:20 | 显示全部楼层 |阅读模式
8位 hex 文件格式说明



这是一个跑马灯程序的hex文件内容(由winavr ,atmega8编译生成)

:1000000012C02BC02AC029C028C027C026C025C0C6

:1000100024C023C022C021C020C01FC01EC01DC0DC

:100020001CC01BC01AC011241FBECFE5D4E0DEBF28

:10003000CDBF10E0A0E6B0E0E0EAF0E002C005903D

:100040000D92A036B107D9F710E0A0E6B0E001C0EC

:100050001D92A036B107E1F701C0D2CFCFE5D4E0C1

:10006000DEBFCDBF8FEF81BB12BA8CE49DE1A0E073

:10007000B0E031E027E032BBFC013197F1F7FC0141

:100080003197F1F7FC013197F1F7FC013197F1F766

:10009000FC013197F1F7330F215027FFECCFE9CF67

:00000001FF



说明: 除" : "外,以2个字符表示一个0xff型16进制数据



  数据头         数据                        校验数据

:10000000  12C02BC02AC029C028C027C026C025C0     C6



字符":" - 是每一行的开头标志

字符串" 10000000 " - 分解为 " 10 0000 00 "

        即为: 10 数据的长度(16进制) 该行数据有16个字节

              0000 在储存器中的偏移地址: (16进制)

              00  数据类型 (类似关键字). 00 表示记录是数据,最后一行的01 表示记录结束



字符串" 12C02BC02AC029C028C027C026C025C0 " 表示数据为(22组合表示一个16进制数)

12 C0 2B C0 2A C0 29 C0 28 C0 27 C0 26 C0 25 C0

0x12 0xC0 0x2B 0xC0 0x2A 0xC0 0x29 0xC0 0x28 0xC0 0x27 0xC0 0x26 0xC0 0x25 0xC0



字符串" C6 " 是校验数据, 除了" : " 和 校验数据本身 的所有数据(转换后的)的累加和

    也就是:

0x10

+ 0x0000

+ 0x00

+ ( 全加0x12 0xC0 0x2B 0xC0 0x2A 0xC0 0x29 0xC0 0x28 0xC0 0x27 0xC0 0x26 0xC0 0x25 0xC0 )



这个数必须始终为8位,中间相加过程的超出0xff的部分是忽略的



然后这个数再加上 校验数据 ,则 = 0x00 ,说明数据正确,否则数据校验错误.





hex to bin

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <sys/types.h>



#define TRUE  1

#define FALSE 0

#define BYTE unsigned char



//8位Hex格式,由 WinAVR编译生成,MCU类型 ATmega8

typedef struct _HEX_FORMAT

{

BYTE DataLen;  //记录长度  00

int  MemOffset; //偏移地址  0000

BYTE DataType; //数据类型  00

BYTE Data[20]; //数据长度  最大16位

BYTE DataVerify;//数据校验  00

}HEX_FORMAT;



char HexArr[16] = "0123456789ABCDEF";



//16进制字符转10进制数,默认为0??

BYTE ChHex2Dct(char chr)

{

BYTE i;

for(i=0;i<16;i++)

{

  if(HexArr == chr)

  {

   return i;

  }

}

return 0;

}

BYTE Hex2Dct(char chH,char chL)

{

BYTE RetVal;



RetVal = ChHex2Dct(chH) * 16 + ChHex2Dct(chL);

return RetVal;

}

int Hex4Dct(char ch1,char ch2,char ch3,char ch4)

{

int RetVal;



RetVal = ChHex2Dct(ch1) << 12;

RetVal += ChHex2Dct(ch2) << 8;

RetVal += ChHex2Dct(ch3) << 4;

RetVal += ChHex2Dct(ch4);



return RetVal;

}

  





int Hex2Bin(char* szHexPath,char* szBinPath)

{

int fpHex;

int fpBin;



int HexFileLen;

int BinFileLen;



BYTE *pHexBuf;

int i,j;



BYTE *pBinBuf;

int iBinBufLen;



HEX_FORMAT *pHexRec;

int iRecCou;



struct stat HexInfo;

int TmpCou;

BYTE TmpVal;







fpHex = open(szHexPath,O_RDONLY);

if(fpHex<0) return FALSE;



fstat(fpHex,&HexInfo);



HexFileLen =(int)HexInfo.st_size;



printf("%s Hex File Length:%d
",szHexPath,HexFileLen);



pHexBuf = (BYTE*)malloc(HexFileLen+1);

if(!pHexBuf)

{

  printf("Malloc Memory Fail!
");

  return FALSE;

}

read(fpHex,pHexBuf,HexFileLen);



close(fpHex);





//以上读取hex文件的内容并保存到pHexBuf内存中



iRecCou=0;

//计算记录的个数

for(i=0;i<HexFileLen-1;i++)

{

  if(pHexBuf == 13 && pHexBuf[i+1] == 10)

  {

   iRecCou++;

  }

}



//为记录结构分配内存

pHexRec = malloc(iRecCou * sizeof(HEX_FORMAT) + 1);

if(!pHexRec)

{

  printf("Hex Record Malloc Memory Fail!
");

  return FALSE;

}



//将数据转换到记录结构中

TmpCou=0;

for(i=0;i<iRecCou;i++)

{

  if(pHexBuf[TmpCou++] != ':')

  {

   printf("Data Format Error!
");

   free(pHexBuf);

   free(pHexRec);

   return FALSE;

  }

  //记录长度  00

  pHexRec.DataLen = Hex2Dct(pHexBuf[TmpCou],pHexBuf[TmpCou+1]);

  TmpCou+=2;

  //偏移地址  0000

  pHexRec.MemOffset = Hex4Dct(pHexBuf[TmpCou],pHexBuf[TmpCou+1],pHexBuf[TmpCou+2],pHexBuf[TmpCou+3]);

  TmpCou+=4;

  //数据类型  00

  pHexRec.DataType = Hex2Dct(pHexBuf[TmpCou],pHexBuf[TmpCou+1]);

  TmpCou+=2;

  

  for(j=0;j<pHexRec.DataLen;j++)

  {

   pHexRec.Data[j] = Hex2Dct(pHexBuf[TmpCou],pHexBuf[TmpCou+1]);

   TmpCou+=2;

  }

  //数据校验  00

  pHexRec.DataVerify = Hex2Dct(pHexBuf[TmpCou],pHexBuf[TmpCou+1]);

  TmpCou+=2;

  //该行结束符 13,10

  if(pHexBuf[TmpCou] != 13 || pHexBuf[TmpCou+1] != 10)

  {

   printf("Data Format Error,End Not 13,10!
");

   free(pHexBuf);

   free(pHexRec);

   return FALSE;

  }

  TmpCou+=2;

}



free(pHexBuf);



  

/*

for(i=0;i<iRecCou;i++)

{

  printf("
Record %d:
",i+1);

  printf("Data Length     :%d
",pHexRec.DataLen);

  printf("Memory Offset  :%4x
",pHexRec.MemOffset);

  printf("Data Type      :%x
",pHexRec.DataType);

  printf("Data:");

  for(j=0;j<pHexRec.DataLen;j++)

   printf("%x ",pHexRec.Data[j]);

  printf("
Data Verify :%x
",pHexRec.DataVerify);  

   

}

*/



//对每条记录进行校验 ,(除了 ; 和 校验 之外的所有数据的累加和  + 校验数据 )&0xff = 0x00



iBinBufLen = 0;

for(i=0;i<iRecCou;i++)

{

  TmpVal = 0;

  TmpVal += pHexRec.DataLen;

  TmpVal += (pHexRec.MemOffset & 0xff00) >> 8;

  TmpVal += (pHexRec.MemOffset & 0xff);

  TmpVal += pHexRec.DataType;

  

  for(j=0;j<pHexRec.DataLen;j++)

  {

   TmpVal += (pHexRec.Data[j])&0xff;

  }

  if( ((TmpVal + (pHexRec.DataVerify & 0xff)) & 0xff) != 0x00)

  {

   printf("Record[%d]:Data Verify Error!
",i);

   printf("Data:%x ,Data Verify:%x = %x
",TmpVal,pHexRec.DataVerify,TmpVal+pHexRec.DataVerify);

   free(pHexRec);

   return FALSE;

  }

  iBinBufLen += pHexRec.DataLen;

}



pBinBuf = malloc(iBinBufLen+1);

if(!pBinBuf)

{

  printf("Bin Buffer Malloc Memory Error!
");

  free(pHexRec);

  return FALSE;

}



//将数据直接提取出来,直接存成bin格式

TmpCou = 0;

for(i=0;i<iRecCou;i++)

{

  for(j=0;j<pHexRec.DataLen;j++)

  {

   pBinBuf[TmpCou]=pHexRec.Data[j];

   TmpCou++;

  }

}

free(pHexRec);



fpBin = open(szBinPath,O_RDWR|O_CREAT);

if(fpBin<0)

  fpBin = open(szBinPath,O_RDWR|O_CREAT);

  

write(fpBin,pBinBuf,iBinBufLen);



close(fpBin);



free(pBinBuf);



return TRUE;

}





int main(int argc,char *argv[])

{

char szHexPath[255];

char szBinPath[255];



puts("Hex to Bin Program...");



if(argc < 3)

{

  if(argc < 2)

  {

   printf("Please Input Hex Filename:");

   scanf("%s",szHexPath);

  }        

  else

  {

   strcpy(szHexPath,argv[1]);

  }

     

  if(argc < 3)

  {

   printf("Please Input Bin Filename:");

   scanf("%s",szBinPath);

  }  

}

else

{

  //赋值

  strcpy(szHexPath,argv[1]);

  strcpy(szBinPath,argv[2]);

}



printf("Source File(Hex):%s
Target File(Bin):%s
",szHexPath,szBinPath);







if(Hex2Bin(szHexPath,szBinPath)==FALSE)

{

  printf("
Error Transform Hex file:%s To Bin file:%s!
",szHexPath,szBinPath);

  exit(-1);

}

printf("
Success Transform Hex file:%s To Bin file:%s!
",szHexPath,szBinPath);



exit(0);

}



取出里面的hex 转bin 的过程,放到bootloader 得pc端程序中,即可将winavr 生成的 8 位hex 文件

数据 转成 atmega8 可以直接存储的格式, 注意,这个是8位 hex格式 !

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2009-8-19 22:52:28 | 显示全部楼层
好帖子啊,难得难得。居然一直没有人顶,可惜啊

出0入0汤圆

发表于 2009-9-7 08:32:23 | 显示全部楼层
没怎么看明白。没明白这其中的原理

出0入0汤圆

发表于 2009-9-7 08:51:51 | 显示全部楼层
先mark,以后再看。

出0入0汤圆

发表于 2009-9-7 08:57:40 | 显示全部楼层
为什么要费劲用程序转呢,如果用gcc的话,直接修改makefile,直接输出bin格式就可以了

出0入0汤圆

发表于 2009-10-29 13:27:51 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-12-12 14:25:32 | 显示全部楼层
好文,非常详细

出0入0汤圆

发表于 2010-12-12 14:44:50 | 显示全部楼层
一个办法是用编程器软件,比如西尔特,不用硬件,启动后读入HEX文件,在另存BIN就行了

出0入0汤圆

发表于 2010-12-12 15:45:48 | 显示全部楼层
mark

出0入0汤圆

发表于 2013-6-20 16:39:04 | 显示全部楼层
mark

出0入0汤圆

发表于 2013-7-20 23:49:28 | 显示全部楼层
顶下。。。。

出0入0汤圆

发表于 2013-7-21 08:47:30 | 显示全部楼层
参考着用下。

出0入0汤圆

发表于 2013-7-24 21:32:45 | 显示全部楼层
写的好!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 23:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表