|
|
View previous topic :: View next topic |
Author |
Message |
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
Understanding hex file |
Posted: Thu Nov 30, 2006 6:55 pm |
|
|
Hi,
I'm just entering the realm of bootloaders and have fairly thoroughly taken apart the ex_bootloader and ex_bootload HEX files. Where the #ORG #SEGMENT #BUILD definitions place instructions in ROM.
------------------------------
The last three lines starting with colon read to me as... Write 10 Bytes at 0x0300000, Finish.
Reading the code in the loader.c I understand that if the addresses are not sequenctial then the ROM is CLEARED with 0xFF up to the next write.
Q1: Is this really just a clear all remaining ROM Data? If so why write 10 Bytes of data? What are these 10Bytes? Is 0x03000000 not beyond the end of the ROM? I'm stuck!
------------------------------
Code: |
#if getenv("FLASH_ERASE_SIZE") > getenv("FLASH_WRITE_SIZE")
if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")/2-1)!=0))
erase_program_eeprom(addr);
next_addr = addr + 1;
#endif
|
I could understand the above, from loader.c, if the #if was a standard if statment.
Q2: Can anyone explain to me why this is a compiler directive? If this is taken out by the comiler then is the remaining memory cleared or left as was?
------------------------------
There are some bytes in memory that are not specifically set by the bootloader or the application. e.g. The four bytes after the reset four bytes.
Q3: Are these bytes cleared (high or low) when the PIC is flashed with the bootloader or are they deliberatlley left alone? Actually I think I've just answered this. Spaces in the application will be set 0xFF by the loader. So know my question is does the ICD programmer do the same?
Thanks your time.
Cheers Scott |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Dec 01, 2006 12:33 am |
|
|
1. What PIC are you using ?
Quote: |
The last three lines starting with colon read to me as... Write 10 Bytes
at 0x0300000, Finish. |
2. Which CCS example file are you compiling, to get the HEX file
with the data listed above ?
3. Can you post a section of the HEX file that shows the line you
mentioned above ? Show that line, and several lines before it. |
|
|
Ttelmah Guest
|
|
Posted: Fri Dec 01, 2006 3:42 am |
|
|
To answer a couple of parts. 0x30000, is a 'special' address, where the configuration fuses are mapped. These program like the main memory, but have a much smaller 'page' size (usually only a single word).
It sounds as if you are looking at code that writes the configuration words.
Best Wishes |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Fri Dec 01, 2006 4:29 pm |
|
|
TTlemah,
Thanks for the info. That makes sense as both the bootloader and application are using the same fuses, see below. I'm not quite sure, but I don't think the application can change the FUSES such that the bootloader will not work. Should the FUSES always be the same? Or can you change them with impunity?
FUSES in the application, and bootloader.
Code: |
#include <18F258.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
|
PCM programmer,
Thanks for the response, I hope the following covers all the questions you asked.
I'm using PIC18F258 which is one of the CAN enabled PICs.
This is the tail end of the application HEX file. Compiled from ex_bootload.c (which includes bootloader.h). So far I've only changed the target and clock, and added comments, lots of them...
Code: |
:1005F000066A076A075088DF000905E0072A9EA8F7
:10060000FED7AD6EF7D7062A06C007F01B0E086EA0
:0E061000AAD7200E9EA8FED7AD6EF5D7030028
:020000040030CA
:0E00000000220F0E000081000FC00FE00F4025
:00000001FF
;PIC18F258
|
This is the tail end of the bootloader HEX file. ex_bootloader.c (which includes bootloader.h and loader.c)
Code: |
:1003F0007F6B120E7E6F89DE79C04DF001C04CF02C
:1004000047A004D0060E9EA8FED7AD6E110E9EA882
:10041000FED7AD6EF0D6060E9EA8FED7AD6E110EBD
:080420009EA8FED7AD6E000C92
:04050000FFD7000C15
:020000040030CA
:0E00000000220F0E000081000FC00FE00F4025
:00000001FF
;PIC18F258
|
The line thatstarts ":02" I understand to be a set Most Significant Word for the ROM 0x0030.
The folowing line ":0E" is write 12 (sorry I did mistakenly say 10 earlier) bytes at Least Significant Word for ROM 0x0000. Therebye writing the 12 bytes to 0x00300000.
The line below that is the END OF HEX FILE statment.
The last line does not start with a colon and is ignored.
I believe the line breceeding the above starting ":04" is the bootloader fake/dummy application which gets overwritten by the start of the real application.
My questions arose from wanting to modify the bootloader to suit my application, there are several bootloader models I'd like to use/try. To further my understanding of the #ORG and #Build directives I have written a little PC application which overlays two HEX files (so I could fully understand what was going on... So here's the output, which I've commented in line with my understanding of the compiler directives written in the example code. I thought you might like a look.
Code: |
+---------+----------------------------------------------------+----------------------------------+
| ROM | DATA | FROM WHICH HEX FILE |
| ADDRESS | | 1=Bootloader |
| | | 2=Applicatoin |
| | | 3=both |
+---------+----------------------------------------------------+----------------------------------+
| | | |
| | | |
#define LOADER_END 0x4FF
#define LOADER_SIZE 0x3FF
#define LOADER_ADDR LOADER_END-LOADER_SIZE
THE BOOTLOADER RESET
| NO #BUILD DIRECTIVE IN ex_bootloader.c THEREFORE UNMOVED.
|
| THE BOOT LOADER INTERUPTS GO HERE
| | #ORG default - ex_bootloader.c
| |
0x000000 20 EF 00 F0 84 EF 02 F0 00 00 00 00 1 1 1 1 1 1 1 1 1 1 1 1
0x000010 00 00 00 00 00 00 00 00 8C EF 02 F0 10 00 1 1 1 1 1 1 1 1 1 1 1 1 1 1
BOOTLOADER MAIN - APP/BOOTLOADER DECISION
| #org 0x40,0x7F - ex_bootloader.c
|
0x000040 F8 6A D0 9E EA 6A E9 6A 40 0E AF 6E 26 0E AC 6E 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000050 90 0E AB 6E C1 80 C1 82 C1 84 C1 96 93 8A 81 BA 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000060 01 D0 4E D8 4D DA 03 00 1 1 1 1 1 1 1 1
PROXY LOADER TO FIX LOCATION)
| #ORG LOADER_ADDR, LOADER_ADDR+9 - loader.c
|
| REAL LOADER OR ONE OF IT'S FUNCTIONS
| | #ORG LOADER_ADDR+10, LOADER_END auto=0 default - loader.c
| |
0x000100 77 D8 00 0C 80 6B 81 6B 81 51 1 1 1 1 1 1 1 1 1 1
0x000110 01 08 29 E3 7F C0 03 F0 7E C0 E9 FF 7F C0 EA FF 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000120 EF 50 40 08 0E E2 80 51 10 0D F3 CF 82 F0 7E C0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000130 E9 FF 7F C0 EA FF EF 50 82 25 BF 0F 0A 0F 80 6F 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000140 0C D0 80 51 10 0D F3 CF 82 F0 7E C0 E9 FF 7F C0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000150 EA FF EF 50 82 25 D0 0F 80 6F 81 51 81 2B 7E 2B 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000160 D8 B4 7F 2B D4 D7 80 C0 01 F0 00 0C F2 50 03 6E 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000170 F2 9E A6 8E A6 84 0F 01 55 0E A7 6E AA 0E A7 6E 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000180 A6 82 00 00 03 50 F2 12 00 01 00 0C D0 8C A6 9C 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000190 F6 50 07 0B 00 6E F8 0E F6 16 0A 00 79 C0 01 F0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0001A0 79 C0 02 F0 08 0E 00 66 02 26 02 50 07 0F F8 0B 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0001B0 02 6E F6 50 00 66 07 D0 01 0F 3F 0B 04 E1 A6 88 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0001C0 09 00 D4 DF 0A 00 00 66 07 D0 EE CF F5 FF 01 52 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0001D0 04 E0 0F 00 01 06 03 D0 00 06 0B 00 0C 00 07 0E 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0001E0 F6 14 07 0A D8 B4 C2 DF 02 2E E3 D7 F8 6A 00 0C 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0001F0 47 92 4C 6A 4D 6A 47 B2 0E D1 06 6A 03 6A 06 50 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000200 07 0F E9 6E 00 0E 03 20 EA 6E 9E AA FE D7 AE CF 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000210 EF FF 06 50 06 2A 03 6A 07 0F E9 6E 00 0E 03 20 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000220 EA 6E EF 50 0D 08 03 E0 06 50 40 08 E7 E2 13 0E 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000230 9E A8 FE D7 AD 6E 47 80 07 50 3A 08 D8 A4 E0 D0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000240 7F 6B 08 0E 7E 6F 61 DF 01 C0 58 F0 7F 6B 0A 0E 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000250 7E 6F 5B DF 01 C0 79 F0 7F 6B 0C 0E 7E 6F 55 DF 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000260 79 C0 4B F0 01 C0 4A F0 7F 6B 0E 0E 7E 6F 4D DF 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000270 01 C0 49 F0 4C C0 50 F0 4D C0 51 F0 4A C0 4E F0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000280 4B C0 4F F0 49 2C 02 D0 47 82 BA D0 51 52 05 E1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000290 50 52 03 E1 4F 50 00 08 08 E2 51 52 06 E1 50 52 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0002A0 04 E1 4F 50 04 08 D8 B0 AB D0 51 52 D8 A4 A8 D0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0002B0 50 50 2F 08 D8 A0 A4 D0 48 6A 01 0E 57 6E 03 0E 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0002C0 06 5C 57 5C 10 E2 03 6A 57 50 07 0F 79 6F 00 0E 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0002D0 03 20 7A 6F 7F 6F 79 C0 7E F0 17 DF 01 50 48 26 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0002E0 02 0E 57 26 EC D7 FF 0E D8 80 48 54 01 0F 48 6E 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0002F0 03 0E 06 5C 03 6A 07 0F 7A 6F 00 0E 03 20 7B 6F 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000300 7F 6F 7A C0 7E F0 01 DF 01 50 48 5C 02 E0 47 90 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000310 77 D0 49 52 64 E1 09 0E 57 6E 56 6A 03 0E 06 5C 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000320 57 5C 1F E2 56 50 56 2A 03 6A 59 0F 01 6E 00 0E 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000330 03 22 01 C0 7A F0 03 C0 7B F0 03 6A 57 50 07 0F 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000340 7C 6F 00 0E 03 20 7D 6F 7F 6F 7C C0 7E F0 DD DE 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000350 7B C0 EA FF 7A C0 E9 FF 01 C0 EF FF 02 0E 57 26 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000360 DD D7 52 50 4E 5C 09 E1 53 50 4F 5C 06 E1 54 50 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000370 50 5C 03 E1 55 50 51 5C 19 E0 4E 50 01 0B 00 6E 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000380 01 6A 02 6A 03 6A 00 52 06 E1 01 52 04 E1 02 52 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000390 02 E1 03 52 0B E0 D0 8C 50 C0 F8 FF 4F C0 F7 FF 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0003A0 4E C0 F6 FF A6 88 A6 9C E1 DE F8 6A 01 0E 4E 24 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0003B0 52 6E 00 0E 4F 20 53 6E 00 0E 50 20 54 6E 00 0E 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0003C0 51 20 55 6E 50 C0 F8 FF 4F C0 F7 FF 4E C0 F6 FF 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0003D0 EA 6A 59 0E E9 6E 58 C0 79 F0 D8 DE 11 D0 49 50 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0003E0 04 08 0E E1 7F 6B 10 0E 7E 6F 8F DE 01 C0 79 F0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x0003F0 7F 6B 12 0E 7E 6F 89 DE 79 C0 4D F0 01 C0 4C F0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000400 47 A0 04 D0 06 0E 9E A8 FE D7 AD 6E 11 0E 9E A8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000410 FE D7 AD 6E F0 D6 06 0E 9E A8 FE D7 AD 6E 11 0E 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0x000420 9E A8 FE D7 AD 6E 00 0C 1 1 1 1 1 1 1 1
#org 0, LOADER_END {} - bootloader.h (APP ONLY) PROTECTS THE ABOVE FROM BEING OVER WRITTEN
THE BOOTLOADER "DUMMY" APPLICATION PUT HERE AND IS OVER WRITTEN
| #org LOADER_END+2,LOADER_END+20 - bootloader.h
| THE APPLICATION RESET
| #build(reset=LOADER_END+1, interrupt=LOADER_END+9) - bootloader.h
|
| THE INTERUPTS START HERE - THE REST OF THE APPLICATION FOLLOWS
| |#build(reset=LOADER_END+1, interrupt=LOADER_END+9 - bootloader.h (APP ONLY)
| |
0x000500 EA EF 02 F0 F7 6A 18 0F F6 6E 05 0E 3 3 3 3 2 2 2 2 2 2 2 2
0x000510 F7 22 09 00 F5 50 12 00 0D 0A 41 70 70 6C 69 63 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x000520 61 74 69 6F 6E 20 70 72 6F 67 72 61 6D 20 76 65 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x000530 72 73 69 6F 6E 20 31 2E 30 30 20 0D 0A 00 0A 50 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x000540 01 6A 09 5C 03 E2 09 C0 00 F0 0C D0 00 6A 08 0E 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x000550 0B 6E 09 36 00 36 0A 50 00 5C D8 B0 00 6E 01 36 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x000560 0B 2E F7 D7 00 0C 01 50 07 C0 09 F0 64 0E 0A 6E 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x000570 E6 DF 00 C0 07 F0 01 50 30 0E 07 E1 08 A2 0D D0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x000580 08 B6 0B D0 08 B8 20 0E 03 D0 08 96 08 98 08 80 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x000590 01 26 01 50 9E A8 FE D7 AD 6E 07 C0 09 F0 0A 0E 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x0005A0 0A 6E CD DF 00 C0 07 F0 01 50 30 0E 06 E1 08 B6 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x0005B0 09 D0 08 A0 07 D0 08 B8 20 0E 01 26 01 50 9E A8 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x0005C0 FE D7 AD 6E 30 0E 07 26 07 50 9E A8 FE D7 AD 6E 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x0005D0 09 EF 03 F0 F8 6A D0 9E EA 6A E9 6A 40 0E AF 6E 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x0005E0 26 0E AC 6E 90 0E AB 6E C1 80 C1 82 C1 84 C1 96 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x0005F0 06 6A 07 6A 07 50 88 DF 00 09 05 E0 07 2A 9E A8 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x000600 FE D7 AD 6E F7 D7 06 2A 06 C0 07 F0 1B 0E 08 6E 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0x000610 AA D7 20 0E 9E A8 FE D7 AD 6E F5 D7 03 00 2 2 2 2 2 2 2 2 2 2 2 2 2 2
CLEAR ALL BYTES TO HERE AND WRITE FUSES TO SPECIAL MEMORY LOCATION
0x300000 00 22 0F 0E 00 00 81 00 0F C0 0F E0 0F 40 3 3 3 3 3 3 3 3 3 3 3 3 3 3
|
Cheers Scott |
|
|
Ttelmah Guest
|
|
Posted: Sat Dec 02, 2006 3:35 am |
|
|
You have to be very careful about fuses.
Generally having them the 'same', is easy, and safe.
An example of having them 'different', and stopping the bootloader working, would be to have a code protect fuse in the main code. The bootloader will program this, and it will not have effect till the next reboot. Once it is in force (depending on the one involved), it may well then stop the bootloader being able to work. These particular fuses, cannot be cleared, except by a full erase, which will remove the bootloader as well...
Best Wishes |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Sat Dec 02, 2006 1:23 pm |
|
|
Thanks Ttelmah,
Now I just need to know why the clear memory section is "compiled in" if FLASH_ERASE_SIZE > FLASH_WRITE_SIZE.
Think I've just been saved by the PDF manual... because I'd never have found this in the hard copy I usually use
There is a section "Additional Notes: Clarifications about the functions to write to program memory:"
I now understand that there are two types of PIC, hence the compiler directive.
Therefore, this section of code does the following:
Code: |
// IF CORRECT CHIP TYPE
#if getenv("FLASH_ERASE_SIZE") > getenv("FLASH_WRITE_SIZE")
// IF NOT THE LAST ADDRESS PLUS ONE &&
// AND NOT AT START OR MIDDLE OF BLOCK
// NOTE: IF AT START WRITE_PROGRAM_MEMORY WILL CLEAR THE BLOCK
// NOTE: IF AT MIDDLE THEN DO NOT ERASE BECAUSE THIS BLOCK MAY HAVE BEEN WRITTEN TO BEFORE.
if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")/2-1)!=0))
// THEN ERASE WHOLE BLOCK
erase_program_eeprom(addr);
// INCREMENT COUNTER
next_addr = addr + 1;
#endif
// WRITE THE HEX FILE DATA
// NOTE: IF AT START OF ERASE BLOCK WILL AUTOMATICALLY ERASE WHOLE BLOCK
write_program_memory(addr, data, count);
|
The bootloader does not, as previously stated, clear ALL ROM between locations specified in the HEX file. It does however clear all Erase Blocks writen to.
Is this correct? Especially my comments about the MIDDLE and clearing memory.
The bootloader (if loading a smaller program than previous) leaves the non-overwritten blocks with the previous program information. There is no need to clear these areas because there are no jumps to it. Do programmers (generally) clear the entire ROM or do they do they do the same as the bootloader and only clear the sections the HEX file they are writing to? I'm using MPLAB and ICD 2, which does by default, but does have the option not to. What are the implications, is it just speed? I ask because I'm wondering whether my bootloader (when I start to write it, once I fully understand this one) should or should not clear all application reserved memory.
Thanks Scott
PS as an aside (but linked at the hip)... Is there a thread where the pros and cons of having the bootloader reside in High or Low memory discussed? I'm sure there must be but I can't find it. From what I've read this only has any real implications on interupts, and as I'd like to use interupts in both (and the same interupt) then I'd better understand this as well. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|