1. 程式人生 > >自定義串列埠資料協議傳送hex檔案

自定義串列埠資料協議傳送hex檔案

hex檔案格式:

Intel HEX is a file format that conveys binary information in ASCII text form. It is commonly used for programming microcontrollers, EPROMs, and other types of programmable logic devices. In a typical application, acompiler orassembler converts a program's source code (such as in C or assembly language

) to machine code and outputs it into a HEX file. The HEX file is then imported by aprogrammer to "burn" the machine code into aROM, or is transferred to the target system for loading and execution.[1]

Format

Intel HEX consists of lines of ASCII text that are separated by line feed or carriage return characters or both. Each text line contains

hexadecimal characters that encode multiple binary numbers. The binary numbers may represent data, memory addresses, or other values, depending on their position in the line and the type and length of the line. Each text line is called arecord.

Record structure

A record (line of text) consists of six

fields (parts) that appear in order from left to right:

  1. Start code, one character, an ASCII colon ':'.
  2. Byte count, two hex digits, indicating the number of bytes (hex digit pairs) in the data field. The maximum byte count is 255 (0xFF). 16 (0x10) and 32 (0x20) are commonly used byte counts.
  3. Address, four hex digits, representing the 16-bit beginning memory address offset of the data. The physical address of the data is computed by adding this offset to a previously established base address, thus allowing memory addressing beyond the 64 kilobyte limit of 16-bit addresses. The base address, which defaults to zero, can be changed by various types of records. Base addresses and address offsets are always expressed asbig endian values.
  4. Record type (see record types below), two hex digits, 00 to 05, defining the meaning of the data field.
  5. Data, a sequence of n bytes of data, represented by 2n hex digits. Some records omit this field (n equals zero). The meaning and interpretation of data bytes depends on the application.
  6. , two hex digits, a computed value that can be used to verify the record has no errors.

Color legend

As a visual aid, the fields of Intel HEX records are colored throughout this article as follows:

 Start code Byte count  Address  Record type  Data  Checksum

Checksum calculation

A record's checksum byte is the two's complement (negative) of the least significant byte (LSB) of the sum of all decoded byte values in the record preceding the checksum. It is computed by summing the decoded byte values and extracting the LSB of the sum (i.e., the data checksum), and then calculating the two's complement of the LSB (e.g., by inverting its bits and adding one).

For example, in the case of the record :0300300002337A1E, the sum of the decoded byte values is 03 + 00 +30 +00 +02 +33 +7A =E2. The two's complement ofE2 is 1E, which is the checksum byte appearing at the end of the record.

The validity of a record can be checked by computing its checksum and verifying that the computed checksum equals the checksum appearing in the record; an error is indicated if the checksums differ. Since the record's checksum byte is the negative of the data checksum, this process can be reduced to summing all decoded byte values — including the record's checksum — and verifying that the LSB of the sum is zero.

Text line terminators

Intel HEX records are separated by one or more ASCII line termination characters so that each record appears alone on a text line. This enhances legibility by visuallydelimiting the records and it also provides padding between records that can be used to improve machineparsing efficiency.

Programs that create HEX records typically use line termination characters that conform to the conventions of theiroperating systems. For example, Linux programs use a single LF (line feed, hex value0A) character to terminate lines, whereas Windows programs use a CR (carriage return, hex value0D) followed by a LF.

Record types

Intel HEX has six standard record types:

Hex codeRecord typeDescriptionExample
00DataContains data and a 16-bit starting address for the data. The byte count specifies number of data bytes in the record. The example shown to the right has0B (decimal 11) data bytes (61,64,64,72,65,73,73,20,67,61,70) located at consecutive addresses beginning at address0010.:0B0010006164647265737320676170A7
01End Of FileMust occur exactly once per file in the last line of the file. The data field is empty (thus byte count is00) and the address field is typically0000.:00000001FF
02Extended Segment AddressThe data field contains a 16-bit segment base address (thus byte count is 02) compatible with 80x86 real mode addressing. The address field (typically0000) is ignored. The segment address from the most recent02 record is multiplied by 16 and added to each subsequent data record address to form the physical starting address for the data. This allows addressing up to one megabyte of address space.:020000021200EA
03Start Segment AddressFor 80x86 processors, specifies the initial content of the CS:IP registers. The address field is0000, the byte count is04, the first two bytes are theCS value, the latter two are theIP value.:0400000300003800C1
04Extended Linear AddressAllows for 32 bit addressing (up to 4GiB). The address field is ignored (typically0000) and the byte count is always02. The two encoded, big endian data bytes specify the upper 16 bits of the 32 bit absolute address for all subsequent type00 records; these upper address bits apply until the next04 record. If no type04 record precedes a00 record, the upper 16 address bits default to 0000. The absolute address for a type00 record is formed by combining the upper 16 address bits of the most recent04 record with the low 16 address bits of the00 record.:02000004FFFFFC
05Start Linear AddressThe address field is 0000 (not used) and the byte count is 04. The four data bytes represent the 32-bit value loaded into the EIP register of the 80386 and higher CPU.:04000005000000CD2A

Named formats


