[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [avr-gcc-list] Newbie question
From: |
Weddington, Eric |
Subject: |
RE: [avr-gcc-list] Newbie question |
Date: |
Wed, 25 Feb 2009 09:27:11 -0700 |
> -----Original Message-----
> From:
> address@hidden
> [mailto:address@hidden
> org] On Behalf Of David VanHorn
> Sent: Wednesday, February 25, 2009 9:05 AM
> To: address@hidden
> Subject: [avr-gcc-list] Newbie question
>
>
> :)
>
> Interrupt latency.
>
> So my question is, how close can I get to my ASM approach, using C?
You'll probably have to whittle this down in steps.
See comments below.
>
> 0000022D: 9508 RET Subroutine return
> @0000022E: __vector_1
> 450: {
> +0000022E: 921F PUSH R1 Push
> register on stack
> +0000022F: 920F PUSH R0 Push
> register on stack
> +00000230: B60F IN R0,0x3F In from I/O location
> +00000231: 920F PUSH R0 Push
> register on stack
> +00000232: 2411 CLR R1 Clear Register
> +00000233: 938F PUSH R24 Push
> register on stack
> +00000234: 939F PUSH R25 Push
> register on stack
> +00000235: 93EF PUSH R30 Push
> register on stack
> +00000236: 93FF PUSH R31 Push
> register on stack
> 451: if (Raw_Edge_Flag == 0) // If this is the first time thru
> +00000237: 91800082 LDS R24,0x0082 Load direct
> from data space
> +00000239: 2388 TST R24 Test for
> Zero or Minus
> +0000023A: F441 BRNE PC+0x09 Branch if not equal
> 453: TCNT1H=0; // Timer starts at 0
> +0000023B: BD8D OUT 0x2D,R24 Out to I/O location
> 454: TCNT1L=0;
> +0000023C: BD8C OUT 0x2C,R24 Out to I/O location
> 455: Raw_Edge_Flag = 0xFF; // Next time is the end of a pulse
> +0000023D: EF8F SER R24 Set Register
> +0000023E: 93800082 STS 0x0082,R24 Store
> direct to data space
> 456: Debug_DDR |= (1 << Debug_Pin); // Output
> +00000240: 9A8D SBI 0x11,5 Set bit in
> I/O register
> 457: Debug_Port |= (1 << Debug_Pin); // High
> +00000241: 9A95 SBI 0x12,5 Set bit in
> I/O register
I know that it's not adding much code, but can you remove (comment out) your
debug statements, like above? I noticed there are more below, too.
> 458: return;
> +00000242: C020 RJMP PC+0x0021 Relative jump
> 462: Raw_Data[0][Raw_Data_In_Index] = TCNT1;
> +00000243: 91800083 LDS R24,0x0083 Load direct
> from data space
> +00000245: 2FE8 MOV R30,R24 Copy register
> +00000246: 27FF CLR R31 Clear Register
> +00000247: 0FEE LSL R30 Logical Shift Left
> +00000248: 1FFF ROL R31 Rotate Left
> Through Carry
> +00000249: 57EC SUBI R30,0x7C Subtract immediate
> +0000024A: 4FFF SBCI R31,0xFF Subtract
> immediate with carry
> +0000024B: B58C IN R24,0x2C In from I/O location
> +0000024C: B59D IN R25,0x2D In from I/O location
> +0000024D: 8391 STD Z+1,R25 Store
> indirect with displacement
> +0000024E: 8380 STD Z+0,R24 Store
> indirect with displacement
Your assignment into an array seems to generate a lot of code. Is there any way
that you can just use some dedicated global variables while in the ISR, and
then stuff values to an array during a task in the main loop?
> 463: Debug_DDR |= (1 << Debug_Pin); // Output
> +0000024F: 9A8D SBI 0x11,5 Set bit in
> I/O register
> 464: Debug_Port &=~(1 << Debug_Pin); // Low
> +00000250: 9895 CBI 0x12,5 Clear bit
> in I/O register
More debug statements.
> 465: Raw_Edge_Flag = 0; // So the next event will be
> a beginning
> +00000251: 92100082 STS 0x0082,R1 Store
> direct to data space
> 467: if ((TIFR & (1<< TOV1))==1) // If we rolled T0
> +00000253: B788 IN R24,0x38 In from I/O location
> +00000254: 2799 CLR R25 Clear Register
> +00000255: 7084 ANDI R24,0x04 Logical AND
> with immediate
> +00000256: 7090 ANDI R25,0x00 Logical AND
> with immediate
> +00000257: 9701 SBIW R24,0x01 Subtract
> immediate from word
> +00000258: F421 BRNE PC+0x05 Branch if not equal
Hmm. It seems the compiler is treating this expression as a 16-bit value. It
could be because of the comparison with the constant '1', which gets
automatically treated like an int. Can you see if typecasting will help?:
if ((TIFR & (uint8_t)(1<<TOV1)) == (uint8_t)1)
If it works, it should save 2 instructions.
> 470: TIFR |= (1<<TOV1); // reset the overflow condition
> +00000259: B788 IN R24,0x38 In from I/O location
> +0000025A: 6084 ORI R24,0x04 Logical OR
> with immediate
> +0000025B: BF88 OUT 0x38,R24 Out to I/O location
> +0000025C: C006 RJMP PC+0x0007 Relative jump
> 477: GICR |= (1 << INT1); // Enable INT1
> +0000025D: B78B IN R24,0x3B In from I/O location
> +0000025E: 6880 ORI R24,0x80 Logical OR
> with immediate
> +0000025F: BF8B OUT 0x3B,R24 Out to I/O location
> 478: GICR &=~(1 << INT0); // Disable INT0
> +00000260: B78B IN R24,0x3B In from I/O location
> +00000261: 7B8F ANDI R24,0xBF Logical AND
> with immediate
> +00000262: BF8B OUT 0x3B,R24 Out to I/O location
You're doing two assignments back to back to GICR, which causes two separate
read-modify-write blocks. Is there any way that they can be combined into one
step? Like so:
GICR = ((GICR & ~(1<<INT0)) | (1 << INT1));
I would think this would compile to an IN,ANDI,ORI,OUT sequence
> +00000263: 91FF POP R31 Pop
> register from stack
> +00000264: 91EF POP R30 Pop
> register from stack
> +00000265: 919F POP R25 Pop
> register from stack
> +00000266: 918F POP R24 Pop
> register from stack
> +00000267: 900F POP R0 Pop
> register from stack
> +00000268: BE0F OUT 0x3F,R0 Out to I/O location
> +00000269: 900F POP R0 Pop
> register from stack
> +0000026A: 901F POP R1 Pop
> register from stack
> +0000026B: 9518 RETI
>
If we can keep the ISR from using as many other registers as possible, then it
will help in both the ISR prologue and epilogue.
> **************************************************************
> **************
> This communication (including any attachments) is for the use of the
> intended recipient(s) only and may contain information that is
> confidential, privileged or otherwise legally protected. Any
> unauthorized use or dissemination of this communication is
> prohibited. If you have received this communication in error, please
> immediately notify the sender by return e-mail message and delete
> all copies of the original communication. Thank you for your
> cooperation.
> **************************************************************
Any way that you can remove the above confidential notice? You're sending this
mail to a public mailing list.
Eric Weddington
Re: [avr-gcc-list] Newbie question, Vincent Trouilliez, 2009/02/25
Re: [avr-gcc-list] Newbie question, David Kelly, 2009/02/25