Forums

how to ISR code with lesser memory usage(Urgent)

Started by lallisidhu May 17, 2008
Hi all,

Could anybody help me or guide me to write a better ISR code which uses
lesser memory and compiles smaller hex file.The problem I am facing is if I
use too many 'if else' conditions in my ISR the hex file compiles shoots to
18Kb whereas if i use one or two conditions only the hex file is around 5Kb
.I want my compiled Hex file to be around 8-10 Kb.Below is my code of ISR.


//
***************************************************************************************
// Low Priority Interrupt
//
***************************************************************************************
void HIGH_ISR (void);
#pragma code high_vector_section=0x08
void high_vector (void)
{
	_asm 
		goto HIGH_ISR 
	_endasm
}
#pragma code
#pragma interrupt HIGH_ISR
void HIGH_ISR (void)
{

	if (PIR1bits.RCIF == 1)		// If USART Rx Flag is set
	{
    UART_Data.Input = ReadUSART();	// Get character USART module
  

 if(UART_Data.Input == 0x11)
        {        
         EE_Address = 0xAA;
         EE_Data = Current_time;
         Write_EEPROM();

         EE_Address = 0xAB;
         EE_Data = Current_ports;
         Write_EEPROM();
        }
  
       else if(UART_Data.Input == 0x12)
        {
           Read_EE();          
        printf("\nCurrent Time settings = %d", eet);
        printf("\nCurrent Port settings = %d", eep);
        }
        
    else if(UART_Data.Input == 0x13)
        {
      printf("\nCurrent Time settings = %x", Current_time);
        }
        
       else if(UART_Data.Input == 0x14)
        {
         printf("\nCurrent Port settings = %x", Current_ports);
        }
       
      else if(UART_Data.Input == 0x15)
        {
         Current_time = Default_time;
         Current_ports = Default_ports;
		 delay = (Current_time*5);
//         Set_Port_Time();
         printf("\nCurrent Port settings = %x", Current_ports);
        }

     else if((UART_Data.Input >= 0x21) && (UART_Data.Input <= 0x2A))
         {
              
              Current_ports = UART_Data.Input;
             printf("\n%x",UART_Data.Input);                       
        }

      else if((UART_Data.Input == 0x31) || (UART_Data.Input == 0x33) ||
(UART_Data.Input == 0x35) || (UART_Data.Input == 0x37) || (UART_Data.Input
== 0x39))
         {
              Current_ports = UART_Data.Input;
              printf("\n%x",Current_ports);                    
        } 

       else if(UART_Data.Input >= 0x80)
        {
            Current_time = ((UART_Data.Input) & (0x7F)); 
            printf("\nTiming Selected = %dms",Current_time*50);
        	delay = (Current_time*5);
		//    Set_Port_Time();
        } 


	else if(UART_Data.Input < 0x80)
       {
           PORTB = 0x00;
	       PORTC = 0x00;
            ports = ((UART_Data.Input) & (0x0F)) ;    
            if( (ports >= 1) && (ports <= 10) )
            {
              Current_ports = ports;
              printf("\nPorts Selected higher priority intr =
%d",Current_ports); 
             }
            else{
            printf("\n Enter valid ports number (1-10) \n"); 
	      }
       }

     
       UART_Data.Flag_UART_RX = 1;
	   PIR1bits.RCIF = 0;				// Clear the interrupt flag
	}	
}


Could anybody help me over this I desperately need to reduce my code size
to flash to MCU.

Thank you all .Appreciate if anybody can guide over an alternative
strategy for 'if else'.





lallisidhu ha scritto:
> Hi all, > > Could anybody help me or guide me to write a better ISR code which uses > lesser memory and compiles smaller hex file.The problem I am facing is if I > use too many 'if else' conditions in my ISR the hex file compiles shoots to > 18Kb whereas if i use one or two conditions only the hex file is around 5Kb > .I want my compiled Hex file to be around 8-10 Kb.Below is my code of ISR. >
You can try to refactor your code to use a switch, sometimes the compiler is smart enough to convert your code to a table jump. Or you may try to implement a lookup table instead of manually check for every possible UART_Data.Input value. Ciao -- _|/ Francesco Sacchi - Develer S.r.l., R&D dept. |\ http://www.develer.com/ - http://www.bertos.org
On Sat, 17 May 2008 07:02:23 -0500, "lallisidhu"
<lallisidhu@gmail.com> wrote:

>Hi all, > >Could anybody help me or guide me to write a better ISR code which uses >lesser memory and compiles smaller hex file.The problem I am facing is if I >use too many 'if else' conditions in my ISR the hex file compiles shoots to >18Kb whereas if i use one or two conditions only the hex file is around 5Kb >.I want my compiled Hex file to be around 8-10 Kb.Below is my code of ISR.
For one thing, you're using stdio library functions inside the ISR. In your (unspecified) architecture, is printf() reentrant? Even if it is, you might want to separate [read the UART] from [handle the results of the read] into foreground and background processes. Have the ISR simply read and queue the characters, let the main execution thread handle the characters. -- Rich Webb Norfolk, VA
lallisidhu schreef:
> Hi all, > > Could anybody help me or guide me to write a better ISR code which uses > lesser memory and compiles smaller hex file.The problem I am facing is if I > use too many 'if else' conditions in my ISR the hex file compiles shoots to > 18Kb whereas if i use one or two conditions only the hex file is around 5Kb > I want my compiled Hex file to be around 8-10 Kb.Below is my code of ISR. > > > // > *************************************************************************************** > // Low Priority Interrupt > // > *************************************************************************************** > void HIGH_ISR (void); > #pragma code high_vector_section=0x08 > void high_vector (void) > { > _asm > goto HIGH_ISR > _endasm > } > #pragma code > #pragma interrupt HIGH_ISR > void HIGH_ISR (void) > { > > if (PIR1bits.RCIF == 1) // If USART Rx Flag is set > { > UART_Data.Input = ReadUSART(); // Get character USART module > > > if(UART_Data.Input == 0x11) > { > EE_Address = 0xAA; > EE_Data = Current_time; > Write_EEPROM(); > > EE_Address = 0xAB; > EE_Data = Current_ports; > Write_EEPROM(); > } > > else if(UART_Data.Input == 0x12) > { > Read_EE(); > printf("\nCurrent Time settings = %d", eet); > printf("\nCurrent Port settings = %d", eep); > } > > else if(UART_Data.Input == 0x13) > { > printf("\nCurrent Time settings = %x", Current_time); > } > > else if(UART_Data.Input == 0x14) > { > printf("\nCurrent Port settings = %x", Current_ports); > } > > else if(UART_Data.Input == 0x15) > { > Current_time = Default_time; > Current_ports = Default_ports; > delay = (Current_time*5); > // Set_Port_Time(); > printf("\nCurrent Port settings = %x", Current_ports); > } > > else if((UART_Data.Input >= 0x21) && (UART_Data.Input <= 0x2A)) > { > > Current_ports = UART_Data.Input; > printf("\n%x",UART_Data.Input); > } > > else if((UART_Data.Input == 0x31) || (UART_Data.Input == 0x33) || > (UART_Data.Input == 0x35) || (UART_Data.Input == 0x37) || (UART_Data.Input > == 0x39)) > { > Current_ports = UART_Data.Input; > printf("\n%x",Current_ports); > } > > else if(UART_Data.Input >= 0x80) > { > Current_time = ((UART_Data.Input) & (0x7F)); > printf("\nTiming Selected = %dms",Current_time*50); > delay = (Current_time*5); > // Set_Port_Time(); > } > > > else if(UART_Data.Input < 0x80) > { > PORTB = 0x00; > PORTC = 0x00; > ports = ((UART_Data.Input) & (0x0F)) ; > if( (ports >= 1) && (ports <= 10) ) > { > Current_ports = ports; > printf("\nPorts Selected higher priority intr = > %d",Current_ports); > } > else{ > printf("\n Enter valid ports number (1-10) \n"); > } > } > > > UART_Data.Flag_UART_RX = 1; > PIR1bits.RCIF = 0; // Clear the interrupt flag > } > } > > > Could anybody help me over this I desperately need to reduce my code size > to flash to MCU. > > Thank you all .Appreciate if anybody can guide over an alternative > strategy for 'if else'.
If at all possible consider removing printf() from all of your code. Chances are that the printf() code consumes many times more memory than the if-else-if code in your ISR.
lallisidhu wrote:

> Could anybody help me or guide me to write a better ISR code which uses > lesser memory and compiles smaller hex file.
For starters, you're doing way too much work inside your ISR. As a rule of thumb, ISRs shouldn't usually have to call more than one other function. If their jobs are big enough to be delegated to a separate function, an ISR shouldn't be trying to do more than one of them. Stuff like calling printf() or performing an EEPROM write operation is generally out of the question for an ISR. You'd be blocking further interrupts for far too long.
> The problem I am facing is if I use too many 'if else' conditions in > my ISR the hex file compiles shoots to 18Kb whereas if i use one or > two conditions only the hex file is around 5Kb.
I rather doubt that the number of conditionals, in and of itself, is the root cause of that code explosion. It's much more likely that what you're doing in all those branches that's killing you.
On May 17, 2:40 pm, Dombo <do...@disposable.invalid> wrote:
> lallisidhu schreef: > > > > > Hi all, > > > Could anybody help me or guide me to write a better ISR code which uses > > lesser memory and compiles smaller hex file.The problem I am facing is if I > > use too many 'if else' conditions in my ISR the hex file compiles shoots to > > 18Kb whereas if i use one or two conditions only the hex file is around 5Kb > > I want my compiled Hex file to be around 8-10 Kb.Below is my code of ISR. > > > // > > *************************************************************************************** > > // Low Priority Interrupt > > // > > *************************************************************************************** > > void HIGH_ISR (void); > > #pragma code high_vector_section=0x08 > > void high_vector (void) > > { > > _asm > > goto HIGH_ISR > > _endasm > > } > > #pragma code > > #pragma interrupt HIGH_ISR > > void HIGH_ISR (void) > > { > > > if (PIR1bits.RCIF == 1) // If USART Rx Flag is set > > { > > UART_Data.Input = ReadUSART(); // Get character USART module > > > if(UART_Data.Input == 0x11) > > { > > EE_Address = 0xAA; > > EE_Data = Current_time; > > Write_EEPROM(); > > > EE_Address = 0xAB; > > EE_Data = Current_ports; > > Write_EEPROM(); > > } > > > else if(UART_Data.Input == 0x12) > > { > > Read_EE(); > > printf("\nCurrent Time settings = %d", eet); > > printf("\nCurrent Port settings = %d", eep); > > } > > > else if(UART_Data.Input == 0x13) > > { > > printf("\nCurrent Time settings = %x", Current_time); > > } > > > else if(UART_Data.Input == 0x14) > > { > > printf("\nCurrent Port settings = %x", Current_ports); > > } > > > else if(UART_Data.Input == 0x15) > > { > > Current_time = Default_time; > > Current_ports = Default_ports; > > delay = (Current_time*5); > > // Set_Port_Time(); > > printf("\nCurrent Port settings = %x", Current_ports); > > } > > > else if((UART_Data.Input >= 0x21) && (UART_Data.Input <= 0x2A)) > > { > > > Current_ports = UART_Data.Input; > > printf("\n%x",UART_Data.Input); > > } > > > else if((UART_Data.Input == 0x31) || (UART_Data.Input == 0x33) || > > (UART_Data.Input == 0x35) || (UART_Data.Input == 0x37) || (UART_Data.Input > > == 0x39)) > > { > > Current_ports = UART_Data.Input; > > printf("\n%x",Current_ports); > > } > > > else if(UART_Data.Input >= 0x80) > > { > > Current_time = ((UART_Data.Input) & (0x7F)); > > printf("\nTiming Selected = %dms",Current_time*50); > > delay = (Current_time*5); > > // Set_Port_Time(); > > } > > > else if(UART_Data.Input < 0x80) > > { > > PORTB = 0x00; > > PORTC = 0x00; > > ports = ((UART_Data.Input) & (0x0F)) ; > > if( (ports >= 1) && (ports <= 10) ) > > { > > Current_ports = ports; > > printf("\nPorts Selected higher priority intr = > > %d",Current_ports); > > } > > else{ > > printf("\n Enter valid ports number (1-10) \n"); > > } > > } > > > UART_Data.Flag_UART_RX = 1; > > PIR1bits.RCIF = 0; // Clear the interrupt flag > > } > > } > > > Could anybody help me over this I desperately need to reduce my code size > > to flash to MCU. > > > Thank you all .Appreciate if anybody can guide over an alternative > > strategy for 'if else'. > > If at all possible consider removing printf() from all of your code. > Chances are that the printf() code consumes many times more memory than > the if-else-if code in your ISR.
I guess, the printf() taking up memory. Is look like you are printing a string and a number in each printf(). can you define two variables, one for string and one for number. and assign appropriate values in the if clause. after the if clause call the printf() to print the string variable and number variable. in that case you are calling print() only once. it might help, just a suggestion. Thanushan
On Sat, 17 May 2008 07:02:23 -0500, lallisidhu <lallisidhu@gmail.com> wrote:
> Hi all, > > Could anybody help me or guide me to write a better ISR code which uses > lesser memory and compiles smaller hex file.The problem I am facing is if I > use too many 'if else' conditions in my ISR the hex file compiles shoots to > 18Kb whereas if i use one or two conditions only the hex file is around 5Kb > .I want my compiled Hex file to be around 8-10 Kb.Below is my code of ISR.
I think I'd recommend running your compiler against both (all) versions of your code and generating assembler/object listings. With those in hand (or on acreen) you can see where and how the additional memory is being used. If you're not familiar with this, check your compiler's options, the compiler manual, or the online help as appropriate. Examining the code generated by one's compiler can give you a good feel for how your C code maps into bytes/words of flash. Hope this helps... Frank McKenney -- You cannot depend on your eyes when your imagination is out of focus. -- Mark Twain -- Frank McKenney, McKenney Associates Richmond, Virginia / (804) 320-4887 Munged E-mail: frank uscore mckenney ayut mined spring dawt cahm (y'all)