Why are some "expert" blogs so wrong! - Page 1
Forum section: electronics / general

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 11, 2015, 10:38:15 pm
content: There is a lot of good information on the web and a lot of bad as well:I googled to find info about how to interpret a compiler .hex file to find how to burn code and this is now I have to decide what is right and what is wrong: Here's the question I was seeking the answer to:======================================For example, consider these beginning three IMAGININARY .hex records to burn into a PIC18F45K22 or similar from an Intel .Hex file:0400000012345678(CHECKSUM BYTE OMITTED):107CD600FEDCBA9876543210FFEEDDCCBBAA0011(CHECKSUM BYTE OMITTED):107CE6009F8E7F6B5A493827160511223344556677(CHECKSUM BYTE OMITTED)------------Programming rules require that first bytes to be burned first need to be loaded into 64-byte buffer table register prior to writing them to the MCU. Then the 64-byte write buffer is written to the target MCU.I have visited several blog websites, and there seems some are making s a remarkable error about how the start address is interpreted. And none even show a simple chart like I've created below that shows the burn clearly.A Microchip 1998 application note says the hex record start Address (0x7CD6) should be divided by two (because an Intel Hex file only supports 8-bits???) If so, how then does an address like a possible 0xFFFF/2 =0x7FFF identify anything less than a 15-bit address??Other expert's blogs state the address shown in the .hex file record is the address not divided by two??From the above,I get that the address is either divided by two or is not, and this makes a very big difference!Ok, now consider the 16 byte code payload of the second record data payload "FEDCBA9876543210FFEEDDCCBBAA0011"if I program the code flash of the PIC18, starting at address 0x3E6b (address of the main body of code) and examine the code after writing it, should do I then see this:MCUFlash "FE DC BA 98 76 54 32 10 FF EE DD CC BB AA 00 11" was burnt (from start of main code above)Address Data Address Data ( in the case of 2 bytes per MCU address I would see)0x3E6a FF 0x3E6a FFFF0x3E6b FE 0x3E6b FEDC0x3E6c DC 0x3E6c BA98d BA 0x3e6d 7654e 98 0x3e6e 3210f 76 f FFEE70 54 70 DDCC71 32 71 BBAA0x3E72 10 72 001173 FF 0x3e73 'next record's address and payload starts here74 EE75 DD76 CC77 BB78 AA79 000X3E7A 110x3E7b ....next record code starts to be entered hereWhat of the above is correct?

author: Andy Watson
author_rank: Super Contributor
timestamp: June 11, 2015, 10:49:07 pm
content: You should be able to compare the hex file with the lst file - this will help you reverse-engineer the format.I believe it was Intel that specified the format of the those hex files - back in the day when 8 bits were the norm - the format seems to have diverged with different manufacturers and different word lengths!

author: hamster_nz
author_rank: Super Contributor
timestamp: June 11, 2015, 10:55:45 pm
content: The format is quite well specified, and even has it's own wikipedia page :http://en.wikipedia.org/wiki/Intel_HEXHowever, I would assume that the PIC has a flash memory width of greater than 8 bits, so what is going on is....When you are told put hex ABCDDCBA at address 1234, you think1234 <= AB1235 <= DC1236 <= DC1237 <= BABut the PIC does not have byte addressable memory, so as 91A is 0x1234/2, you will be writing into address 91A and 91B:91A <= DCAB (assuming little-endian)91B <= BADCedit: fixed up a typo

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 11, 2015, 11:02:39 pm
content: Thanks for your hexelent advice, hamster_nz, but your target MCU bytes are a bit chewed up, don't quite match what you've started with! I wrote code to examine the MCU byte by consecutive byte and I get consistent results using the TBLPTR to set each consecutive address, odd or even.Andy, I have read the Wikipedia and many other blogs until I was hexed out, but the Intel hex standard is the Intel hex standard and .hex files should not confuse any burner HW.But thanks much Andy Watson, you've saved the day, why didn't I think at taking a look at the .lst file?

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 11, 2015, 11:32:15 pm
content: Thanks Again Andy I looked at the .hex file and see that I was completely wrong with addresses!:040000006BEF3EF074:107CD6000001B9EF3EF0E8CF1BF01B50D96EDA6A0F:107CE600DECF0BF0DECF0CF0DECF0DF0DECF0EF0E8:107CF60017C00FF018C010F019C011F01AC012F01A:107D060055EC3FF01B50D96EDA6A0BC0DEFF0CC093and then I see in the .lst file:185 psect cinit186 007CD6 __pcinit:187 opt stack 0188 007CD6 start_initialization:189 opt stack 0190 007CD6 end_of_initialization:191 opt stack 0192007CD6 0100movlb 0193 007CD8 EFB9 F03E goto _main ;jump to C main() function194 wreg equ 0xFE8195 postinc2 equ 0xFDE196 postdec2 equ 0xFDD197 fsr2h equ 0xFDA198 fsr2l equ 0xFD9199 status equ 0xFD8Watson, my dear Watson, why didn't you tell me this 40-hours ago!This means if I use my program to examine the contents of address of 0x7CD6 I should see0x7CD5 0x00 'lo byte0x7CD6 0x01 'hi byte0x7CD7 0xEF0x7CD8 0x89I may be still a little confused, I seem to be able to read odd addresses! The programmer mode Command 1000 Table Read, works by clocking in 8 dummy bits in and then only 8-bits are output by the MCU with 8 output PClks per Cmd 1000 call, just one byte can be gotten at once. There seems no problem to set TBLPTRL to an odd address.

