  | 
	  | 
		 
	 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		
			PCM programmer
 
 
  Joined: 06 Sep 2003 Posts: 21708
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Tue Apr 19, 2011 5:47 pm     | 
				     | 
			 
			
				
  | 
			 
			
				I've created a technique to solve the problem of how to get 
 
Ex_bootloader.c to compile for a different PIC.  
 
 
The first thing to do is to compile Ex_bootloader.c for the default 16F877
 
and then draw a memory map of all the program segments.    
 
 
The .SYM file lists all the program segments and their address in ROM.
 
I have re-arranged them below, to put them in the correct address order:
 
 	  | Code: | 	 		  
 
ROM Allocation:
 
0004  isr
 
0020  MAIN
 
0020  @cinit  
 
0040  load_program
 
004A  atoi_b16
 
0082  real_load_program
 
0170  @@WRITE_PROGRAM_MEMORY
 
0200  application
 
  | 	  
 
I only have the PCM (and PCH) compilers.  If you have PCWH, etc., then
 
you get the .STA file which has more information, such as the size of each
 
segment and how many bytes are used in each one.   But I don't need it.
 
 
The next step is to create the memory map, with the #org and #define
 
statements that control the starting address and size of each segment.
 
This is for the 16F877, for compiler vs. 4.119. 
 
 	  | Code: | 	 		  
 
0x0000
 
Reset Vector
 
 
0x0004
 
isr()
 
 
#org 0x20, 0x3F
 
main()
 
@cinit()
 
 
#define LOADER_END  0x1FF   // In Bootloader.h
 
#define LOADER_SIZE 0x1BF   // In Bootloader.h
 
 
//      0x40          0x1FF        0x1BF
 
#define LOADER_ADDR  (LOADER_END - LOADER_SIZE)  
 
 
//   0x40,        0x49
 
#org LOADER_ADDR, LOADER_ADDR +9
 
load_program()
 
 
//   0x4A,            0x1FF
 
#org LOADER_ADDR +10, LOADER_END
 
atoi_b16()
 
real_load_program()
 
@@write_program_memory()
 
 
//   0x200,         0x209
 
#org LOADER_END +1, LOADER_END +10
 
application()
 
 | 	  
 
Now we can edit Ex_bootloader.c and change the #include line for the
 
PIC to your desired PIC, the 16F883.   When I compile it, I get this error:
 
 	  | Quote: | 	 		  
 
Out of ROM, A segment or the program is too large: real_load_program
 
Seg 0004A-001FF, 016A left, need 01C1
 
 | 	  
 
The ROM space required by real_load_program() for the 16F883 is
 
larger than the 16F877. Why would this be ?  Look at real_load_program()
 
in the Loader.c file.   Notice the #if-#endif statements.
 
If they are executed, additional ROM space will be required.  To see if
 
this is the case, I'm going to add a #warning message at the start of
 
the #if block, and re-compile:
 
 	  | Quote: | 	 		  
 
 #if getenv("FLASH_ERASE_SIZE") > getenv("FLASH_WRITE_SIZE")
 
                  #warning Flash erase size is greater than the write size | 	  
 
When I compile for the 16F883, I get the warning.  When I compile for
 
the 16F877, I don't get it.   So that's one reason why the code is larger.
 
The #if block is being executed for the 16F883.   
 
 
Another reason is because the @@write_program_memory() routine is
 
much larger for the 16F883 than for the 16F877.    The code for the 
 
16F883 is 68 ROM words larger.  If you comment out the #nolist line
 
at the start of the 16F883.h (or 16F877.h) file and re-compile, you will
 
see the ASM code for @@write_program_memory().
 
 
Another common reason for differences in code size is the start-up code
 
@cinit in main().   It's larger for the 16F883 by 13 ROM words.
 
 
---------------------
 
To fix the problem we need to increase the ROM segment size for 
 
real_load_program. This is controlled by LOADER_END and LOADER_SIZE.
 
They are both defined at the start of the Bootloader.h file
 
 
The compiler error message tells us that it needs 0x57 more ROM words.
 
This is from 0x1C1 - 0x16A = 0x57.     Let's round it up to 0x60.
 
Now let's edit the file and add 0x60 to each of the default values in 
 
Bootloader.h, so the modified code looks like this:
 
 	  | Code: | 	 		  
 
#if defined(__PCM__)
 
   #define LOADER_END   (0x1FF + 0x60)
 
   #define LOADER_SIZE  (0x1BF + 0x60)
 
 | 	   
 
We re-compile, and it gets rid of the real_load_program() error, but now
 
we have a new error.  The main() segment is too small by 9 ROM words:
 
 	  | Quote: | 	 		  Out of ROM, A segment or the program is too large:    MAIN
 
Seg 00020-0003F, 0020 left, need 0029
 
 | 	  
 
This means the solution is more complex.  We need to change the #org
 
statement for main() to increase the size of its segment, and also move
 
up the starting address of the real_load_program() segment.
 
 
Here's the solution:
 
 
Edit Ex_bootloader.c and increase the #org segment for main() by 0x10
 
