The .hex file Breakdown

Decimal System

a human beings as we are we use our fingers to count things.

Picture3

but while dealing with computers we have to add some extra fingers.

Picture2

Hex-a-What?

The hexadecimal notation is almost universally used in computing – and not without a reason. There are sixteen hex digits – 0 to 9, and A to F (which correspond to decimal values 0 to 15), and each hex digit represents exactly four bits. Exactly two hex digits represent a byte, which can have a value from 00 to FF (that is from 0 to 255 decimal). In order to find a hex value of a multi-byte object, you would concatenate its bytes, for example, bytes 26 0F 3E 5A constitute a four-byte value 0x260F3E5A (or 0x5A3E0F26 if the computer uses the reverse byte ordering).

Picture1

But why hexadecimal? Can’t we just use good old decimal numbers? Well, they would be fine for a decimal computer, but most contemporary computers are binary and work on bits and bytes. A decimal digit represents approximately 3.3 bits, and this makes arithmetic too complicated. Let’s assume we have two bytes with decimal values 243 and 78. What will be the value of the two-byte word? 24378? No, this method works with hexadecimal digits only. To find the decimal value of the word we must compute 243*256+78, which equals to 62286. Does not look very obvious, does it? Imagine finding a value of an eight-byte long variable and you will see why the decimal notation is not the best choice for binary computers.

Do I really need to know this?

Yes, you should have some understanding of hexadecimal notation; in fact, there is not much else to know. Hex byte is the only kind of object a computer handles, and hex bytes are used to represent anything. For example, a hex byte 0x9409 may represent the 8-bit AVR command “IJMP – Indirect Jump”, the decimal number 37897 or a zillion of other things.

so, let’s say we have this simple code

<
/*
 * hexbreakdown.c
 *
 * Created: 6/20/2016 11:52:05 PM
 * Author: Kareem A.Abdullah
 */

#include <avr/io.h>
#include <stdint.h>
#include <gprs.h>
#include <uart.h>

uint8_t unit_id = 5; //unit ID

int main(void)
{
 uart_init(); //UART initialization
 GPRS_init(); //GPRS instialization
 //send unit ID to the server
 send_GPRS(unit_id);
 while (1)
     {
     //get unit updates from the server
      get_unit_updates();
     }
}

Now, let’s imagine that you are in a production phase for this product and you are  producing 150 unit. each time you are downloading the code on the hardware, you’ll go the IDE change the unit_ID ,then compile and finally download the final .hex image, which is headache.Now, we got a serious time problem.what are our options to eliminate this problem?
Yes, you got it right designing our own Desktop app to download the code and change the unit it without going there the compilation process again. But how can we do that???
seems like we got no other way but understanding how to edit the final .hex image!

Understanding the .hex fine(image)

after going to your $Project_folder/debug/
open hexbreakdown.hex with the text editor
hex1

to understand what these Harry Potter magical spells like symbols , we need to investigate them as follow:

hex2  hex3

 

hex4

hex5

hex6

hex7

Now,we got it, and we know our area of concern which is the code area, But what to do next?

open command prompt in the same folder then write this command
avr-objdump -m avr -D hexbreakdown.hex>hexbreakdown.txt

open the generated .txt file which contains the disassembly view of your hex file.
if you wanna understand more about the instruction set of 8-bit AVR you can have a look on the 8-Bit AVR instruction set 

Capture

Now, scroll down the file till you find the value you wanna modify and get the address which is in our case hex valye a4

11

it’s crystal clear now that you can modify the value 0005 to the value you need let’s say 0008, the most important question now “is this the end of the story?”
unfortunately,No. you still have to modify the checksum byte value to the correct  value.

How to calculate the checksum byte ?

1. Add the bytes together and drop the carries.
2.Take the 2’s complement of the total sum.
This is the checksum byte, which becomes the last byte of the series.
E.g. For 25H, 62H, 3FH, and 52H
sum = 25H, 62H, 3FH, and 52H = 118H
discard caries, sum = 18H
checksum  = ~sum + 1= ~(18H) + 1 = E7 + 1   = E8
Error = 25H + 62H + 3FH + 52H + E8 = 200
After discarding carries if remaining 8-bit answer is zero that means no error.
Let’s apply this knowledge to our example:
0200A400050055
checksum  = ~sum + 1= ~(02H+00H+A4H+00H+05H) + 1 = 54 + 1   = 55
hey,it’s working!!!
let’s apply it now to our modified value:
0200A400080052
checksum=  ~(02H+00H+A4H+00H+08H) + 1 = 51+1=52

so, the final version of the .hex file would be like that

123

This concludes the .hex file breakdown, If you have any questions or comments about this article please leave it and we’ll answer it as soon as possible.
If you like our blog please like  our facebook page to stay tuned.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s