That format specification document is Copyright, Intel Corporation, 1988. Since we don't desire to infringe on their Copyright and there is so much information about it on the Internet (just search for iHex), the standard portions of the iHex format are not redocumented here.
The purpose of this data format is to efficiently exchange information with the microcontroller: read its present memory contents and write new contents to its memory. It handles the need to be able to back up the device's programmed contents and to be able to reprogram it.
Consider the following three (3) blocks containing the very same information. They were all generated with MIRTOS, using the commands shown, which differ by only by the inclusion of an "H" and an "8" in the specifier before the space character. As a reminder, characters between the "D" and the first space may be input in any order, and are not case-sensitive. See the Display manual page for more details.
> DE+ 0xB0 80 EEPROM contents: 00B0: 3B 20 42 6F 6F 74 75 70-20 49 6E 69 74 3A 20 00 ; Bootup Init: . 00C0: 45 20 31 20 7E 3D 20 30-78 43 30 00 4E 2A 2A 00 E 1 ~= 0xC0.N**. 00D0: 4E 44 2B 00 45 53 20 34-37 39 3D 35 38 00 45 20 ND+.ES 479=58.E 00E0: 30 78 31 39 20 3D 20 30-78 32 35 00 45 20 30 78 0x19 = 0x25.E 0x 00F0: 32 30 20 3D 20 30 78 32-34 00 FF FF FF FF FF FF 20 = 0x24....... >DE+H 0xB0 80 EEPROM contents: :02000002E0001C :1000B0003B20426F6F74757020496E69743A20005E :1000C000452031207E3D2030784330004E2A2A00E2 :1000D0004E442B004553203437393D3538004520F8 :1000E00030783139203D2030783235004520307865 :1000F0003230203D203078323400FFFFFFFFFFFF19 :00000001FF >DEH+8 0xB0 80 EEPROM contents: :02000002E0001C :0800B0003B20426F6F74757074 :0800B80020496E69743A200032 :0800C000452031207E3D203077 :0800C800784330004E2A2A00A3 :0800D0004E442B00455320347F :0800D80037393D3538004520A1 :0800E00030783139203D203059 :0800E800783235004520307824 :0800F0003230203D203078324F :0800F8003400FFFFFFFFFFFFD2 :00000001FF >
Although all three formats are human-readable, the first is a little more human-friendly than the other two because it has spaces and an interpretation of its contents on the right. The second format is the most compact (i.e., most efficient) of the three. Both the second and third formats have a simple way to check each line for transmission errors, while the first format does not. Although the second format is more common, the second format is quite valid and limits lines to 27 characters, excluding any Carriage Return or Line Feed character, which is not shown. This third format is used to transmit unbroken blocks over the nRF24L01 radio.
As shown below, the EEPROM, FLASH (or PROGRAM) memory and SRAM may each be output. The '-' in the third example simply omits the data type header.
So far, so good? OK, output is great, but consider this example:> DH+E 0 32 EEPROM contents: :02000002E0001C :100000001021009F010184FF04220EFF283C50FFB5 :10001000C0003FFF60080367FF2574FFFFFFFFFF7D :00000001FF >DH+F 0 32 FLASH (program memory) contents: :100000000C948030436F707972696768742C202873 :10001000632920323031332D323031362C20534396 :00000001FF >DH+-P 0 32 ; Same data block as above :100000000C948030436F707972696768742C202873 :10001000632920323031332D323031362C20534396 :00000001FF >DH+S 0 32 SRAM contents: :02000002F0000C :10000000000072001809281004DF00040C007C08AE :10001000100E0382FF00000030101F007D081F003B :00000001FF >D+H 0 32 SRAM contents: :02000002F0000C :10000000000012015609281004BE00040C007C08F0 :10001000100E0382FF00000030101F007D081F003B :00000001FF >
m> DF+ 0x2670 160 FLASH (program memory) contents: 2670: 27 2C 20 65 78 63 65 70-74 20 74 6F 20 34 20 64 ', except to 4 d 2680: 69 67 69 74 73 20 28 2A-2A 29 00 35 20 73 61 6D igits (**).5 sam 2690: 65 20 61 73 20 27 32 27-2C 20 65 78 63 65 70 74 e as '2', except 26A0: 20 74 6F 20 35 20 64 69-67 69 74 73 20 28 2A 2A to 5 digits (** 26B0: 29 00 36 20 73 61 6D 65-20 61 73 20 27 32 27 2C ).6 same as '2', 26C0: 20 65 78 63 65 70 74 20-74 6F 20 36 20 64 69 67 except to 6 dig 26D0: 69 74 73 20 28 2A 2A 29-00 37 20 77 61 73 20 75 its (**).7 was u 26E0: 6E 75 73 65 64 20 28 2A-2A 29 00 38 20 77 61 73 nused (**).8 was 26F0: 20 75 6E 75 73 65 64 20-28 2A 2A 29 00 39 20 64 unused (**).9 d 2700: 69 73 70 6C 61 79 73 20-63 6F 6D 6D 61 6E 64 20 isplays command m>DFH+ 0x2670 160 FLASH (program memory) contents: :10267000272C2065786365707420746F2034206483 :10268000696769747320282A2A2900352073616DCF :1026900065206173202732272C206578636570746C :1026A00020746F20352064696769747320282A2A92 :1026B0002900362073616D65206173202732272C35 :1026C0002065786365707420746F203620646967B4 :1026D00069747320282A2A290037207761732075AE :1026E0006E7573656420282A2A2900382077617363 :1026F00020756E7573656420282A2A2900392064A4 :102700006973706C61797320636F6D6D616E6420A5 :00000001FF m>X 0x26B0 ; Reset the block from 0x2680 to 0x26FF m>DF+ 0x2670 160 ; Redisplay it to verify erasure FLASH (program memory) contents: 2670: 27 2C 20 65 78 63 65 70-74 20 74 6F 20 34 20 64 ', except to 4 d 2680: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................ 2690: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................ 26A0: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................ 26B0: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................ 26C0: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................ 26D0: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................ 26E0: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................ 26F0: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................ 2700: 69 73 70 6C 61 79 73 20-63 6F 6D 6D 61 6E 64 20 isplays command m>; Copy and paste from the iHex block above: m>:10267000272C2065786365707420746F2034206483 m>:10268000696769747320282A2A2900352073616DCF m>:1026900065206173202732272C206578636570746C m>:1026A00020746F20352064696769747320282A2A92 m>:1026B0002900362073616D65206173202732272C35 m>:1026C0002065786365707420746F203620646967B4 m>:1026D00069747320282A2A290037207761732075AE m>:1026E0006E7573656420282A2A2900382077617363 m>:1026F00020756E7573656420282A2A2900392064A4 m>:102700006973706C61797320636F6D6D616E6420A5 m>:00000001FF m>DF+ 0x2670 160 ; Display again to verify restoration FLASH (program memory) contents: 2670: 27 2C 20 65 78 63 65 70-74 20 74 6F 20 34 20 64 ', except to 4 d 2680: 69 67 69 74 73 20 28 2A-2A 29 00 35 20 73 61 6D igits (**).5 sam 2690: 65 20 61 73 20 27 32 27-2C 20 65 78 63 65 70 74 e as '2', except 26A0: 20 74 6F 20 35 20 64 69-67 69 74 73 20 28 2A 2A to 5 digits (** 26B0: 29 00 36 20 73 61 6D 65-20 61 73 20 27 32 27 2C ).6 same as '2', 26C0: 20 65 78 63 65 70 74 20-74 6F 20 36 20 64 69 67 except to 6 dig 26D0: 69 74 73 20 28 2A 2A 29-00 37 20 77 61 73 20 75 its (**).7 was u 26E0: 6E 75 73 65 64 20 28 2A-2A 29 00 38 20 77 61 73 nused (**).8 was 26F0: 20 75 6E 75 73 65 64 20-28 2A 2A 29 00 39 20 64 unused (**).9 d 2700: 69 73 70 6C 61 79 73 20-63 6F 6D 6D 61 6E 64 20 isplays command m>
The contents of a 128-BYTE block of FLASH memory (with 16 BYTEs both before and after) were displayed in both DEBUG and iHEX formats. That block was reset back to its initial, unprogrammed state, with all BYTEs set to 0xFF (i.e., all bits set to logic '1'.) The block that was just output a moment before in iHex format was re-input, restoring the original contents of the block.
Important notes: All of that was done without shutting down the running program or any need to stop and restart the microcontroller. Also, note the "m>" prompt, indicating that we were in Manager Mode, which is toggled simply with a '$' as the very first character on a command line.
Please understand that MIRTOS is an Operating System, not simply a boot
loader. Any portion of the FLASH memory below the System Memory area may
be reprogrammed using the iHEX command in Manager Mode.
This table summarizes the memory ranges in MIRTOS Version 3.01.
MCU | FLASH Pages | BYTES per Page |
Available for User Code | System Memory |
Erase in Manager Mode | Erase in Admin Mode |
Prevented from being displayed |
Protected from Erasure |
---|---|---|---|---|---|---|---|---|
328P | 256 | 128 = 0x80 | 0x0100 to 0x38FF | 0x3900 to 0x7FFF | 0x0000 to 0x38FF | 0x0000 to 0x6FFF | 0x4000 to 0x7FFF | 0x7000 to 0x7FFF |
1284P | 512 | 256 = 0x100 | 0x00100 to 0x1A6FF | 0x1A700 to 0x1FFFF | 0x00000 to 0x1A6FF | 0x00000 to 0x1DFFF | 0x1AE00 to 0x1FFFF | 0x1E000 to 0x1FFFF |
2560 | 1024 | 256 = 0x100 | 0x00100 to 0x3A4FF | 0x3A500 to 0x3FFFF | 0x00000 to 0x3A4FF | 0x00000 to 0x3DFFF | 0x3AC00 to 0x3FFFF | 0x3E000 to 0x3FFFF |
The same for any portion of the SRAM; here initialized, zeroed, and copied to a new location. Small blocks are used here, but larger blocks of any memory type can be manipulated with the iHex format commands:> DE+ 0xB0 32 EEPROM contents: 00B0: 3B 20 42 6F 6F 74 75 70-20 49 6E 69 74 3A 20 00 ; Bootup Init: . 00C0: 45 20 31 20 7E 3D 20 30-78 43 30 00 4E 2A 2A 00 E 1 ~= 0xC0.N**. >DEH+ 0xB0 32 EEPROM contents: :02000002E0001C :1000B0003B20426F6F74757020496E69743A20005E :1000C000452031207E3D2030784330004E2A2A00E2 :00000001FF >EW 0xB8 = -1 -1 -1 -1 >DE+ 0xB0 32 EEPROM contents: 00B0: 3B 20 42 6F 6F 74 75 70-FF FF FF FF FF FF FF FF ; Bootup........ 00C0: 45 20 31 20 7E 3D 20 30-78 43 30 00 4E 2A 2A 00 E 1 ~= 0xC0.N**. >; Login in Manager Mode at this point m>:02000002E0001C m>:1000B0003B20426F6F74757020496E69743A20005E m>:1000C000452031207E3D2030784330004E2A2A00E2 m>:00000001FF m>DE+ 0xB0 32 EEPROM contents: 00B0: 3B 20 42 6F 6F 74 75 70-20 49 6E 69 74 3A 20 00 ; Bootup Init: . 00C0: 45 20 31 20 7E 3D 20 30-78 43 30 00 4E 2A 2A 00 E 1 ~= 0xC0.N**. m>
> D+ 0x600 16 SRAM contents: 0600: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ >ES 0x600 = 1 2 3 4 5 ; No need to login for EDIT commands >D+ 0x600 16 SRAM contents: 0600: 01 02 03 04 05 00 00 00-00 00 00 00 00 00 00 00 ................ >D+H 0x600 6 SRAM contents: :02000002F0000C :06060000010203040500E5 :00000001FF >EZS 0x600 5 ; Zero those same 5 BYTEs >D+ 0x600 16 SRAM contents: 0600: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ >; Login in Manager Mode at this point m>:02000002F0000C m>:06060000010203040500E5 m>D+ 1536 16 SRAM contents: 0600: 01 02 03 04 05 00 00 00-00 00 00 00 00 00 00 00 ................ m>:06060800010203040500E5 ; Change just the address from 0600 to 0608 Checksum error; received: 0xE5; calculated: 0xDD m>:06060800010203040500DD ; Make the correction and reinput m>:00000001FF m>D+ 0x600 16 SRAM contents: 0600: 01 02 03 04 05 00 00 00-01 02 03 04 05 00 00 00 ................ m>
Notice that when the MIRTOS iHex parser detected a checksum error, it output a message with the correct checksum. The iHex input mode will not wrote to any target memory (FLASH, EEPROM, or SRAM) unless logged in, however it does save FLASH blocks with valid checksums in its buffer when not logged in. By default, it also copies the existing 128-BYTE (for a 328P or 256-BYTE for the 1284P or 2560) FLASH block at that address to its buffer when a valid line is input, whether logged in or not, although that default (in EEbFlags_OS) can be changed.
Consider this scenario: capture iHex output, revise only the address, and send the new lines to MIRTOS in normal (i.e., logged out) mode. Checksum warnings are generated for each line. Change addresses in the iHex file and test them, noting the correct checksums, with the assurance that no memory is being modified changed. Login and reinput the revised iHex file to make the actual changes in the destination memory blocks. There are other considerations (e.g., RCALL and RJMP addresses) for PROGRAM memory, of course, but this method works well for SRAM and EEPROM.
When opening a new iHex session (i.e., a line beginning with ':' is input while no iHex buffer is already allocated), the new buffer is allocated and the block type is set. It will be FLASH unless EEPROM or SRAM are specified. Once any block type is specified, the Operating System will remember and store that type of memory until it encounters an End Of File (":00000001FF") record. It does not hurt anything to send an extra End Of File; it simply closes any open FLASH memory block if one is waiting to be written (or discards it if not logged in.) In fact, we HIGHLY recommend doing just that. If nothing is waiting to be written, MIRTOS closes the iHex memory buffer. Use the "M" command to check the memory status, indicated in the SP (Stack Pointer) value or check that high memory area directly.
EEPROM is selected using a ":02000002E0001C" Extended Segment Address iHex record; SRAM is selected using ":02000002F0000C". If neither of those two are given and an iHex command is input, FLASH memory is the default.
Consider this final example:> :1030000080E209C081E207C082E205C083E203C01A >:1030100084E201C085E2282FE4E70E940000EDE78A >:103020000E940000682F6150822FEDE701D0E5E794 >:103030000C940000FFFFFFFFFFFFFFFFFFFFFFFFFC >:1030400088E0EAE00E940000EDE70E9400009C0199 >:1030500040E050E090E081E078EB60E0EDE710D0F8 >:10306000ECE60ED0EDE70CD042E0EAE509D09CE3B7 >:103070008EE3BC01E0E604D0CB01ECE401D0EBE54B >; We weren't logged in; login at this point using '$' m>:103080000C940000FFFFFFFFFFFFFFFFFFFFFFFFAC m>:00000001FF
What got stored? Actually, everything - all 256 (not just 144) BYTEs!
Despite not being logged in when the lines beginning with ">:103010" through ">:103070" were entered, the iHex parser validated and stored all those lines to SRAM. FLASH memory is both erased and written as a block (of 128 BYTEs in a 328P, and of 256 BYTEs in the 1284P and 2560) at one time.
Here's an instance of things which are different between the 328P and the other two MPUs. When MIRTOS in the 328P detected a block change with the ":10308000..." line, and found that it was logged in, it saved the prior 128 BYTEs (from 0x3000 to 0x307F) to FLASH. Had we not been logged in, MIRTOS would have simply discarded that 128-BYTE block. When it then encountered the End Of File (":00000001FF") record, it then saved that 128 BYTEs (from 0x3080 to 0x30FF) to FLASH.
In the 1284P and 2560, FLASH blocks have 256 BYTEs. MIRTOS would not have attempted to save anything in those MCUs until the EOF (End Of File) record is entered. When that EOF was encountered, all 256 BYTEs (from 0x3000 to 0x30FF) would be saved to FLASH.
So be careful! This is a very powerful tool, but can catch you if you're not being careful. By remaining logged out, parsed blocks can be validated and FLASH commands saved in SRAM. No saving change is made to any type of memory using the iHex command unless you're logged in when the EOF record is input.
See also: The BIT_OS_COPY_FLASH bit the EEbFlags_OS system BYTE and the display, edit, admin login, memory, NRF24L01 radio, and erase flash System Commands.