Hex檔案是可以燒錄到MCU中,被MCU執行的一種檔案格式。如果用記事本開啟可發現,整個檔案以行為單位,每行以冒號開頭,內容全部為16進位制碼(以ASCII碼形式顯示)。Hex檔案可以按照如下的方式進行拆分來分析其中的內容:

例如 “:1000080080318B1E0828092820280B1D0C280D2854”可以被看作“0x10 0x00 0x08 0x00 0x80 0x31 0x8B 0x1E 0x08 0x28 0x09 0x28 0x20 0x28 0x0B 0x1D 0x0C 0x28 0x0D 0x28 0x54”

第一個位元組 0x10表示本行資料的長度;

第二、三位元組 0x00 0x08表示本行資料的起始地址;

第四位元組 0x00表示資料型別,資料型別有:0x00、0x01、0x02、0x03、0x04、0x05。

'00' Data Rrecord:用來記錄資料,HEX檔案的大部分記錄都是資料記錄

'01' End of File Record: 用來標識檔案結束,放在檔案的最後,標識HEX檔案的結尾

'02' Extended Segment Address Record: 用來標識擴充套件段地址的記錄

'03' Start Segment Address Record:開始段地址記錄

'04' Extended Linear Address Record: 用來標識擴充套件線性地址的記錄

'05' Start Linear Address Record:開始線性地址記錄

然後是資料,最後一個位元組 0x54為校驗和。

校驗和的演算法為:計算0x54前所有16進位制碼的累加和(不計進位),檢驗和 = 0x100 - 累加和

unsigned char HandleUart::HexChecksum( unsigned char *inputHexData,int len)
{

    unsigned char m_checksum = 0x00;
    for(int i = 0; i<len; i++)
    {
       m_checksum += *inputHexData;
       inputHexData++;
    }
    m_checksum%=256;
    m_checksum=0x100-m_checksum;
    return m_checksum;
}

hex檔案之線性地址處理

線性地址來源是超過64K,重新從零開始  :02000004AAAABB   AAAA:高位地址  BB:校驗和

復原hex檔案,儲存每一行資料 ,記錄線性地址 ,插入線性地址 

//    linearAddressNum =*(inputData+5);    //獲取線性地址高位信 息
//    if( linearAddressNum == (linearAddressLastNum+0x01))
//    {
//        printf("linearAddressNum%02X\n",linearAddressNum);
//        unsigned char buf[7] = {0x02, 0x00, 0x00, 0x04, 0x00};
//        buf[5] = linearAddressNum;
//        buf[6] = HexChecksum(buf,6);
//        fprintf(m_hexfile, ":");
//        assert(m_hexfile);
//        for(int i =0; i < sizeof(buf); i++)
//        {
//            fprintf(m_hexfile, "%02X",  buf[i]);
//            printf("%02X",buf[i]);
//        }
//        fprintf(m_hexfile, "\n");
//        printf("\n");
//        linearAddressLastNum = linearAddressNum;
//    }

CRC32迴圈校驗:

採用查表法,每一次需要使用上一次的校驗值,達到迴圈目的。初始值為0xffffffff

static const uint32_t crc32_table[256] =
{
        0x00000000L, 0x77073096L, 0xee0e612cL,

        0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,

        0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL,

        0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L,

        0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L,

        0x83d385c7L, 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,

        0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L,

        0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L,

        0xd20d85fdL, 0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L,

        0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,

        0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L,

        0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, 0x2802b89eL, 0x5f058808L,

        0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL,

        0xb6662d3dL, 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,

        0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L,

        0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL,

        0x91646c97L, 0xe6635c01L, 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L,

        0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,

        0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL,

        0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL,

        0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL,

        0xd3d6f4fbL, 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,

        0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL,

        0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L,

        0xb966d409L, 0xce61e49fL, 0x5edef90eL, 0x29d9c998L, 0xb0d09822L,

        0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,

        0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L,

        0x9dd277afL, 0x04db2615L, 0x73dc1683L, 0xe3630b12L, 0x94643b84L,

        0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L,

        0x7d079eb1L, 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,

        0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L,

        0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L,

        0x17b7be43L, 0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L,

        0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,

        0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L,

        0xa867df55L, 0x316e8eefL, 0x4669be79L, 0xcb61b38cL, 0xbc66831aL,

        0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L,

        0x5505262fL, 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,

        0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L,

        0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL,

        0x72076785L, 0x05005713L, 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL,

        0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,

        0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL,

        0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, 0x88085ae6L, 0xff0f6a70L,

        0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L,

        0x166ccf45L, 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,

        0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL,

        0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L,

        0x47b2cf7fL, 0x30b5ffe9L, 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L,

        0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,

        0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L,

        0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
};

unsigned int HandleUart::crc32Check( unsigned char *inputData, int len,unsigned int  crc)
{

    unsigned int  tmp;
    for(int i = 0; i < len; i++)
    {

       tmp = (crc ^ (( unsigned int )( 0x000000FF & (*inputData++)))) & 0x000000FF;
       crc  = (( crc >> 8) & 0x00FFFFFF) ^ crc32_table[tmp];
     }
    return crc;

}

在unix系統跑應用,結果出現檔案儲存不完整,原因是unix下延遲寫的問題,使用fsync同步重新整理,解決了儲存不完整的問題