| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| edgarp 
 
 
 Joined: 18 Jun 2024
 Posts: 6
 
 
 
			    
 
 | 
			
				| interrupt in bootloader |  
				|  Posted: Fri Jun 28, 2024 5:42 pm |   |  
				| 
 |  
				| device : 16F1939 
 compiler version: 5.116
 
 from what I understood in this post,
 https://www.ccsinfo.com/forum/viewtopic.php?t=60380
 if you use the bootloader example the ISR would be placed at the application code area not bootloader's area,  making the bootloader dependent on the application.
 
 I would like to make it so that the interrupt is placed in the bootloader's area and make the application use the ISR placed on the bootloader.
 
 to get it to work like this  I Would like to know if the following configuration would be what you would expect to see.
 
 
 
 
  	  | Code: |  	  | #define LOADER_END 0x1ffF
 
 
 #build(reset=LOADER_END+1)
 
 #org 0, 0x7FF {}
 #org 0x800, 0xFFF{}
 #org 0x1000, 0x17FF {}
 #org 0x1800, 0x1ffF {}
 
 
 
 #IMPORT (FILE=Botlloader_interrupt_test.hex,HEX,RANGE=0:LOADER_SIZE)
 
 
 BYTE next_in = 0;
 BYTE global_flag =0;
 BYTE JUMP_flag =0;
 
 #byte global_flag = 40
 #byte next_in = 44
 #byte JUMP_flag = 48
 
 //#define TICKS_PER_SECOND 10000
 void main(void)
 {
 unsigned int16 tick;
 
 printf("Application 1.2 running\r\n");
 enable_interrupts(INT_RDA);
 enable_interrupts(GLOBAL);
 tick = get_ticks();
 
 for(;;)
 {
 if (global_flag)
 {
 if ((get_ticks() - tick) >= TICKS_PER_SECOND/5)
 {
 tick = get_ticks();
 output_toggle(EXT_WATCHDOG_IO);
 }
 }
 else
 {
 if ((get_ticks() - tick) >= TICKS_PER_SECOND/10)
 {
 tick = get_ticks();
 output_toggle(EXT_WATCHDOG_IO);
 }
 if (JUMP_flag)
 {
 //          application();
 }
 
 }
 }
 }
 
 
 | 
 
 I would be using the flags set by the interrupt in the main loop.
 
 the bootloader configuration would be like this :
 
  	  | Code: |  	  | #define _bootloader 1
 #define LOADER_END 0x1ffF//
 
 
 #org LOADER_END+1,LOADER_END+3
 void application(void) {
 while(TRUE);
 
 
 #define BUFFER_SIZE 32
 BYTE buffer[BUFFER_SIZE];
 BYTE next_in = 0;
 BYTE next_out = 0;
 BYTE global_flag =0;
 BYTE JUMP_flag =0;
 
 #byte global_flag = 40
 #byte next_in = 44
 #byte JUMP_flag = 48
 
 
 #int_rda
 void serial_isr()
 {
 int t;
 buffer[next_in]=getc();
 t=next_in;
 if (  buffer[next_in] == 0x03)
 {
 global_flag =  ~global_flag;
 }
 if (  buffer[next_in] == 0x05)
 {
 JUMP_flag =  ~JUMP_flag;
 }
 
 next_in=(next_in+1) % BUFFER_SIZE;
 if(next_in==3)
 next_in=0;           // Buffer full !!
 
 printf("B");
 }
 
 }
 
 
 void main(void)
 {
 unsigned int16 tick;
 
 printf("Bootloader 1.1 running\r\n");
 enable_interrupts(INT_RDA);
 enable_interrupts(GLOBAL);
 tick = get_ticks();
 
 for(;;)
 {
 if (global_flag)
 {
 if ((get_ticks() - tick) >= TICKS_PER_SECOND/2)
 {
 tick = get_ticks();
 output_toggle(EXT_WATCHDOG_IO);
 }
 }
 else
 {
 if ((get_ticks() - tick) >= TICKS_PER_SECOND/4)
 {
 tick = get_ticks();
 output_toggle(EXT_WATCHDOG_IO);
 }
 if (JUMP_flag)
 {
 application();
 }
 
 }
 }
 }
 
 
 
 | 
 
 I Kept things that are not relevant out of the code, but if it is easier to follow I could just post the whole file.
 
 -would I need to make use of the #build(share_interrupts) directive at all?
 
 -at the application code it the build directive is only setting the reset, would it be good to also set the interrupt like this  ?
 // #build(reset=LOADER_END+1, interrupt=4)
 
 
 Thanks in advance for any help.
 Edgar
 |  |  
		|  |  
		| asmallri 
 
 
 Joined: 12 Aug 2004
 Posts: 1660
 Location: Perth, Australia
 
 
			        
 
 | 
			
				| Re: interrupt in bootloader |  
				|  Posted: Fri Jun 28, 2024 7:39 pm |   |  
				| 
 |  
				| I know a thing or two about bootloaders. The question to ask yourself is why do you need a bootloader to support interrupts? 
 A bootloader really has a single task - to bootload an image.
 
 Adding interrupt capability in the bootloader, when unnecessary, just adds complexity and latency to the application. It typically requires remapping of interrupt vectors, and double jump on interrupt. The first to the interrupt handler of the bootloader and the second to the application.
 
 The method I use is to reserve the bootloader vectors and the remainder of the first page of program memory for the application. The application is compiled ti reserve the program memory space used by the bootloader. This way the application image can run unchanged whether or not the bootloader is present. This greatly simplifies application development and debugging.
 _________________
 Regards, Andrew
 
 http://www.brushelectronics.com/software
 Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
 
 Last edited by asmallri on Wed Jul 03, 2024 6:19 pm; edited 1 time in total
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Jun 29, 2024 5:32 am |   |  
				| 
 |  
				| There can be an advantage to doing this, but it does bring potential issues.
 So (for example), imagine you have a very well written neat serial
 handler, and are using no other  interrupts. Provided  you are 100%
 certain that this will never need to change, using it in both the
 bootloader and the main code could make a lot of sense. Now the
 issues are that first this implies you are stuck with the handlers in
 the bootloader. If any fault is found, you have to program the whole
 chip, and that you are restricted to only using the interrupts for which
 the bootloader has handlers.
 However you then have to realise a very simple thing. Your code never
 actually 'uses' an interrupt handler. It only uses the variables that connect
 'to' it. So in the example of the serial ISR, you have the buffered gutc
 routine, which reads from the buffer, and updates the counters, and the
 interrupt handler itself, then handles putting the data into this buffer.
 So you can use the routine in the bootloader, by simply declaring these
 same variables in the main code, and #locating these to the locations
 used in the bootloader, then enabling the interrupt. Have a duplicate
 buffered getc routine, and the bootloader ISR will then handle this
 interrupt.
 |  |  
		|  |  
		| asmallri 
 
 
 Joined: 12 Aug 2004
 Posts: 1660
 Location: Perth, Australia
 
 
			        
 
 | 
			
				|  |  
				|  Posted: Sat Jun 29, 2024 6:10 am |   |  
				| 
 |  
				| You have not convinced me but maybe this is because I use common CPU boards across multiple projects. The bootloaders, once installed, stay on the board irrespective of the project / application. I would rarely ever changed the bootloader unless I am using encryption in which case I have to accommodate different encryption keys and mechanisms. 
 Having a dependency between the bootloaders and applications is, in my opinion just creating a problem down the track.
 _________________
 Regards, Andrew
 
 http://www.brushelectronics.com/software
 Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Jun 29, 2024 9:35 am |   |  
				| 
 |  
				| For 99% of situations, I'd say you are right. The 1%, is the odd situation,, where (for example), you are very restricted on space, and have just
 enough room in the allocated page for the bootloader, to have this extra
 handling, which then saves space for the main program.
 I did this decades ago, when dealing with an early PIC, and was very
 short of space, but needed to offer bootloader updates for the main code.
 In recent years, where I will always if possible use a chip larger than I
 actually need, I have never had to do it again....
  |  |  
		|  |  
		| asmallri 
 
 
 Joined: 12 Aug 2004
 Posts: 1660
 Location: Perth, Australia
 
 
			        
 
 | 
			
				|  |  
				|  Posted: Sun Jun 30, 2024 6:53 pm |   |  
				| 
 |  
				|  	  | Ttelmah wrote: |  	  | For 99% of situations, I'd say you are right. The 1%, is the odd situation,, where (for example), you are very restricted on space, and have just
 enough room in the allocated page for the bootloader, to have this extra
 handling, which then saves space for the main program.
 I did this decades ago, when dealing with an early PIC, and was very
 short of space, but needed to offer bootloader updates for the main code.
 In recent years, where I will always if possible use a chip larger than I
 actually need, I have never had to do it again....
  | 
 
 I agree - this would be a valid use case but, for anyone designing a new product that needs to do this, it is an indication that they should have spent a few more cents to buy the next variant of the processor with the amount flash to support the what if ...
 _________________
 Regards, Andrew
 
 http://www.brushelectronics.com/software
 Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
 |  |  
		|  |  
		| edgarp 
 
 
 Joined: 18 Jun 2024
 Posts: 6
 
 
 
			    
 
 | 
			
				| Re: interrupt in bootloader |  
				|  Posted: Tue Jul 02, 2024 10:26 am |   |  
				| 
 |  
				|  	  | asmallri wrote: |  	  | I know a thing or two about bootloaders. The question to ask yourself is why do you need a bootloader to support interrupts? 
 A bootloader really has a single task - to bootload an image.
 
 Adding bootloader capability in the bootloader, when unnecessary, just adds complexity and latency to the application. It typically requires remapping of interrupt vectors, and double jump on interrupt. The first to the interrupt handler of the bootloader and the second to the application.
 
 The method I use is to reserve the bootloader vectors and the remainder of the first page of program memory for the application. The application is compiled ti reserve the program memory space used by the bootloader. This way the application image can run unchanged whether or not the bootloader is present. This greatly simplifies application development and debugging.
 | 
 
 this bootloader uses encrypted firmware over a proprietary protocol which the application also uses, it is transmitted over I2C  to an slave device.
 
 Latency or complexity is not a priority for this task but  we would like to make the bootloader completely standalone from application.
 |  |  
		|  |  
		| edgarp 
 
 
 Joined: 18 Jun 2024
 Posts: 6
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Jul 02, 2024 10:41 am |   |  
				| 
 |  
				|  	  | Ttelmah wrote: |  	  | There can be an advantage to doing this, but it does bring potential issues.
 So (for example), imagine you have a very well written neat serial
 handler, and are using no other  interrupts. Provided  you are 100%
 certain that this will never need to change, using it in both the
 bootloader and the main code could make a lot of sense. Now the
 issues are that first this implies you are stuck with the handlers in
 the bootloader. If any fault is found, you have to program the whole
 chip, and that you are restricted to only using the interrupts for which
 the bootloader has handlers.
 However you then have to realise a very simple thing. Your code never
 actually 'uses' an interrupt handler. It only uses the variables that connect
 'to' it. So in the example of the serial ISR, you have the buffered gutc
 routine, which reads from the buffer, and updates the counters, and the
 interrupt handler itself, then handles putting the data into this buffer.
 So you can use the routine in the bootloader, by simply declaring these
 same variables in the main code, and #locating these to the locations
 used in the bootloader, then enabling the interrupt. Have a duplicate
 buffered getc routine, and the bootloader ISR will then handle this
 interrupt.
 | 
 
 yes, this is a risk we are willing to take, extensive testing will be done to try to avoid this to happen.
 
 We would like to keep the bootloader completely standalone from the application incase the application memory area gets corrupted. That's why we would like to put the interrupt on the bootloader and make the application  use  the variables hooked to it.  do you have any comments on the code itself ?specially the set up of the interrupt.
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Jul 03, 2024 1:33 am |   |  
				| 
 |  
				| I have to reiterate Andrews comment. There is honestly no reason to use the interrupt in the bootloader. So just poll the serial here, and use interrupts
 only in the main code. It is much neater and less likely to give issues.
 If you do decide to embed an ISR, there is nothing special involved at all
 just enable the interrupt in the main, and have a copy of the bgetc routine
 here that references the variables #located at the locations use in the
 bootloader.
 |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |