|
|
View previous topic :: View next topic |
Author |
Message |
jksor1234
Joined: 18 Jan 2007 Posts: 9
|
C instruction time |
Posted: Thu Jan 18, 2007 9:06 am |
|
|
Is there a document which outlines how much time it takes to execute every 'C' instruction.
In the datasheet for the PIC16F913, it states that the Instruction Cycle Time equals four divided by the oscillator frequency --> Tcy = 4/Fosc
I want to know how many instructions an IF statement uses, how many a WHILE loop uses, how many an Interrupt Routine uses, etc. In the CCS Manual, it gives a table for the amount of time math functions take.
Is there a document which says how many instruction cycles each instruction takes or do I need to just go through the LST file and figure it out? |
|
|
Ttelmah Guest
|
|
Posted: Thu Jan 18, 2007 9:25 am |
|
|
Simple answer. No.
It will even vary according to the data involved, and where the instructions occur.
There is a table in the manual, giving 'typical' times for the maths operations, but the problem is that a single C instruction, may involve anything from one assembler instruction to thousands. The compiler optimiser, is smart enough so that (for instance), if a page switch is necessary in one location, but not in another, it is removed in the latter case, so exactly the same access instruction, can have different numbers of machine instructions in different locations. As another example, taking the 'modulus' (remainder after division), of two numbers. This according to the timing 'table', takes typically 116 instructions for two 8 bit numbers. However the latter optimsers are smart enough, that if the second number is a 'binary' value (2, 4, 8 etc.), and a constant, the '&' operand is used instead, taking just a couple of instructions.
The only way to find out, is to either manually count instructions, or use a tool like the MPLAB simulator, and sopwatch function, and physically time the operation for real. Even here you need to be aware that timings for arithmetic operations in particular, will change with different values...
Best Wishes |
|
|
rwyoung
Joined: 12 Nov 2003 Posts: 563 Location: Lawrence, KS USA
|
|
Posted: Thu Jan 18, 2007 9:27 am |
|
|
Use the LST file.
The time to complete an if or while will vary with the argument list. Is your argument list a simple variable comparison (i<3) or a more complex multi-level with pointers? Also things like chip archetecture can affect the time.
This has been suggested MANY times and I'll say it again. Learn a little assembly first. You don't have to be proficient, but at least be able to read it and recognize the basics. Then when you are working with the CCS compiler and you just KNOW your C code is correct but yet the wrong thing happens, you have a chance. Look at the LST file, see what the compiler produced. It does occasionally generate "crap" (usually though it is a mater of GIGO). _________________ Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month! |
|
|
jksor1234
Joined: 18 Jan 2007 Posts: 9
|
|
Posted: Thu Feb 08, 2007 4:05 pm |
|
|
Where in the LST file can you see the instructions required to get into an interrupt and the instructions required to get out of an interrupt? I want to calculate the amount of time my interrupt routines are taking. |
|
|
Ttelmah Guest
|
|
Posted: Thu Feb 08, 2007 4:19 pm |
|
|
Comment out the line '#nolist' in the include file for the processor you are using. This allows the 'hidden' bits of housekeeping code to be seen.
Then just look at the code starting at the hardware interrupt address (depends on whether this is a PIC16, or a PIC18). Expect perhaps 30 to 40 instruction times, before the actual jump to the handler code, and a similar number on the return.
Best Wishes |
|
|
jksor1234
Joined: 18 Jan 2007 Posts: 9
|
|
Posted: Fri Feb 09, 2007 8:55 am |
|
|
I am using a PIC16F913. Where is the hardware interrupt address?
From the LST file:
Code: | .................... #int_TIMER1
.................... void TIMER1_isr(void) //setup to interrupt every 262mS
.................... {
.................... Check_Flag = TRUE;
*
0073: BSF 2A.0
.................... }
....................
....................
0074: BCF 0C.0
0075: BCF 0A.3
0076: GOTO 022
|
Is 0022 the interrupt address?
at 0022 in the LST file:
Code: | 0022: MOVF 22,W
0023: MOVWF 04
0024: MOVF 23,W
0025: MOVWF 77
0026: MOVF 24,W
0027: MOVWF 78
0028: MOVF 25,W
0029: MOVWF 79
002A: MOVF 26,W
002B: MOVWF 7A
002C: MOVF 27,W
002D: MOVWF 7B
002E: MOVF 28,W
002F: MOVWF 0A
0030: SWAPF 21,W
0031: MOVWF 03
0032: SWAPF 7F,F
0033: SWAPF 7F,W
0034: RETFIE
0035: BCF 0A.3
0036: GOTO 073
|
So, when the interrupt occurs, the PIC jumps to 0022. It sees if the Timer1 caused the interrupt. If it did, then it jumps to 0073 and runs the Timer1 interrupt routine. After the routine is completed, it jumps back to 0022 and runs that code again until it sees RETFIE. So, to get into the interrupt routine, it takes 21 instructions. It takes 4 instructions to run the interrupt routine and return to the interrupt handler. And finally, it takes 19 instructions to exit the interrupt handler.
So the total time the interrupt will take, using an 8MHz processor is...
21+4+19 = 44 instructions
500nS per instruction
22uS total execution time.
If more than one interrupt is enabled, then the number of instructions to get in and out of the interrupt routine will change because now the interrupt handler has to figure out which interrupt occured.
Are the above statements correct? |
|
|
Ttelmah Guest
|
|
Posted: Fri Feb 09, 2007 9:51 am |
|
|
The hardware address for a 16 chip, is 0004.
Look at the data sheet...
You will find elsewhere in the assembly, the 'global' handler. This saves all the registers, then jumps to the individual hanlder (in your case at 0073). Then the code at here, jumps back when it finishes, which restores the registers, and returns to the caller.
The typical 'global' handler, for a 16 chip, is:
Code: |
0004: MOVWF 7F
0005: SWAPF 03,W
0006: CLRF 03
0007: MOVWF 21
0008: MOVF 0A,W
0009: MOVWF 20
000A: CLRF 0A
000B: MOVF 04,W
000C: MOVWF 22
000D: MOVF 77,W
000E: MOVWF 23
000F: MOVF 78,W
0010: MOVWF 24
0011: MOVF 79,W
0012: MOVWF 25
0013: MOVF 7A,W
0014: MOVWF 26
0015: MOVF 7B,W
0016: MOVWF 27
0017: BCF 03.7
0018: BCF 03.5
0019: MOVLW 8C
001A: MOVWF 04
//Up to here, is the 'saving' code, and code to set the banks
//for the next part - total of 23 instructions
001B: BTFSS 00.3
001C: GOTO 01F
001D: BTFSC 0C.3
001E: GOTO 042
001F: MOVLW 8C //This part handles the test for an interrupt,
//and jumps to it's handler. In this case another 4 instructions
//From here is the 'restore' code - this is the part you have found
0020: MOVWF 04
0021: BTFSS 00.1
0022: GOTO 025
0023: BTFSC 0C.1
0024: GOTO 03F
0025: BTFSS 0B.4
0026: GOTO 029
0027: BTFSC 0B.1
0028: GOTO 03C
0029: MOVF 22,W
002A: MOVWF 04
002B: MOVF 23,W
002C: MOVWF 77
002D: MOVF 24,W
002E: MOVWF 78
002F: MOVF 25,W
0030: MOVWF 79
0031: MOVF 26,W
0032: MOVWF 7A
0033: MOVF 27,W
0034: MOVWF 7B
0035: MOVF 20,W
0036: MOVWF 0A
0037: SWAPF 21,W
0038: MOVWF 03
0039: SWAPF 7F,F
003A: SWAPF 7F,W
003B: RETFIE
//Another 28 instructions to return to the caller...
|
Best Wishes |
|
|
|
|
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
|