Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: system and user modes

2006-04-17 by jayasooriah

--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@...> wrote:
> SWI then acts 
> as an indirect jump table to the underlying kernel functions.  But
with the 
> small micros, especially those w/o an external bus, programs can as
easily 
> be built with a static link and avoid the extra overhead of the SWI.
 Both 
> the simple timing overhead and the need to build a gateway library that 
> provides the prototypes and parameter conversion from standard C
type call 
> to an SWI based call.

I know of many who think along the lines you have expressed.  They
associate "kernel" with what is found in general purpose operating
systems.

Allow me to challenge your perceptions relating to timing overheads
and gateway library requirements for SWI in embedded ARM context.  I
will use the watchdog feed example that got me involved in the earlier
thread.

Here is the interface

> static inline void
> atomicFeed(volatile int *feed, int arg1, int arg2)
> {
>         register volatile int *param1 asm ("r1") = feed;
>         register int param2 asm ("r2") = arg1;
>         register int param3 asm ("r3") = arg2;
>         register int vector asm ("r0");
> 
>         asm volatile
>         (
>                 "ldr\t%0, =atomicFeed"  "\n\t"
>                 "swi\t0"
>                 : "=r" (vector)
>                 : "r" (param1), "r" (param2), "r" (param3)
>         );
> 
> } // atomicFeed()

and the implementation 

> __attribute__((naked))
> void
> _atomicFeed(void)
> {
>         asm volatile
>         (
>                 PROLOG (atomicFeed)
>                 "msr\tcpsr_c, #0xd3"    "\n\t"
>                 "str\tr2, [r1]"         "\n\t"
>                 "str\tr3, [r1]"         "\n\t"
>                 EPILOG ()
>         );
> 
> } // _atomicFeed()

The application includes the header file and invokes atomic feed:

>        atomicFeed(&_WD.feed, 0xaa, 0x55);

The code generated for the application in 16-bit mode is:

>         ldr     r1, =[address]
>         mov     r2, #170
>         mov     r3, #85
>         ldr     r0, =atomicFeed
>         swi     0

The SWI 'vector' at 0x00000008 is always coded as

>         mov	pc, r0

And generated code for the "kernel" handler in 16- and 32-bit modes

>         .code   32
>         .global atomicFeed
> atomicFeed:
>         msr     cpsr_c, #0xd3
>         str     r2, [r1]
>         str     r3, [r1]
>         movs    pc, lr

The beauty of this method is that it supports both 16- and 32-bit
compilation (with no conditionals I must add), and it works when
invoked from both user and kernel modes.

Have a go and see how much you can trim off this implementation in
terms of timing and gateway library interface overheads by using
procedure calls and consider what you would stand to lose.

Incidentally, the "vectored SWI" approach I use allows any team member
who are play with custom "system mode" kernel calls.

Jaya

PS:  E&OE applies here too :)  If you spot mistakes, please do not
hesitate to point it out.

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.