Hex File Transfer bin file

Source: Internet
Author: User
Tags 04x

In embedded development, compiler-generated target files are generally. hex files.
Why to convert, direct use of hex file not, but I have been in the development process is directly generated hex files, and then download, also did not see an error.
When you are not sure of the format of the hex and bin files, it may be a problem for your small partners. The reason for the conversion is that the data records (record) in the hex file are not arranged in the order of "Start address –> termination address", because each row of data contains the starting address and the data length, so the data in the hex file does not need to be ranked from low to high in the address order , and the data in the bin file is sorted strictly by address order.

First you need to know the format of the hex file, you can refer to the official information Intel hexadecimal Object file format specification, you can also see my other Blog--hex file description.

The most recent ECU pc download tool, one step is to convert the contents of the hex file into binary data (bin file) arranged in address order (from low to high).
So I found a conversion tool--hex2bin, the source address. I'll do some analysis of the entire conversion process for this tool.
The whole process is divided into two main steps:
1. Traverse the entire hex file, find the smallest address and the largest address (that is, start and end address), calculate the length of data (data length = End address-starting address), according to the length of the data to allocate the corresponding size of memory (open an array);
2. Iterate through the entire hex file, calculate the offset of the starting address and the starting address of the hex file in each data record, and write the data portion of the data record to the array in the first step according to the offset. (This enables the entire hex file to be sorted in order from the lowest to highest address).
Finally, you only need to write out the array to the file.

