hexとbinファイルフォーマットの違い


1.hex紹介
Hexフルネーム(Intel HEX)ファイルは、1行のIntel HEXファイル形式に適合するテキストからなるASCIIテキストファイルである.Intel HEXファイルには、行ごとにHEXレコードが含まれています.これらのレコードは、対応するマシン言語コードおよび/または定数データの16進数符号化数字から構成される.Intel HEXファイルは、通常、ROMまたはEPROMに格納されるプログラムおよびデータを転送するために使用される.ほとんどのEPROMプログラマまたはシミュレータはIntel HEXファイルを使用します.
2.hexとbinファイルの違い
  • HEXファイルにはアドレス情報が含まれているが、BINファイルフォーマットにはデータ自体しか含まれていない.HEXファイルを焼いたりダウンロードしたりするときは、HEXファイル内部の情報にアドレスが含まれているため、ユーザーがアドレスを指定する必要はないのが一般的である.BINファイルを焼く場合、ユーザーは必ずアドレス情報を指定する必要があります.
  • BINファイルフォーマットは、バイナリファイルには「フォーマット」がありません.ファイルには純粋なバイナリデータが含まれているだけです.

  • 3.hexファイルフォーマット
    レコードフォーマット
    1つのIntel HEXファイルには、任意の16進数のレコードを含めることができます.各レコードには5つのドメインがあり、以下はレコードのフォーマットです.
    :llaaaatt[dd...]cc
    各アルファベットのセットは独立したドメインであり、各アルファベットは16進数であり、各ドメインは少なくとも2つの16進数から構成され、以下はバイトの説明である.
    :コロンは各Intel HEXレコードの開始です
    llはこの記録の長さドメインであり、データ(dd)のバイト数を表す.
    aaaaはアドレスドメインであり、データの開始アドレスを表す
    ttこのドメインはこのHEXレコードのタイプを表し、彼は以下のいくつかのタイプ00---データレコード01---ファイル終了レコード02---拡張セグメントアドレスレコード04---拡張線形アドレスレコードである可能性がある.
    ddはデータドメインであり、1バイトのデータを表し、1レコードに複数のデータバイトがある可能性があり、バイト数はllドメインの説明を表示することができる.
    ccは有効とドメインであり、記録の有効とを表し、計算方法は、本条の記録コロンから始まるすべてのアルファベットを表示された16進数に加算して256で得られた残数を模除し、最後に残数の補符号、すなわち本有効バイトccを求める.
    データレコード
    Intel HEXファイルはいくつかのデータ記録から構成され、1つのデータ記録は1つのリターンと1つの改行で終了し、例えば次のデータ記録:10246200464 C 55494420550524 F 46494 C 4500464 C 33、10はこの行の記録データのバイト数である.2462は、メモリ内のデータの開始アドレスである.00は、レコードタイプ00(データレコード)である.464 Cから464 Cはデータです.33は、この行の記録の有効性の和です.
    拡張線形アドレス記録(HEX 386)拡張線形アドレス記録は32ビットアドレス記録/HEX 386記録とも呼ばれ、この記録は高16(16-31ビット)ビットデータアドレスを含み、この拡張線形記録は常に2バイトのデータを有し、以下のように:0200004 FFFFFFFC 02は記録データバイト数0000がアドレスドメインであり、これは、拡張アドレス記録において常に0000 04が記録タイプ04(拡張アドレス記録)FFFFが高16ビットアドレスFCであることが記録効果和であり、計算方法は、01 h+NOT(02 h+00 h+00 h+04 h+FFh+FFh)が、1つの拡張線形アドレス記録が読み出されると、拡張線形アドレス記録のデータ領域が保存され、後にIntel HEXファイルから読み出される記録に適用されるこの拡張線形記録は、次の拡張線形記録が読み出されるまで有効である.絶対メモリアドレス=データ記録におけるアドレス+シフト後の拡張線形アドレスは、データ記録のアドレスドメインからアドレス2462、拡張線形アドレス記録のアドレスドメインからアドレスFFFFFF、絶対メモリアドレスFFFF 2462の処理を例示する
    拡張セグメントアドレスレコード(HEX 86)
    拡張セグメントアドレスレコードはHEX 86レコードとも呼ばれ、4-19ビットのデータアドレスセグメントを含み、この拡張セグメントアドレスレコードには常に2バイトのデータがあり、以下の通りである:02000021200 EA 02は記録中のデータバイト数0000はアドレスドメインであり、拡張セグメントアドレスレコードでは、このドメインは常に0000 02が記録タイプであり、02(拡張セグメントアドレスの表示)1200が当該セグメントのアドレスEAであることは、01 h+NOT(02 h+00 h+00 h+02 h+12 h+00 h)である.拡張セグメントアドレス記録が読み込まれると、拡張セグメントアドレスは、次の拡張セグメントアドレス記録絶対メモリアドレス=データ記録におけるアドレス+シフトされた拡張セグメントアドレスデータ記録におけるアドレスドメインが読み込まれ、シフトされた拡張セグメントアドレス記録におけるアドレスドメインがシフトされるまで有効となる.この処理は、データ記録のアドレスドメインからアドレス2 4 6 2、拡張セグメントのアドレス記録のアドレスドメインからアドレス1 2 0、絶対メモリアドレス0 0 0 1 4 6 2を得る
    ファイル終了レコード(EOF)Intel HEXファイルにはファイル終了レコードが必要です.このレコードのタイプドメインは01でなければなりません.1つのEOFレコードは、常に、1,000,000,000 FF 00がレコード中のデータバイト数0000であるこのアドレスは、EOFレコードにとって何の意味もない01レコードタイプが01(ファイル終了レコード表示)FFであることが有効である、以下のように計算される:01 h+NOT(00 h+00 h+00 h+01 h)である.
    4.手順は以下の通り
    hex2bin.h
    #ifndef HEX2BIN_H
    #define HEX2BIN_H
    
    typedef unsigned char uint8_t;
    typedef unsigned short uint16_t;
    typedef unsigned long uint32_t;
    
    #define HEX_MAX_LENGTH		521
    #define HEX_MIN_LEN		11
    
    typedef enum {
    	RES_OK = 0,		//  
    	RES_DATA_TOO_LONG,	//    
    	RES_DATA_TOO_SHORT,	//    
    	RES_NO_COLON,		//   
    	RES_TYPE_ERROR,		//    ,     
    	RES_LENGTH_ERROR,	//                
    	RES_CHECK_ERROR,	//    
    	RES_HEX_FILE_NOT_EXIST,	//HEX     
    	RES_BIN_FILE_PATH_ERROR,//BIN         
    	RES_WRITE_ERROR,	//     
    	RES_HEX_FILE_NO_END	//hex       
    } RESULT_STATUS;
    
    typedef struct {
    	uint8_t len;
    	uint8_t	type;
    	uint16_t addr;
    	uint8_t *data;
    } BinFarmat;
    
    RESULT_STATUS HexFile2BinFile(char *src, char *dest);
    #endif

    hex2bin.c
    #include "hex2bin.h"
    #include 
    #include 
    /********************************************************************************
    input:
    c:    ('0'~'9' 'a'~'f', 'A'~'F')
    output:
               
    ********************************************************************************/
    static uint8_t HexCharToBinBinChar(char c)
    {
    	if (c >= '0' && c <= '9')
    		return c - '0';
    	else if (c >= 'a' && c <= 'z')
    		return c - 'a' + 10;
    	else if (c >= 'A' && c <= 'Z')
    		return c - 'A' + 10;
    	return 0xff;
    }
    
    /********************************************************************************
    input:
    p:       
    output:
       1   
    ********************************************************************************/
    static uint8_t Hex2Bin(const char *p)
    {
    	uint8_t tmp = 0;
    	tmp = HexCharToBinBinChar(p[0]);
    	tmp <<= 4;
    	tmp |= HexCharToBinBinChar(p[1]);
    	return tmp;
    }
    
    /********************************************************************************
    input:
    src: hex     
    p->type:           ,           
    p->len:         ,         bin    
    p->data:         ,      0,            
    p->addr[0]:           ,           
    p->addr[1]:           ,           
    output:
      hex        
    ********************************************************************************/
    static RESULT_STATUS HexFormatUncode(const char *src, BinFarmat *p)
    {
    	uint8_t check = 0, tmp[4], binLen;
    	uint16_t hexLen = strlen(src);
    	uint16_t num = 0, offset = 0;
    	if (hexLen > HEX_MAX_LENGTH)		//      
    		return RES_DATA_TOO_LONG;
    	if (hexLen < HEX_MIN_LEN)
    		return RES_DATA_TOO_SHORT;	//      
    	if (src[0] != ':')
    		return RES_NO_COLON;		//    
    	if ((hexLen - 1) % 2 != 0)
    		return RES_LENGTH_ERROR;	//hexLen        
    	binLen = (hexLen - 1) / 2;		//bin      ,    ,  ,       
    	while (num < 4)
    	{
    		offset = (num << 1) + 1;
    		tmp[num] = Hex2Bin(src + offset);
    		check += tmp[num];
    		num++;
    	}
    	p->len = tmp[0];			//               
    	p->addr = tmp[1];
    	p->addr <<= 8;
    	p->addr += tmp[2];
    	p->type = tmp[3];
    	while (num < binLen)
    	{
    		offset = (num << 1) + 1;        //     bin     
    		p->data[num - 4] = Hex2Bin(src + offset);
    		check += p->data[num - 4];
    		num++;
    	}
    	if (p->len != binLen - 5)		//  hex                
    		return RES_LENGTH_ERROR;
    	if (check != 0)				//        
    		return RES_CHECK_ERROR;
    	return RES_OK;
    }
    
    RESULT_STATUS HexFile2BinFile(char *src, char *dest)
    {
    	FILE *src_file, *dest_file;
    	uint16_t addr_low = 0;
    	uint32_t addr_hign = 0;
    	char buffer_hex[600];
    	uint8_t buffer_bin[255];
    	BinFarmat gBinFor;
    	RESULT_STATUS res;
    	gBinFor.data = buffer_bin;
    	src_file = fopen(src, "r");		//          hex  
    	if (!src_file)
    		return RES_HEX_FILE_NOT_EXIST;
    	dest_file = fopen(dest, "wb");		//            ,         
    	if (!dest_file)
    		return RES_BIN_FILE_PATH_ERROR;
    	fseek(src_file, 0, SEEK_SET);           //     ,          
    	while (!feof(src_file))
    	{
    		fscanf(src_file, "%s\r
    ", buffer_hex); res = HexFormatUncode(buffer_hex, &gBinFor); if (res != RES_OK) { fclose(src_file); fclose(dest_file); return res; } switch (gBinFor.type) { case 0: // addr_low = gBinFor.addr; // fseek(dest_file, addr_low + addr_hign, SEEK_SET); 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_hign = ((uint32_t)gBinFor.addr) << 4; break; case 3: break; case 4: // addr_hign = ((uint32_t)gBinFor.addr) << 16; break; case 5: break; default: fclose(src_file); fclose(dest_file); return RES_TYPE_ERROR; } } fclose(src_file); fclose(dest_file); return RES_HEX_FILE_NO_END; }

    main.c
    #include 
    #include "hex2bin.h"
    const char *TipString[] =
    {
    	"bin file to hex file success!",
    	"line data of hex file is too large",
    	"line data of hex file is too short",
    	"line data of hex file is no colon",
    	"line data of hex file type is error",
    	"line data of hex file length is error",
    	"line data of hex file check error",
    	"hex file is not exist",
    	"bin file path is error",
    	"hex file is no end"
    };
    int main(int argc, char *argv[])
    {
    	RESULT_STATUS res;
    	if (argc != 3)
    	{
    		printf("para doesn't match!\r
    "); } res = HexFile2BinFile(argv[1], argv[2]); printf("%s\r
    ", TipString[res]); if (res != RES_OK) { return -1; } return 0; }

    プログラム呼び出し:hex 2 bin.exe   test.hex test.bin
    入力を便利にするために、hex 2 binというbatファイルを書きました.exeファイル転送パラメータ.
    @echo off
    echo hex2bin  ,bat   hex         
    echo     :XXX.hex
    echo     :XXX.bin
    set /p a=  hex    :
    set /p b=  bin    :
    hex2bin %a%  %b%
    pause

    参考サイト:
    https://www.cnblogs.com/skullboyer/p/7978189.html
    https://blog.csdn.net/hwb_1988/article/details/45132417