as shown below in bold:
 
 	  | Quote: | 	 		  
 
#if defined(__PCH__)
 
#org 0x40,0x7F
 
#else
 
#org 0x20, 0x3F + 0x10    // For the PCM compiler
 
#endif
 
void main(void) {
 
   if(!input(PIN_B5))
 
   {
 
      load_program();
 
   }
 
 
   application();
 
}
 
 | 	  
 
Now edit Bootloader.h and add 0x10 to LOADER_END. This will shift the
 
starting point for that block upwards by 0x10 bytes. This allows room for
 
the increased size of the main() segment that we did above.  This change
 
is shown below in bold:
 
 	  | Quote: | 	 		  
 
#if defined(__PCM__)
 
   #define LOADER_END   (0x1FF + 0x60 + 0x10)
 
   #define LOADER_SIZE  (0x1BF + 0x60)
 
 | 	   
 
Finally after doing all this, it compiles with no errors.
 
 
I tested it in hardware. I don't have a 16F883, but I do have a 16F887
 
and it's in the same PIC family.  It required the same changes to the
 
code as given above.   I followed the bootloader procedure that is listed
 
in this post and it worked:
 
http://www.ccsinfo.com/forum/viewtopic.php?t=40920&start=1
 
Here's what it displayed on the terminal. It's working.
 
 	  | Quote: | 	 		  
 
Application program version 1.00
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
 
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
 
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
 
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
 
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
 
105 106 107 108 109 110 111 112 113 114 115 116 117
 
and so on. | 	 
  | 
			 
		  | 
	 
	
		  | 
	 
	
		
			cerr
 
 
  Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Wed Apr 20, 2011 10:04 am     | 
				     | 
			 
			
				
  | 
			 
			
				NICE work PCM. Awesome description of how I can solve the problem! Thanks so much, this is super appreciated. In the meantime I got a bootloader with microchip AN1310 to work successfully but I sure wanna go through the ccs version and apply your changes too!
 
 
Your efforts are much appreciated!
 
Thanks bud! | 
			 
		  | 
	 
	
		  | 
	 
	
		
			SubhamayS
 
 
  Joined: 07 Mar 2012 Posts: 34 Location: jalpaiguri, India 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				| ex_bootloader.c modification for PIC18F4520 | 
			 
			
				 Posted: Sat Dec 20, 2014 1:35 am     | 
				     | 
			 
			
				
  | 
			 
			
				Is it possible to configure 'ex_bootloader.c' for PIC18F4520 ? I am using CCS PCH C Compiler, Version 5.015 and the default 'ex_bootloader.c' is configured with 18F45K22. I have changed the header file and replaced it with 18F4520.h. I have also changed the crystal value to 20MHz (from default value 16MHz) the code is compiling successfully without any error. I proceeded further and verified the output of 'ex_bootloader.c' at the TeraTerm V4.73. I kept PIN_A4 connected to Ground. then pressed the reset button. I got the desired output at the terminal window, which was showing - 
 
 
"Bootloader Version 1.0 
 
Waiting for download..."
 
 
Then I compiled the 'ex_bootload.c' and successfully downloaded the .HEX file in my PIC18F4520.
 
Now as I reset the PIC I am suppose to see the output of 'ex_bootload.c', but nothing is being displayed in the terminal window except some garbage values.
 
 
Is it a problem with the crystal oscillator ? Should I keep it with default value 16MHz ? Please help !!!    | 
			 
		  | 
	 
	
		  | 
	 
	
		
			Ttelmah
 
 
  Joined: 11 Mar 2010 Posts: 19967
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Sat Dec 20, 2014 1:38 am     | 
				     | 
			 
			
				
  | 
			 
			
				Did you change the clock statement in ex_bootload to match your crystal?.
 
 
The fuses and clock statements need to be the same in both bootloader _and_ bootloaded program. | 
			 
		  | 
	 
	
		  | 
	 
	
		
			SubhamayS
 
 
  Joined: 07 Mar 2012 Posts: 34 Location: jalpaiguri, India 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Mon Dec 22, 2014 7:55 am     | 
				     | 
			 
			
				
  | 
			 
			
				 	  | Ttelmah wrote: | 	 		  Did you change the clock statement in ex_bootload to match your crystal?.
 
 
The fuses and clock statements need to be the same in both bootloader _and_ bootloaded program. | 	  
 
 
Thanks a lot for the reply.
 
 
yes I have checked the crystal and it is 20Mhz for both bootloader _and_ bootloaded program.
 
 
while debugging I have added some output_high() in order to drive LEDs to trace the flow of program execution.
 
 
 	  | Code: | 	 		  void main(void) {
 
 
   if(!input(PUSH_BUTTON))
 
   {
 
      printf("\r\nBootloader Version 1.0\r\n");
 
   
 
      // Let the user know it is ready to accept a download
 
      printf("\r\nWaiting for download...");
 
      output_high(PIN_B4); //red LED
 
      load_program();
 
      output_high(PIN_B3); //blue LED
 
   }
 
   application();
 
}
 
 | 	  
 
 