author: Andy Watson
author_rank: Super Contributor
timestamp: June 11, 2015, 11:55:04 pm
content: Quote from: SuzyC on June 11, 2015, 11:32:15 pmI don't believe you askedAlso, be careful with the word endianness - I always manage to get it wrong with PICs.

author: mikerj
author_rank: Super Contributor
timestamp: June 12, 2015, 09:44:16 am
content: Quote from: SuzyC on June 11, 2015, 11:32:15 pmOf course you can read odd addresses, why wouldn't you be able to?

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 12, 2015, 11:32:03 am
content: That s 'cause Hamster_nz Hamster_nz said, "But the PICdoes not have byte addressable memory, so as 91A is 0x1234/2, you will be writing into address 91A and 91B:"

author: amyk
author_rank: Super Contributor
timestamp: June 12, 2015, 01:03:48 pm
content: They are not "wrong", it'syouwho is misunderstanding them!Intel HEX is a generic format which is byte-oriented, and uses byte-wide addressing, but as PIC18s have 16-bit-wide instruction memory, a pair of bytes in the .hex corresponds to a single 16-bit-wide word in the MCU's instruction memory. Thus it is important to distinguish between thebyteaddresses that show up in the .hex, and thewordaddresses which the PIC internally uses for instruction memory.QuoteThe first one is right but the second instruction "efb9 f03e" isn't; it will appear as the byte sequenceb9 ef 3e f0, as you can find in the .hex lines you wrote above:QuoteObserve that the target address of the GOTO is 03eb9, and this is awordaddress; multiply it by 2 to obtain the byte address in the .hex, which will be 07d72.About TBLRD, read the documentation and you'll find that it uses abyteaddress (TBLPTRU:TBLPTRH:TBLPTRL), and reads abytefrom the program memory into TABLAT, which is a byte-wide register.

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: June 12, 2015, 01:58:01 pm
content: Quote from: SuzyC on June 12, 2015, 11:32:03 amIt depends on which PIC family you are looking at.PIC12 and PIC16 have 12 or 14 bit instructions. All the bits are accessed as a single word (there is no 'upper' or 'lower' byte) so the 'byte' address is the same as the 'word' or instruction address. However Intel Hex format requires that a word be recorded as 2 bytes (each with a unique address) so the address in the Hex file must be divided by 2 to get the instruction address.PIC18 has 16 bit instructions which can be accessed one byte at a time. Instruction addresses are always even, and address bit 0 is used to select the upper or lower byte for data access. Therefore PIC18 addresses are true byte addresses (same as Intel Hex) and no translation is required.

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 12, 2015, 02:52:50 pm
content: Bruce Abbot, you have a gift, a way of making things crystal clear!Thank you for your help.thanks again amyk, actually I was going too fast and didn't count my endians.If you google, Intel Hex Format, as I, you will find a quick dozen or two, and you would see their sin in explanation is one of omission, they fail to explain that address representations can vary and then why or else (most frequently) offer no idea that there is a possibility of variation, Bruce Abbot does not!example one: Wikipedia: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 as big endian values.example two: HAMRADIO.SIEach record has a LOAD OFFSET field which specifies the 16-bit starting load offset of the data bytes,therefore this field is only used for Data Records. In other records where this field is not used, it shouldbe coded as four ASCII zero characters ('0000' or 030303030H).example three: Keil.comaaaa is the address field that represents the starting address for subsequent data in the record.example four: arm.comaaaa is the address field that represents the starting address for subsequent data in the record.example five: sbprojects.comAddress fieldThis is the address where the first data byte of the record should be stored. After storing that data byte, the address is incremented by 1 to point to the address for the next data byte of the record. And so on, until all data bytes are stored.The address is represented by a 4 digit hex number (2 bytes), with the MSB first.The order of addresses in the records of a file is not important. The file may also contain address gaps to skip a portion of unused memory.Normally the address aaaa is used to store the first data byte of the record. However this will only allow us to send fileswith a maximum size of 64kb. Therefore Intel designed two extra record formats with which it is possible to pre-set an Extended Segment Address or Upper Linear Base Address.In case of a Extended Segment Address this segment is added to the address field of the record, like in Intel 16 bit processors, to obtain a 20 bit address. This will enable us to send files with a total length of 1Mb. The Extended Segment address is pre-set by 16-bits, given in a special record type.The formula to calculate the target address in case of Extended Segment mode is:Example 6: Ubuntu.comLoad OffsetEach record has a Load Offset field which specifies the 16-bitstarting load offset of the data bytes, therefore this field isonly used for Data Records. In other records where this fieldis not used, it should be coded as four ASCII zero characters(‘‘0000’’ or 0x30303030). This field is two byte, representedas four hexadecimal charactersExample 7: Kana.comAAAA is address in bytesExample 8: eenet.comAfter the number of bytes of data is a 4-digit hexadecimal address. An address of 0A00 appears as0A00.Example 9:Microchip.com Apnote TB025:The address is doubledbecause this format only supports 8-bits (to find the real PICmicro address, simply divide the valueNaturally, since a PIC is something Microchip should know about, I took Microchips answer as sacred.(Address=AAAA / 2.)