First use the file * fopen (const char * path, const char * mode), open the hex file, and then the first traversal to find the starting address and data length.

    /* First traverse Hex file to get address range (Lowest_address and highest_address)///////////////, highest and Lowest addresses so we can allocat

        e The right size */do {unsigned int i; /* Read a line from input file.
        * * Getline (Line,filin);

        record_nb++; /* Remove Carriage Return/line Feed (carriage return/linefeed) at the end of line.

        * * i = strlen (line);

            if (I!= 0) {if (line[i] = = ' \ n ') line[i] = ';
               /* Scan the two bytes and NB of bytes. The two bytes are read in First_word since their use depend on the record type:if it ' s a extended address R
               Ecord or a data record.
               *////* SSCANF ()-Reads data from a string that matches the specified format and returns the number of arguments successfully. ":%2x%4x%2x%s": Format description: Colon begins, 2 hexadecimal digits, 4 hexadecimal digits, 2 hexadecimal digits, remaining as string/result = SSCANF (line, ":%2x%4x%2x%s", &nb_
            BYTES,&FIRST_WORD,&TYPE,DATA_STR); if (Result!= 4) fprintf (stderr, "Error in line%d of hex file\n ", RECORD_NB); p = (char *) data_str; P represents a pointer to a data field (including checksum)/* If we ' re reading the last record, ignore it. */switch (TYPE) {/* Data record/Case 0:if (nb_bytes

                = = 0) break;

                address = First_word; 
                if (Seg_lin_select = = segmented_address) {phys_addr = (Segment << 4) + address; else {/* linear_address or NO_ADDRESS_TYPE_SELECTE
                       D upper_address = 0 as specified in the Intel spec. Until a extended address The record is read.
                * * phys_addr = ((upper_address <<) + address);

                if (Verbose_flag) fprintf (stderr, "Physical Address:%08x\n", phys_addr);
               /* Get address range (Lowest_address and highest_address) * * /* Set the lowest address as base pointer.

                */if (Phys_addr < lowest_address) lowest_address = phys_addr; /* Same for the top address.

                * * temp = phys_addr + nb_bytes-1;
                    if (Temp > highest_address) {highest_address = temp;
                if (Verbose_flag) fprintf (stderr, "highest_address:%08x\n", highest_address);

            } break;
                Case 1:if (Verbose_flag) fprintf (stderr, "End of File record\n");

            Break Case 2:/* First_word contains the offset. It ' s supposed to is 0000 so we ignore it. */////* Extended segment Address 

                * * if (Seg_lin_select = = no_address_type_selected) Seg_lin_select = segmented_address; /* Then Ignore subsequent extended linear address recorDS/if (Seg_lin_select = = segmented_address) {result = Sscanf p, "
                    %4x%2x ", &AMP;SEGMENT,&AMP;TEMP2);

                    if (Result!= 2) fprintf (stderr, "Error in line%d of hex file\n", RECORD_NB);

                    if (Verbose_flag) fprintf (stderr, "Extended Segment address record:%04x\n", Segment); /* Update the current address.
                * * phys_addr = (Segment << 4);  else {fprintf (stderr, "ignored extended linear address record%d\n",
                RECORD_NB);

            } break;
                Case 3:if (Verbose_flag) fprintf (stderr, "Start Segment address record:ignored\n");

            Break Case 4:/* First_word contains the offset. It ' s supposed to is 0000 so we ignore it. */////* Extended linear address
    */            if (Seg_lin_select = = no_address_type_selected) Seg_lin_select = linear_address; /* Then Ignore subsequent extended segment address Records/if (Seg_lin_select = = Linear_addres    S) {result = SSCANF (P, "%4x%2x", &AMP;UPPER_ADDRESS,&AMP;TEMP2); Remove base addresses (Extended Linear address) and checksum if (Result!= 2) fprintf (stderr, "Error in line%d of hex fil

                    E\n ", RECORD_NB);

                    if (Verbose_flag) fprintf (stderr, "Extended Linear address record:%04x\n", upper_address); /* Update the current address.

                    * * phys_addr = (upper_address << 16);
                if (Verbose_flag) fprintf (stderr, "Physical Address:%08x\n", phys_addr); else {fprintf (stderr, "ignored extended segment address record%d\n"
                , RECORD_NB); } break;

            Case 5:if (Verbose_flag) fprintf (stderr, "Start Linear address record:ignored\n");

            Break
                Default:if (Verbose_flag) fprintf (stderr, "Unknown record type:%d at%d\n", TYPE,RECORD_NB);
            Break 
    }} while (!feof (Filin)); /*feof () is used to detect whether the end of the file is read, and the parameter stream is the file pointer returned by fopen (). Returns a value other than 0 if the end of the file is read, otherwise returns 0.*/

Read one row at a time, looping through it until the end of the file.

Requests a specified length of memory (malloc) and then a second traversal, the purpose of which is to arrange the data in address order.

    /* Second traverse hex file, processing data * * * Read the file & process the lines.

        */DO/* Repeat until EOF (Filin)/{unsigned int i; /* Read a line from input file.
        * * Getline (Line,filin);

        record_nb++; /* Remove Carriage Return/line feed at the end of line.

        * * i = strlen (line);

        fprintf (stderr, "record:%d; Length:%d\n", RECORD_NB, I);

            if (I!= 0) {if (line[i] = = ' \ n ') line[i] = ';
               /* Scan the two bytes and NB of bytes. The two bytes are read in First_word since their use depend on the record type:if it ' s a extended address R
            Ecord or a data record.
            * * result = SSCANF (line, ":%2x%4x%2x%s", &AMP;NB_BYTES,&AMP;FIRST_WORD,&AMP;TYPE,DATA_STR);

            if (Result!= 4) fprintf (stderr, "Error in line%d of hex file\n", RECORD_NB); Checksum = Nb_bytes + (First_word >> 8) + (First_word & 0xFF) + Type;The first 4 bytes accumulate p = (char *) data_str; /* If we ' re reading the last record, ignore it. */switch (TYPE) {/* Data record/Case 0:if (nb_bytes
                    = = 0) {fprintf (stderr, "0 byte length Data record ignored\n");
                Break

                address = First_word;
                if (Seg_lin_select = = segmented_address) phys_addr = (Segment << 4) + address; else/* linear_address or no_address_type_selected upper_address = 0 as Specifi Ed in the Intel spec. Until a extended address record is read. */if (Address_alignment_word) phys_addr = (upper_address <<) + (ADD
                    Ress << 1) + Offset; else Phys_addr = ((upper_address << 16) + address); /* Check that the "Physical address" stays in the buffer ' s range.
                    */if ((phys_addr >= lowest_address) && (phys_addr <= highest_address)) { /* The memory block begins at lowest_address/phys_addr-= lowest_address; /* Calculates the offset of the data record from the starting address of the hex file */p = readdatabytes (p); /* Writes the data in this record to the specified array based on the offset */* Read the Checksum value.
                    * * result = SSCANF (P, "%2x", &AMP;TEMP2);

                    if (Result!= 1) fprintf (stderr, "Error in line%d of hex file\n", RECORD_NB); /* Verify Checksum value. *///* checksum = 0x100-addition of all bytes except Checksum/* Checksum = (Checksum + temp2) & 0xF
                    F
                Verifychecksumvalue ();
                        else {if (Seg_lin_select = segmented_address) Fprintf (stderr, "Data record skipped at%4x:%4x\n", segment,address);
                else fprintf (stderr, "Data record skipped at%8x\n", phys_addr);

            } break; /* End of File record */Case 1:/* Simply ignore checksum errors in this line.

            * * BREAK; /* Extended segment Address record/Case 2:/* First_word contains the offset. It ' s supposed to is 0000 so we ignore it. */////* Extended segment Address 

                * * if (Seg_lin_select = = no_address_type_selected) Seg_lin_select = segmented_address; /* Then Ignore subsequent extended linear address records/if (Seg_lin_select = = Segme
                    nted_address) {result = SSCANF (P, "%4x%2x", &AMP;SEGMENT,&AMP;TEMP2); if (Result!= 2) fpriNTF (stderr, "Error in line%d of hex file\n", RECORD_NB); /* Update the current address.

                    * * phys_addr = (Segment << 4); /* Verify Checksum value.
                    * * Checksum = (Checksum + (Segment >> 8) + (Segment & 0xFF) + temp2) & 0xFF;
                Verifychecksumvalue ();

            } break;  /* Start segment Address record/Case 3:/* Nothing is done since it's for specifying the

            Starting address for execution of the binary code */break; /* Extended linear address record/Case 4:/* First_word contains the offset. It ' s supposed to is 0000 so we ignore it. */if (Address_alignment_word)/* defaults to false*/{sscanf (P, "%4x", &o
                    Ffset);
offset = offset << 16;                    Offset-= lowest_address; }/* Extended linear address record?

                * * if (Seg_lin_select = = no_address_type_selected) Seg_lin_select = linear_address; /* Then Ignore subsequent extended segment address Records/if (Seg_lin_select = = LINEAR
                    _address) {result = SSCANF (P, "%4x%2x", &AMP;UPPER_ADDRESS,&AMP;TEMP2);

                    if (Result!= 2) fprintf (stderr, "Error in line%d of hex file\n", RECORD_NB); /* Update the current address.

                    * * phys_addr = (upper_address << 16); /* Verify Checksum value.
                               * * Checksum = (Checksum + (upper_address >> 8) + (Upper_address & 0xFF) + Temp2)
                    & 0xFF;
                Verifychecksumvalue ();

            } break; /* Start LineaR Address Record/Case 5:/* Nothing is done since it's for specifying the starting Addre
            SS for execution of the binary code */break;
                default:fprintf (stderr, "Unknown record type\n");
            Break }} while (!feof (Filin));

Finally, the contents of the array output to the file, you can get the bin file.

According to the above ideas I wrote a conversion class in Java (used in the above mentioned ECU download tool), interested students can have a look.
One of the pits that came across it was necessary to mention that since the data in the hex file is ASC II, and the data in the bin file is a direct-use binary (there is no encoding), it involves coding conversions during the conversion process. There is also a point to mention, because Java is not unsigned, if you read the data to the byte variable, in the process of debugging using the print output will see garbled (data overflow byte type range).

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.