Now after burning this modified 'ex_bootloader.c', when the reset button is pressed it shows the desired message in TeraTerm & the RED led glows. and then after downloading the 'ex_bootload.c', the Blue LED is not glowing. So, is it that there may be a problem in the execution of the function load_program();. I have compared the .SYM files for Both 18F45K22 (default device) & 18F4520 which is given below.
 
 
ROM Allocation: 18F45K22 (Default Device)
 
000008  isr
 
00001E  @const724.call
 
00003A  @const726.call
 
000054  @PSTRINGC_9600_31766_31767
 
000076  @PUTCHARI_BIU_1
 
00007E  atoi_b16
 
0000E4  @FLASHWR
 
000104  @WRITE_PROGRAM_MEMORY
 
000148  real_load_program
 
00031A  load_program
 
000320  MAIN
 
000320  @cinit1
 
000354  @cinit2
 
000500  application
 
 
ROM Allocation: PIC18F4520
 
000008  isr
 
00001E  @const674.call
 
00003A  @const676.call
 
000054  @PSTRINGC_9600_31766_31767
 
000076  @PUTCHARI_BIU_1
 
00007E  atoi_b16
 
0000E4  @FLASHWR
 
000104  @WRITE_PROGRAM_MEMORY
 
000158  real_load_program
 
0003E8  load_program
 
0003EE  MAIN
 
0003EE  @cinit1
 
000414  @cinit2
 
000500  application
 
 
Is it a problem due to differences in code size ? @WRITE_PROGRAM_MEMORY is taking more space in 18F4520 than the default device. Do I need to increase the ROM segment size for @WRITE_PROGRAM_MEMORY & others following !!   | 
			 
		  | 
	 
	
		  | 
	 
	
		
			PCM programmer
 
 
  Joined: 06 Sep 2003 Posts: 21708
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Mon Dec 22, 2014 11:46 pm     | 
				     | 
			 
			
				
  | 
			 
			
				I tested it just now with vs. 5.015, and an 18F4520, with a 16 MHz crystal
 
and it worked OK.  It displayed incrementing numbers on Teraterm:
 
 	  | Quote: | 	 		  
 
Bootloader Version 1.0
 
 
Waiting for download...
 
Application Version 1.0
 
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 
 
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 
 
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 
 
104 105 106 107 108 109 110 111 112 113 114 115 | 	  
 
 
I then removed the 16 MHz crystal and installed a 20 MHz crystal. 
 
I edited both files, ex_bootloader.c and ex_bootload.c, and changed the
 
#use delay() to 20 MHz in each one.   I then re-compiled both projects
 
and programmed ex_bootloader.hex into the 18F4520 with a Pickit 3.
 
Then I did the normal bootload procedure and it worked.
 
 
Your problem sounds like what Ttelmah said.  Maybe you forgot to 
 
re-compile the Ex_bootload project after you edited the Ex_bootload.c file.
 
If you forgot to re-compile it, then it would still be expecting the hardware
 
to have a 16 MHz crystal and it would produce garbage output on a board 
 
running at 20 MHz. | 
			 
		  | 
	 
	
		  | 
	 
	
		
			SubhamayS
 
 
  Joined: 07 Mar 2012 Posts: 34 Location: jalpaiguri, India 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Tue Dec 23, 2014 8:42 am     | 
				     | 
			 
			
				
  | 
			 
			
				 	  | PCM programmer wrote: | 	 		  
 
Your problem sounds like what Ttelmah said.  Maybe you forgot to 
 
re-compile the Ex_bootload project after you edited the Ex_bootload.c file.
 
If you forgot to re-compile it, then it would still be expecting the hardware
 
to have a 16 MHz crystal and it would produce garbage output on a board 
 
running at 20 MHz. | 	  
 
 
Thanks for the reply. I have double checked each step pointed by you but the same problem prevails. The oscillator configuration is alright.
 
But as I am dowloading the 'ex_bootload.hex' through TeraTerm... after completion of download. the same message is being displayed again:
 
 
"Bootloader Version 1.0 
 
Waiting for download..." 
 
 
This I think, is due to the fact that a restart of the program is occurring. and the application(); function is never being called. I think in my case the  program somehow is getting stuck at the call of load_program();.
 
 
If possible could you please provide me the code of 'ex_bootloader.c' you are using for PIC18F4520. | 
			 
		  | 
	 
	
		  | 
	 
	
		
			PCM programmer
 
 
  Joined: 06 Sep 2003 Posts: 21708
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Tue Dec 23, 2014 10:24 am     | 
				     | 
			 
			
				
  | 
			 
			
				I'm not going to post it.  If you have vs. 5.015, then you have the same
 
code.
 
 
Are you sure you're doing the download process correctly ?  This post
 
describes how to do it. Except, CCS changed it to use pin A4 (not pin B5).
 
http://www.ccsinfo.com/forum/viewtopic.php?t=40920&start=1
 
You have to make sure that TeraTerm has XON/OFF enabled in the 
 
Setup / Serial Port / Flow Control menu. | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
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
  
		 |