Sorry for typo error in my tutorial. Pleae replace WATCHDOG with
WDFEED. E&OE comes in handy at times like this :)
--- In lpc2000@yahoogroups.com, "jayasooriah" <jayasooriah@...> wrote:
>
> This is an add-on to Danish Ali's contribution to AH's original
question.
>
> I hope it will show how one can use GCC's inline assembly features in
> an effective way to produce code that is both readable *and* efficient.
>
> I am not sure if I could have handcrafted the assembler code to be
> that efficient, considering the three primitives I created in the
> header file are not specific to the WATCHDOG or the LPC.
>
> Sorry it is longish but striking a balance between being brief and
> clear is not always easy considering the nature of this audience.
>
> Enjoy!
>
> Jaya
>
> PS: All you need to know about inline assembly for purposes of
> understanding this tutorial can be found at:
>
> http://www.ethernut.de/en/documents/arm-inline-asm.html
>
> I am happy to explain finer points if anyone wants to know more.
>
> --- In lpc2000@yahoogroups.com, "Danish Ali" <danish@> wrote:
>
> > Attached is an example of something that gcc likes (as
> > supplied with Rowley Crossworks).
>
> > void Watchdog_Feed(void) { /* NOT fiq safe! */
> > int irqStat;
> > asm volatile (
> > " mrs r0, cpsr\n"
> > " mov %0,r0\n" : "=r" (irqStat) : : "r0" );
> > if (128 & ~irqStat)
> > __ARMLIB_disableIRQ();
> > asm volatile (
> > "WDFEED = 0xE0000008\n"
> > " LDR r0, =WDFEED\n"
> > " MOV r1,#0xAA\n"
> > " MOV r2,#0x55\n"
> > " STRB r1,[r0]\n"
> > " STRB r2,[r0]\n" : : : "r0", "r1", "r2");
> > if (128 & ~irqStat)
> > __ARMLIB_enableIRQ();
> > }
>
> I wrote a header file, foo.h with three primitives to do what the
> above code does. This is included at the end of this post E&OE.
>
> I wrote foo.c which includes foo.h (and other header files), and in
> which I invoked the equivalent of the Watchdog_Feed() function as
follows:
>
> > feedSeq(&WATCHDOG);
>
> I used GCC to generate the optimised assembler source file as follows:
>
> > arm-esdk-gcc -Wall -Werror -O3 -S foo.c
>
> The assembler output for the feedSeq() call I got is as follows
> (comments added)
>
> > mov r0, #128 @ 0x80 (IRQ BIT)
> > mov lr, #-536870912 @ 0xe0000000 (&WATCHDOG)
> > mrs ip, cpsr @ save copy of CPSR
> > orr r0, r0, ip @ set IRQ bit in temp
> > msr cpsr, r0 @ disable interrupts
> > mov r0, #170 @ 0xAA (feed byte #1)
> > mov r3, #85 @ 0x55 (feed byte #2)
> > str r0, [lr, #0] @ WATCHDOG FEED #1
> > str r3, [lr, #0] @ WATCHDOG FEED #2
> > msr cpsr, ip @ restore interrupts
>
>
> The header file where I make use of inline functions and inline
> assembly to achieve the above result follows. Note that I do not
> refer to any register by name, but let the compiler tell me what
> register to use.
>
> The name of the game here is not to override the compiler with your
> choices, but to tell the compiler (in the nicest way possible) what
> you want it to do for you ... to produce the code shown above.
>
> > // ===========================================================
> > // 'irqMask'
> >
> > // mask either irq or fiq bit
> > inline int
> > irqMask(mask)
> > {
> > int mode;
> >
> > // set mask bit
> > asm volatile
> > (
> > "mrs\t%0, cpsr" "\n\t"
> > "orr\t%1, %1, %0" "\n\t"
> > "msr\tcpsr, %1"
> > : "=&r" (mode)
> > : "r" (mask)
> > );
> >
> > // previous mode
> > return (mode);
> >
> > } // irqMask()
> >
> > // End of 'irqMask'
> > // ===========================================================
> >
> >
> > // ===========================================================
> > // 'irqMode'
> >
> > // restore mode and irq bits
> > inline void
> > irqMode(int mode)
> > {
> >
> > // restore CPSR
> > asm volatile ("msr\tcpsr, %0" : : "r" (mode));
> >
> > } // irqMode()
> >
> > // End of 'irqMode'
> > // ===========================================================
> >
> >
> > // ===========================================================
> > // 'feedSeq'
> >
> > // atomic feed sequence
> > inline void
> > feedSeq(int *loc)
> > {
> > int mode;
> >
> > // enter critical section
> > mode = irqMask(IRQ_BIT);
> >
> > // atomic feed sequence
> > asm volatile
> > (
> > "str\t%1, [%0, #0]" "\n\t"
> > "str\t%2, [%0, #0]"
> > :
> > : "r" (loc), "r" (0xaa), "r" (0x55)
> > : "r1", "r2"
> > );
> >
> > // leave critical section
> > irqMode(mode);
> >
> > } // feedSeq()
> >
> > // End of 'feedSeq'
> > // ===========================================================
>Message
Re: Example of C and inline ASM in a file?
2006-04-10 by jayasooriah
Attachments
- No local attachments were found for this message.