Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Interrupt Service Routine in assembly - advantages

Status
Not open for further replies.

jonnybgood

Full Member level 4
Full Member level 4
Joined
Dec 28, 2010
Messages
214
Helped
3
Reputation
6
Reaction score
1
Trophy points
1,298
Activity points
3,011
Hi,
I will use an ISR that is restricted to 2μs. I will use PIC18F/PIC24F.
In this ISR the uC will be:

-Firing timer 1 (system clock)
-Stop CTMU current source (1 clock cycle)
-Perford ADC connversion (will use system clock)
-Save ADC to somewhere else (not in the original buffer)
-Drain ADC sampling cap (will only take 2 clock cyles)
-Switch on CTMU (will only take 1 clock cycle)

-I will then have to wait for the other rising edge(new input cycle) to stop the timer. How much latency will there be?

This whole cycle will happen only once - it is not repetitive.

If I will use a 20Mhz crystal, I will have 20clock cycles in 2μs. Am i right?
2/20Mhz=0.1μs.

What advantages would I have if I where to code the ISR in assembly language.

In C, MPLAB SIM I usually use stop watch to calculate exactly the clock cycles.

Any hints would be appreciated a lot.
thanks
 

Hi Johnny,

The external XTAL frequency of you uC in the case of PICs needs to be divided by four to give you your number of instructions per second, so 20MHz would give you 5MIPS(Instructions per second) which is 0.2uS per instruction which only gives you 10 instructions to carry out all your tasks i.e not enough ... You could infact double this number by using a 10MHz XTal and using the onboard PLL in the PIC, this can be turned on using the config menu in MPLab.

I don't think your overheads in C should be that much larger than they would be in assembly apart from some context saving which come to think of it could be quite sizeable in your case and take up a fair amount, if not all of your instruction cycles. Provided your code is re-entrant then there is no need for this context saving and writing the ISR in assembly language would allow you to bypass this being done.

I would say that seen as your ISR is going to be so tiny anyway, just go ahead and write it in assembly.

I must say that I am sceptical as to whether you will be able to perform all the task in the allotted time though as it takes time to perform and A2D conversion, I would suggest starting the conversion going at the start of the ISR and going away and do the other things that need to be done before coming back to check if the A2D conversion is complete.

Hope this helps.

/Pheetuz.
 
I read somewhere that it is rather impossible to write interrupt service routines in C language. I use msp430 microcontroller and whenever I use an interrupt I have to use some assembly code in the C code.
 
It is perfectly possible to write very efficient interrupt routines in C. I have done some very fast software will multiple interrupts with the PIC24H and checked the assembler it produces to ensure it as fast as it could be. However, that was with the full version of the compiler with full optimization for speed. With no optimization the interrupt routine took twice as long.

The objective of the code is not clear, nor is the reason for the required speed. As has already been pointed out, the ADC will limit the time for executing the code. An external ADC may be required unless your sequence of events can be different.

Also, the term 'latency' needs clarifying. To me that is the delay from receiving the interrupt before the interrupt routine actually starts.

If I was wanting a fast interrupt and fast execution I would look at a fast processor such as the PIC24H or the newer PIC24E.

Keith
 
I tried a simple interrupt in C. This just goes to the ISR and do just one asm("nop"); apart from clearing the flag bit. The process from completing the last instruction till returning to the next (going through the ISR) took 16 instruction cycles. From what I learned these are too much.


From completing the main instruction to going to the 'bracket' of the interrupt function, it takes 5 instruction cycles in MPLAB SIM which is accaptable. But from the bracket of the interrupt function to the first instruction it takes another 5 instruction cycles (from disassembly : 0D98 F80034 push.w 0x0034). Then at the end after the "nop" (1 cycle) and Clear Flag (1 cycle), it takes another 4 cycles to return ( 0DA6 F90034 pop.w 0x0034 0DA8 064000 retfie).

Would I see some improvement with using assembly? Where can I find some examples?


Code:
int main()

{

TRISB=0x4000;
AD1PCFG=0xFFFF;

IntInit();    //init interrupts

while(1)
{

asm("nop");
asm("nop");
asm("nop");
asm("nop");
}

return(0);
}

void IntInit(void)
{
   INTCON2 = 0x0000;   /*Setup INT0, INT1, INT2, interupt on falling edge*/
   IFS1bits.INT1IF = 0;    /*Reset INT1 interrupt flag */
   IEC1bits.INT1IE = 1;    /*Enable INT1 Interrupt Service Routine */
   IPC5bits.INT1IP = 1;		/*set low priority*/
}

//_INT1Interrupt() is the INT1 interrupt service routine (ISR).
void __attribute__((__interrupt__)) _INT1Interrupt(void);
void __attribute__((__interrupt__, auto_psv)) _INT1Interrupt(void)
{
        asm("nop");
	IFS1bits.INT1IF = 0;    //Clear the INT1 interrupt flag or else
}
 

I will look at your code properly tomorrow when I have access to my computer, but I notice you haven't declared the interrupt as 'fast'. That would ensure that the context save is done in shadow registers if possible. Also, have you selected optimization for speed? This is available with the full version of the compiler or for 60 days for the trial version.

I am assuming you are using the Microchip C compiler.

Keith
 
those extra instructions may be the push and pop.... You may require some register access inside ISR.. So you need to backup those register values before using it inside ISR. Then after ISR, u need to restore those register value and then return from the ISR.. So that will be the 4 code lines, I assume...
If it is a full version compiler, it may be able to generate more speed optimized code....

Otherwise, I think you can reserve some registers using register variables etc...Any way wait for Keith

Also, there are many other option infront of you,,, AVR, MSP430 etc...They have some good and efficient free compilers,,, I have used avr-gcc and msp430-gcc in linux.. Both are free... Also I experienced some good speed optimization by using -O2 amd -O3 options ;-) ... There is a free compiler supporting PIC, ie SDCC compiler. But I don't know how efficient it is....
 
Last edited:
Yes, I am using Microchip compiler. thanks for your patience. I will try to get the hi-tech c compiler than for pic24. I think i will manage.

On the other hand I will still present my ISR in assembly for my school project to show understanding of time critical situations.
 

Just a thought Johnny but if you want to score some really good marks on your school project then write your ISR in assembly but also write it in C, then do an analysis of the two, you could do this simply by viewing the disassembly listing and comparing the assembly code that the compiler generates with the code that you have written by hand and doing a comparison between them?
 

Just a thought Johnny but if you want to score some really good marks on your school project then write your ISR in assembly but also write it in C, then do an analysis of the two, you could do this simply by viewing the disassembly listing and comparing the assembly code that the compiler generates with the code that you have written by hand and doing a comparison between them?

Thanks for the good idea. Today I managed to lower the machine cycles to just 9 - exaclty as I learned (total latency 4+3 and nop + clear flag = 9 instruction cycles).

This was after specifying no_auto psv in the isr definition and also after checking Unroll loops, omit frame pointer, Procedural abstraction and enabled Pre-Optimization Inst. Scheduling and Post-optimization Inst. Scheduling.

Can you explain which of these were effective in this improvement (from 16 inst cycles to only 9 inst cycles) and maybe say something on each one? I am really curious on the PSV.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top